Blame SOURCES/openldap-nss-regex-search-hashed-cacert-dir.patch

767ab2
MozNSS: better file name matching for hashed CA  certificate directory
767ab2
767ab2
CA certificate files in OpenSSL compatible CACERTDIR were loaded if the file extension was '.0'. However the file name
767ab2
should be 8 letters long certificate hash of the certificate subject name, followed by a numeric suffix which is used
767ab2
to differentiate between two certificates with the same subject name.
767ab2
767ab2
Wit this patch, certificate file names are matched correctly (using regular expressions).
767ab2
767ab2
Author: Jan Vcelak <jvcelak@redhat.com>
767ab2
Upstream ITS: #7374
767ab2
Resolves: #852786
767ab2
767ab2
diff --git a/libraries/libldap/tls_m.c b/libraries/libldap/tls_m.c
767ab2
index 5e49fc5..61d71d4 100644
767ab2
--- a/libraries/libldap/tls_m.c
767ab2
+++ b/libraries/libldap/tls_m.c
767ab2
@@ -38,6 +38,7 @@
767ab2
 #include <ac/unistd.h>
767ab2
 #include <ac/param.h>
767ab2
 #include <ac/dirent.h>
767ab2
+#include <ac/regex.h>
767ab2
 
767ab2
 #include "ldap-int.h"
767ab2
 #include "ldap-tls.h"
767ab2
@@ -118,9 +119,7 @@ static const PRIOMethods tlsm_PR_methods;
767ab2
 
767ab2
 #define PEM_LIBRARY	"nsspem"
767ab2
 #define PEM_MODULE	"PEM"
767ab2
-/* hash files for use with cacertdir have this file name suffix */
767ab2
-#define PEM_CA_HASH_FILE_SUFFIX	".0"
767ab2
-#define PEM_CA_HASH_FILE_SUFFIX_LEN 2
767ab2
+#define PEM_CA_HASH_FILE_REGEX "^[0-9a-f]{8}\\.[0-9]+$"
767ab2
 
767ab2
 static SECMODModule *pem_module;
767ab2
 
767ab2
@@ -1541,6 +1540,7 @@ tlsm_init_ca_certs( tlsm_ctx *ctx, const char *cacertfile, const char *cacertdir
767ab2
 		PRDir *dir;
767ab2
 		PRDirEntry *entry;
767ab2
 		PRStatus fistatus = PR_FAILURE;
767ab2
+		regex_t hashfile_re;
767ab2
 
767ab2
 		memset( &fi, 0, sizeof(fi) );
767ab2
 		fistatus = PR_GetFileInfo( cacertdir, &fi );
767ab2
@@ -1570,20 +1570,30 @@ tlsm_init_ca_certs( tlsm_ctx *ctx, const char *cacertfile, const char *cacertdir
767ab2
 			goto done;
767ab2
 		}
767ab2
 
767ab2
+		if ( regcomp( &hashfile_re, PEM_CA_HASH_FILE_REGEX, REG_NOSUB|REG_EXTENDED ) != 0 ) {
767ab2
+			Debug( LDAP_DEBUG_ANY, "TLS: cannot compile regex for CA hash files matching\n", 0, 0, 0 );
767ab2
+			goto done;
767ab2
+		}
767ab2
+
767ab2
 		do {
767ab2
 			entry = PR_ReadDir( dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN );
767ab2
 			if ( ( NULL != entry ) && ( NULL != entry->name ) ) {
767ab2
 				char *fullpath = NULL;
767ab2
-				char *ptr;
767ab2
+				int match;
767ab2
 
767ab2
-				ptr = PL_strrstr( entry->name, PEM_CA_HASH_FILE_SUFFIX );
767ab2
-				if ( ( ptr == NULL ) || ( *(ptr + PEM_CA_HASH_FILE_SUFFIX_LEN) != '\0' ) ) {
767ab2
+				match = regexec( &hashfile_re, entry->name, 0, NULL, 0 );
767ab2
+				if ( match == REG_NOMATCH ) {
767ab2
 					Debug( LDAP_DEBUG_TRACE,
767ab2
-						   "TLS: file %s does not end in [%s] - does not appear to be a CA certificate "
767ab2
-						   "directory file with a properly hashed file name - skipping.\n",
767ab2
-						   entry->name, PEM_CA_HASH_FILE_SUFFIX, 0 );
767ab2
+						   "TLS: skipping '%s' - filename does not have expected format "
767ab2
+						   "(certificate hash with numeric suffix)\n", entry->name, 0, 0 );
767ab2
+					continue;
767ab2
+				} else if ( match != 0 ) {
767ab2
+					Debug( LDAP_DEBUG_ANY,
767ab2
+						   "TLS: cannot execute regex for CA hash file matching (%d).\n",
767ab2
+						   match, 0, 0 );
767ab2
 					continue;
767ab2
 				}
767ab2
+
767ab2
 				fullpath = PR_smprintf( "%s/%s", cacertdir, entry->name );
767ab2
 				if ( !tlsm_add_cert_from_file( ctx, fullpath, isca ) ) {
767ab2
 					Debug( LDAP_DEBUG_TRACE,
767ab2
@@ -1599,6 +1609,7 @@ tlsm_init_ca_certs( tlsm_ctx *ctx, const char *cacertfile, const char *cacertdir
767ab2
 				PR_smprintf_free( fullpath );
767ab2
 			}
767ab2
 		} while ( NULL != entry );
767ab2
+		regfree ( &hashfile_re );
767ab2
 		PR_CloseDir( dir );
767ab2
 	}
767ab2
 done:
767ab2
-- 
767ab2
1.7.11.4
767ab2