[Fedora-directory-commits] windowsautoenroll/submitrequest submitrequest.vcproj, NONE, 1.1 submitrequest.cpp, 1.1.1.1, 1.2

Steven W Parkinson (sparkins) fedora-directory-commits at redhat.com
Fri Mar 30 00:08:56 UTC 2007


Author: sparkins

Update of /cvs/dirsec/windowsautoenroll/submitrequest
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv16870

Modified Files:
	submitrequest.cpp 
Added Files:
	submitrequest.vcproj 
Log Message:
Added Licence. Made test case more generic, so other people can use it.
Added loop mode, for performance/stress testing. Fixed PKCS#10
submission. Check that a cert was issued.



--- NEW FILE submitrequest.vcproj ---
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
	ProjectType="Visual C++"
	Version="7.10"
	Name="submitrequest"
	ProjectGUID="{B8D349AA-C242-4D81-A6E1-6CB6DBAE1AF2}"
	Keyword="Win32Proj">
	<Platforms>
		<Platform
			Name="Win32"/>
	</Platforms>
	<Configurations>
		<Configuration
			Name="Debug|Win32"
			OutputDirectory="Debug"
			IntermediateDirectory="Debug"
			ConfigurationType="1"
			CharacterSet="2">
			<Tool
				Name="VCCLCompilerTool"
				Optimization="0"
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
				MinimalRebuild="TRUE"
				BasicRuntimeChecks="3"
				RuntimeLibrary="5"
				UsePrecompiledHeader="3"
				WarningLevel="3"
				Detect64BitPortabilityProblems="TRUE"
				DebugInformationFormat="4"/>
			<Tool
				Name="VCCustomBuildTool"/>
			<Tool
				Name="VCLinkerTool"
				OutputFile="$(OutDir)/submitrequest.exe"
				LinkIncremental="2"
				GenerateDebugInformation="TRUE"
				ProgramDatabaseFile="$(OutDir)/submitrequest.pdb"
				SubSystem="1"
				TargetMachine="1"/>
			<Tool
				Name="VCMIDLTool"/>
			<Tool
				Name="VCPostBuildEventTool"/>
			<Tool
				Name="VCPreBuildEventTool"/>
			<Tool
				Name="VCPreLinkEventTool"/>
			<Tool
				Name="VCResourceCompilerTool"/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"/>
			<Tool
				Name="VCXMLDataGeneratorTool"/>
			<Tool
				Name="VCWebDeploymentTool"/>
			<Tool
				Name="VCManagedWrapperGeneratorTool"/>
			<Tool
				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
		</Configuration>
		<Configuration
			Name="Release|Win32"
			OutputDirectory="Release"
			IntermediateDirectory="Release"
			ConfigurationType="1"
			CharacterSet="2">
			<Tool
				Name="VCCLCompilerTool"
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
				GeneratePreprocessedFile="0"
				RuntimeLibrary="4"
				UsePrecompiledHeader="0"
				WarningLevel="3"
				Detect64BitPortabilityProblems="TRUE"
				DebugInformationFormat="3"/>
			<Tool
				Name="VCCustomBuildTool"/>
			<Tool
				Name="VCLinkerTool"
				AdditionalDependencies="certidl.lib"
				OutputFile="$(OutDir)/submitrequest.exe"
				LinkIncremental="1"
				GenerateDebugInformation="TRUE"
				SubSystem="1"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				TargetMachine="1"/>
			<Tool
				Name="VCMIDLTool"/>
			<Tool
				Name="VCPostBuildEventTool"/>
			<Tool
				Name="VCPreBuildEventTool"/>
			<Tool
				Name="VCPreLinkEventTool"/>
			<Tool
				Name="VCResourceCompilerTool"/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"/>
			<Tool
				Name="VCXMLDataGeneratorTool"/>
			<Tool
				Name="VCWebDeploymentTool"/>
			<Tool
				Name="VCManagedWrapperGeneratorTool"/>
			<Tool
				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
		</Configuration>
	</Configurations>
	<References>
	</References>
	<Files>
		<Filter
			Name="Source Files"
			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
			<File
				RelativePath=".\submitrequest.cpp">
			</File>
		</Filter>
		<Filter
			Name="Header Files"
			Filter="h;hpp;hxx;hm;inl;inc;xsd"
			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
			<File
				RelativePath=".\stdafx.h">
			</File>
		</Filter>
		<Filter
			Name="Resource Files"
			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
		</Filter>
		<File
			RelativePath=".\ReadMe.txt">
		</File>
	</Files>
	<Globals>
	</Globals>
</VisualStudioProject>


Index: submitrequest.cpp
===================================================================
RCS file: /cvs/dirsec/windowsautoenroll/submitrequest/submitrequest.cpp,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- submitrequest.cpp	29 Jul 2006 00:42:43 -0000	1.1.1.1
+++ submitrequest.cpp	30 Mar 2007 00:08:54 -0000	1.2
@@ -36,10 +36,12 @@
  * END COPYRIGHT BLOCK */
 
 /* This is a test program which will submit a certificate request */
+/* to the auto enrollment proxy                                   */
 
 
 #define _WIN32_DCOM
 
+#include <atlbase.h>
 
 #include <windows.h> 
 #include <stdlib.h>
@@ -48,7 +50,6 @@
 #include <assert.h>
 
 
-
 #include <certcli.h>
 #include <certsrv.h>
 
@@ -58,40 +59,61 @@
 
 #include "stdafx.h"
 
-#include "../testserver/RedHatCSProxy_h.h"
+#include "../proxy/RedHatCSProxy_h.h"
+
+#define ONCE(x) (onceflag++ ? 0 : x )
 
+int auth=0;
+int onceflag=0;
+int showcert=0;
+unsigned int duration=0;
+int i2=0;
+char*host = NULL;
+char*attrs = "";
 
 EXTERN_C const IID IID_ICertRequestD;
 EXTERN_C const IID IID_ICertConfig;
 
-void use_ICertRequest();
-void use_ICertRequestD();
+void use_ICertRequest(int size, char*buffer);
+void use_ICertRequestD(int size, char*buffer);
 
-BSTR get_request_from_file(char *filename)
+void get_request_from_file(char *filename, int *size, char **buffer)
 {
-	char certreq[10000];
-	FILE *fp = fopen(filename,"r");
-	if (fp == NULL) { return NULL; }
-	certreq[0] = '\0';
+#define bufsize 10000
+	char certreq[bufsize];
+	for(int i=0;i<bufsize;i++) { certreq[i] = 0; }
+	FILE *fp = fopen(filename,"rb");
+	if (fp == NULL) {
+		printf("Couldn't open input file %s\n", filename);
+		exit(1);
+	}
+	size_t offset=0;
 	size_t n;
-	n = fread(certreq,1,10000,fp);
-	fclose(fp);
-	n++;
-	
-	//unsigned short *r = (unsigned short*)malloc(sizeof(unsigned short) *(n+3));
-	wchar_t *r = (wchar_t*)malloc(sizeof(wchar_t) *(n+3));
-	// char*r = (char*)malloc(sizeof(char*) *(n+3));
-	unsigned int dest=0;
-
-	for (unsigned int i=0;i<=n; i++) {
-		if (certreq[i] == '\r' || certreq[i] == '\n')  continue; 
-        //r[dest++] = (wchar_t)certreq[i];
-		//r[dest++] = certreq[i];
-		r[dest++] = (wchar_t)certreq[i];
-		
+	do {
+		n = fread(&certreq[offset],1,bufsize,fp);
+		offset += n;
+		if (offset >= bufsize) {
+			printf("Input file %s too big. Must be smaller than %d bytes\n", 
+					filename,bufsize);
+			exit(1);
+		}
+	} while (n);
+
+	if (offset<100) { printf("malformed input file %s\n",filename); exit(1); }
+
+	if (certreq[0] == '-' && certreq[1] == '-') { 
+		printf("cannot process base-64 encoded input PKCS#10 - must be DER encoded\n",filename); exit(1);
 	}
-	r[dest] = 0;
-	return SysAllocString(r);
+
+	printf("read a total of %d bytes from input file %s\n",offset,filename);
+
+	*buffer = (char*)malloc(offset);
+	memcpy(*buffer, certreq, offset);
+	*size = (int)offset;
+	fclose(fp);
+	return;
+
+
 }
 
 int _tmain(int argc, _TCHAR* argv[])
@@ -103,6 +125,71 @@
 	CLSID certconfig_clid;
 	wchar_t *certconfig_progid = L"CertificateAuthority.GetConfig";
 
+	// For now, make the default ICertRequestD.
+	// Need more testing on the ICertRequest case
+	int certreqd = 1;
+
+	int count=1;
+	char*inputfile = NULL;
+
+	USES_CONVERSION;
+
+	for (int i=0;i<argc;i++) {
+		 printf("argc[%d]= %s\n",i,argv[i]);
+		 if (  argc == 1 ||
+			!strcmp("-h",argv[i])  ||
+			!strcmp("/help",argv[i])  ||
+			!strcmp("-?",argv[i])  ||
+			!strcmp("/?",argv[i])  ||
+			!strcmp("/h",argv[i])  ||
+			!strcmp("-help",argv[i]) ||
+			!strcmp("--help",argv[i])  )
+		 {
+			 printf("Auto Enrollment Proxy test client.\n");
+			 printf("Usage:\n");
+			 printf("  %s  [options]\n", argv[0]);
+			 printf("    -h            This help message\n");
+			 printf("    -v2           Use version 2 interfaces (ICertRequestD/ICertRequestD2)\n");
+			 //printf("    -certreqd     Use ICertRequestD interface (default ICertRequest)\n");
+			 printf("    -showcert     show hex dump of issued cert\n");
+			 printf("    -host=[host]  FQDN of proxy"); //(required if ICertRequestD interface used\n");
+			 printf("    -count=n      # of consecutive requests to make\n");
+			 printf("    -duration=n   # of seconds to run test (mutually exclusive with -count)\n");
+			 printf("    -input=file   Filename of DER PKCS#10 request (not PEM)\n");
+			 printf("    -attrs=XX     semicolon-separated list of attributes\n");
+			 printf("               for DomainController, use -attr=ccm:FQDN (of DC machine)\n");
+			 exit(1);
+		 }
+		 if (!strcmp("-certreqd",argv[i])) { certreqd = 1; }
+		 if (!strcmp("-showcert",argv[i])) { showcert = 1; }
+		 if (!strcmp("-auth",argv[i])) { auth = 1; }   // unused at present.
+		 if (!strcmp("-v2",argv[i])) { i2 = 1; }
+		 if (!strncmp("-host=",argv[i],6)) { 
+			 host = strdup(&argv[i][6]);
+		 }
+		 if (!strncmp("-input=",argv[i],7)) { 
+			 inputfile = strdup(&argv[i][7]);
+		 }
+		 if (!strncmp("-attrs=",argv[i],7)) { 
+			 attrs = strdup(&argv[i][7]);
+			 for (unsigned int j=0;j<strlen(attrs);j++) {
+				 if (attrs[j] == ';') attrs[j]='\n';
+			 }
+		 }
+		 if (!strncmp("-count=",argv[i],7)) { 
+			 char *count_s = strdup(&argv[i][7]);
+			 count = atoi(count_s);
+		 }
+		 if (!strncmp("-duration=",argv[i],10)) { 
+			 char *duration_s = strdup(&argv[i][10]);
+			 duration = atoi(duration_s);
+		 }
+	 }
+
+	if (count >0 && duration >0) {
+		printf("You can't specify -count AND -duration. Pick just one\n");
+	}
+
 	/*
 HKEY_CLASSES_ROOT\AppID\{D99E6E74-FC88-11D0-B498-00A0C90312F3}
 HKEY_CLASSES_ROOT\CLSID\{D99E6E73-FC88-11D0-B498-00A0C90312F3}  (certsrv admin)
@@ -129,39 +216,99 @@
 							*/
 
 
-	
+	int r_size;
+	char *r_buffer=NULL;
+	get_request_from_file(
+			inputfile != NULL ? inputfile : "testrequest.p10",
+			&r_size,
+			&r_buffer  );
 
+	if (r_buffer==NULL) {
+		printf("You must supply PKCS#10 input file   (use -input=file)\n");
+		exit(0);
+	}
 
-	
 
+	DWORD start_time = GetTickCount();
+	i=0;
+	while ((duration > 0) ? (GetTickCount()- start_time) / 1000 <duration :	i < count)
+	{	
+		if (count==1) {
+			printf("request %d\n",i+1);
+		} else {
+			printf("request %d/%d\n",i+1,count);
+		}
 
-	
+		if (certreqd) {
+			use_ICertRequestD( r_size,  r_buffer);
+		} else {
+			use_ICertRequest( r_size,  r_buffer);
+		}
+	i++;
 
-	use_ICertRequest();
-	//use_ICertRequestD();
+	}
 
+	// milliseconds
+	DWORD end_time = GetTickCount();
+	DWORD elapsed = end_time - start_time;
+	printf("---------------\n");
+	printf("%d requests completed in %d seconds\n", i, elapsed/1000);
 
 	CoFreeAllLibraries();
 	return 0;
 }
 
-void use_ICertRequest()
+
+
+void use_ICertRequest(int size, char *buffer)
 {
 	HRESULT r;
+	ICertRequest2 *icr2=NULL;
 	ICertRequest *icr=NULL;
+	ONCE(printf("Using ICertRequest\n"));
+
 	BSTR cacert= NULL;
 	
 	wchar_t *certrequest_progid = L"CertificateAuthority.Request";
 	CLSID certrequest_clid;
 	r = CLSIDFromProgID(certrequest_progid, &certrequest_clid);
 
+	if (FAILED(r)) {
+		printf("failed to get classid for %ws: %lx\n",certrequest_progid,r);
+		exit(0);
+	}
+
+
+	icr=NULL;
 	r = CoCreateInstance(
-			certrequest_clid,
-			NULL,
-			CLSCTX_ALL,
-			IID_ICertRequest,
-			(void**)&icr
-			);
+		certrequest_clid,
+		NULL,
+		CLSCTX_ALL,
+		IID_ICertRequest,
+		(void**)&icr
+		);
+
+	if (FAILED(r)) {
+		printf("Failed to create instance for ICertRequest: %lx\n",r);
+		exit(0);
+	}
+
+
+
+	icr2=NULL;
+
+	r = CoCreateInstance(
+		certrequest_clid,
+		NULL,
+		CLSCTX_ALL,
+		IID_ICertRequest2,
+		(void**)&icr2
+		);
+	
+	if (FAILED(r)) {
+		printf("Failed to create instance for ICertRequest2: %lx\n",r);
+		exit(0);
+	}
 
 
 	//BSTR cacertname = SysAllocString(L"sparkinswindows.sparkins.sfbay.redhat.com\\Steves MS CA");
@@ -176,14 +323,79 @@
 			(void**)&icc
 			);
 
+	if (FAILED(r)) {
+		printf("could not retrieve ICertConfig: %lx\n",r);
+		exit(0);
+	}
+
 	r = icc->GetConfig(CC_UIPICKCONFIG,&cacertname);
 	if (FAILED(r)) {
-		printf("could not retrieve ca info\n");
+		printf("Failed during call to get CA cert name %lx\n",r);
 		exit(0);
 	}
-	
 	printf("got CA info: %ws\n",cacertname);
 
+	wchar_t *b_a = L"Authority";
+	BSTR b_b = SysAllocString(b_a);
+	BSTR val_b = NULL;
+	r = icc->GetField(b_b,&val_b);
+	printf("GetField value for %ws is: %ws\n", b_b, val_b); 
+
+	LONG name_type[] = 
+	{
+		CR_PROP_ADVANCEDSERVER, 
+		CR_PROP_CACERTSTATE,    
+		CR_PROP_CACERTVERSION,  
+		CR_PROP_CANAME,        
+		CR_PROP_TEMPLATES,
+		CR_PROP_CATYPE,
+		CR_PROP_DNSNAME,
+		CR_PROP_FILEVERSION,
+		CR_PROP_SHAREDFOLDER,
+		CR_PROP_CASIGCERTCOUNT,
+		0
+	};
+
+	if (icr2!=NULL) {
+	for (int i=0; name_type[i] != 0; i++) {
+		VARIANT v;
+		LONG flags;
+		r = icr2->GetCAPropertyFlags(cacertname,name_type[i],&flags);
+
+		BSTR n = NULL;
+		icr2->GetCAPropertyDisplayName(cacertname,name_type[i],&n);
+
+		r = icr2->GetCAProperty(cacertname,
+			name_type[i],
+			0,   // index
+			flags,
+			CV_OUT_BASE64,
+			&v);
+		
+		
+		if (SUCCEEDED(r)) {
+            switch (flags  & PROPTYPE_MASK) {
+				case PROPTYPE_LONG:
+					printf("%ws, (%d),  value=%d\n",n,name_type[i],v.lVal);
+					break;
+				case PROPTYPE_STRING:
+					printf("%ws, (%d),  value=%ws\n",n, name_type[i],v.bstrVal);
+					break;
+			}
+		} else {
+			printf("%ws (%d), -> error %lx\n",n,name_type[i],r);
+		}
+		MessageBox(NULL,"Next",NULL,0);
+
+	}
+	}
+
+
+
+	
+	MessageBox(NULL,"about to retrieve CA cert",NULL,0);
+	
+
 	// Retrieve the CA certificate.
 
     r = icr->GetCACertificate(FALSE,
@@ -193,18 +405,18 @@
 							   
 	
 	long        disp;
-    BSTR request = get_request_from_file("testrequest.p10");
-	if (request==NULL) {
-		printf("could not load test request from file 'testrequest.p10' in current dir\n");
-		exit(0);
-	}
 
+	printf("BROKEN: need to fix this\n");
+	exit(0);
+
+/*
 	r = icr->Submit(
 		CR_IN_BASE64HEADER | CR_IN_PKCS10,
 		request,
 		NULL,
 		cacertname,
 		&disp);
+		*/
 	
 	if (!FAILED(r)) {
 		switch (disp) {
@@ -224,21 +436,33 @@
 
 }
 
-void use_ICertRequestD()
+
+void use_ICertRequestD(int size, char *buffer)
 {
 	HRESULT r;
 	ICertRequestD *icrd=NULL;
+	ICertRequestD2 *icrd2=NULL;
+	
+	USES_CONVERSION;
+
+	ONCE(printf("Using ICertReqD\n"));
 
 	COSERVERINFO si;
 	si.dwReserved1 = 0;
 	si.dwReserved2 = 0;
 	si.pAuthInfo = NULL;
-	si.pwszName = L"sparkinswindows.sparkins.sfbay.redhat.com";
+	si.pwszName = L"";
+	if (host) {
+		si.pwszName = A2W(host);
+	} else {
+		printf("hostname must be specified when using ICertRequestD interface\n");
+	}
+	ONCE(printf("using hostname: %ws\n",si.pwszName));
 
 	if (1) {
 		IClassFactory *cf=NULL;
 		r = CoGetClassObject(	CLSID_CCertRequestD,
-								CLSCTX_LOCAL_SERVER,
+								CLSCTX_REMOTE_SERVER,
 								&si,
 								IID_IClassFactory,
 								(void**)&cf   );
@@ -246,13 +470,25 @@
 			printf("failed to get class object %lx\n",r);
 			return;
 		}
+
 		r = cf->CreateInstance(NULL, IID_ICertRequestD, (void**)&icrd);
 		if (FAILED(r)) {
-			printf("failed to get instance object %lx\n",r);
+			printf("failed to get instance of icrd %lx\n",r);
+			exit(0);
+		}
+
+		if (i2) {
+			r = icrd->QueryInterface(IID_ICertRequestD2,(void**)&icrd2);
+			if (FAILED(r)) {
+				printf("failed to get instance of icrd2 (ignoring)%lx\n",r);
+			
+			}
 		}
 
 	} else {
 
+
+		/*
 		MULTI_QI mi;
 		mi.pIID = &IID_ICertRequestD;
 		mi.pItf = NULL;
@@ -267,12 +503,15 @@
 			1,
 			&mi
 			);
-			icrd = (ICertRequestD*) mi.pItf;
-	}
-	if (FAILED(r)) {
-		printf("agh, couldn't create remote object\n");
-	}
 
+		if (FAILED(r)) {
+			printf("agh, couldn't create CCertRequestD object %lx\n",r);
+		}
+
+		icrd = (ICertRequestD*) mi.pItf;
+  */
+	}
+	
 
 
 /*
@@ -285,32 +524,100 @@
 			);
 			*/
 
-
+#if 0
+	if (icrd2 != NULL) {
+		printf("Calling icrd2->Ping2()\n");
+		r = icrd2->Ping2(L"");
+	} else {
+		printf("Calling icrd2->Ping2()\n");
+		r = icrd->Ping(L"");
+	}
+	printf("ping returned: %lx\n",r);
+#endif
 	
 	
 	DWORD request_id=0;
 	DWORD dispword=0;
 	CERTTRANSBLOB rq;
-	rq.cb = 10;
-	rq.pb = (BYTE*) "abcdefghij";
+	rq.cb = size;
+	rq.pb = (BYTE*) buffer;
+
 	CERTTRANSBLOB chainblob;
 	CERTTRANSBLOB certblob;
 	CERTTRANSBLOB dispblob;
-	char *certchain;
-	char *cert;
-	char *dispmsg;
-	
-	r = icrd->Request(CR_IN_BASE64HEADER | CR_IN_PKCS10,
-		L"",
-		&request_id,
-		&dispword,
-		L"",
-		&rq,
-		&chainblob,
-		&certblob,
-		&dispblob
-		);
 
+	int make_request = 1;
+	wchar_t *wattrs = A2W(attrs);
+	
+	if (make_request == 1) {
+		ONCE(printf("icrd2 is: %p\n",(void*)icrd2));
+		if (icrd2 != NULL) {
+			printf("About to call icrd2->Request2\n");
+			r = icrd2->Request2(
+					L"",
+					CR_IN_BASE64HEADER | CR_IN_PKCS10,
+					L"0",
+					&request_id,
+					&dispword,
+					L"",
+					&rq,
+					&chainblob,
+					&certblob,
+					&dispblob
+					);
+
+		} else {
+			ONCE(printf("About to call icr->Request\n"));
+			r = icrd->Request(CR_IN_PKCS10 | CR_IN_BINARY,
+				L"",
+				&request_id,
+				&dispword,
+				wattrs,
+				&rq,
+				&chainblob,
+				&certblob,
+				&dispblob
+				);
+		}
+
+		printf("Request function returned: %lx\n",r);
+		printf("Request disposition: %lx (%s)\n",dispword, 
+			(dispword == CR_DISP_ISSUED) ? "ISSUED" : "REJECTED");
+	}
+
+
+	if (showcert) {
+		if (dispword == CR_DISP_ISSUED) {
+			for (unsigned int i=0;i<certblob.cb;i++) {
+				printf("%02x ",certblob.pb[i]);
+				if (i%16 == 15) {
+					printf("\n");
+				}
+			}
+			printf("\n");
+		}
+	}
+
+	CERTTRANSBLOB infoblob;
+	infoblob.cb = 2000;
+	infoblob.pb = (BYTE*)calloc(2000,1);
+
+
+	if (0) {
+
+#define GCC_FILEx 0x66696c65
+#define GCC_FILE 0x656c6966
+#define GCC_NAME 0x6E616D65
+#define GCC_INFO 0x696E666F
+#define GCC_TYPE 0x74707065
+#define GCC_ST   0x73740000
+
+	r = icrd->GetCACert(GCC_FILE, L"Steves MS CA", &infoblob);
+
+	printf("r = %lx\n",r);
+	printf("infoblob = %d\n",infoblob.cb);
+	}
 
 
 }
+




More information about the Fedora-directory-commits mailing list