Fix various MozNSS compatibility layer issues

+ Force write file with fsync to avoid race conditions
+ Always filestamp both sql and dbm NSS DB variants to not rely on default DB type prefix
+ Allow missing cert and key which is a valid usecase
+ Create extraction folder only in /tmp to simplify selinux rules
+ Fix Covscan issues

Related: #1400570
This commit is contained in:
Matúš Honěk 2017-12-06 15:13:49 +01:00
parent d8e109406e
commit d181b0472d
2 changed files with 123 additions and 265 deletions

View File

@ -1,5 +1,8 @@
MozNSS Interception Code
Author: Matus Honek <mhonek@redhat.com>
Date: Mon Nov 27 16:03:42 CET 2017
diff --git a/configure.in b/configure.in diff --git a/configure.in b/configure.in
index b251b6b06..8a836eabb 100644
--- a/configure.in --- a/configure.in
+++ b/configure.in +++ b/configure.in
@@ -237,6 +237,7 @@ dnl OL_ARG_ENABLE(referrals,[ --enable-referrals enable LDAPv2+ Referrals (ex @@ -237,6 +237,7 @@ dnl OL_ARG_ENABLE(referrals,[ --enable-referrals enable LDAPv2+ Referrals (ex
@ -38,7 +41,6 @@ index b251b6b06..8a836eabb 100644
if test $ol_link_tls = yes ; then if test $ol_link_tls = yes ; then
AC_DEFINE(HAVE_TLS, 1, [define if you have TLS]) AC_DEFINE(HAVE_TLS, 1, [define if you have TLS])
diff --git a/doc/man/man3/ldap_get_option.3 b/doc/man/man3/ldap_get_option.3 diff --git a/doc/man/man3/ldap_get_option.3 b/doc/man/man3/ldap_get_option.3
index 389e1c4fd..60c7d05a5 100644
--- a/doc/man/man3/ldap_get_option.3 --- a/doc/man/man3/ldap_get_option.3
+++ b/doc/man/man3/ldap_get_option.3 +++ b/doc/man/man3/ldap_get_option.3
@@ -772,6 +772,19 @@ must be @@ -772,6 +772,19 @@ must be
@ -62,7 +64,6 @@ index 389e1c4fd..60c7d05a5 100644
On success, the functions return On success, the functions return
.BR LDAP_OPT_SUCCESS , .BR LDAP_OPT_SUCCESS ,
diff --git a/doc/man/man5/ldap.conf.5 b/doc/man/man5/ldap.conf.5 diff --git a/doc/man/man5/ldap.conf.5 b/doc/man/man5/ldap.conf.5
index b6735bab5..612b63a2b 100644
--- a/doc/man/man5/ldap.conf.5 --- a/doc/man/man5/ldap.conf.5
+++ b/doc/man/man5/ldap.conf.5 +++ b/doc/man/man5/ldap.conf.5
@@ -483,6 +483,11 @@ Check the CRL for a whole certificate chain @@ -483,6 +483,11 @@ Check the CRL for a whole certificate chain
@ -78,7 +79,6 @@ index b6735bab5..612b63a2b 100644
.TP .TP
LDAPNOINIT LDAPNOINIT
diff --git a/doc/man/man5/slapd-config.5 b/doc/man/man5/slapd-config.5 diff --git a/doc/man/man5/slapd-config.5 b/doc/man/man5/slapd-config.5
index 6afbd7d6b..2893cd4a5 100644
--- a/doc/man/man5/slapd-config.5 --- a/doc/man/man5/slapd-config.5
+++ b/doc/man/man5/slapd-config.5 +++ b/doc/man/man5/slapd-config.5
@@ -1004,6 +1004,11 @@ Check the CRL for a whole certificate chain @@ -1004,6 +1004,11 @@ Check the CRL for a whole certificate chain
@ -94,7 +94,6 @@ index 6afbd7d6b..2893cd4a5 100644
If If
.B slapd .B slapd
diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5 diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5
index 86abeca80..742568393 100644
--- a/doc/man/man5/slapd.conf.5 --- a/doc/man/man5/slapd.conf.5
+++ b/doc/man/man5/slapd.conf.5 +++ b/doc/man/man5/slapd.conf.5
@@ -1235,6 +1235,11 @@ Check the CRL for a whole certificate chain @@ -1235,6 +1235,11 @@ Check the CRL for a whole certificate chain
@ -110,7 +109,6 @@ index 86abeca80..742568393 100644
Options in this section only apply to the configuration file section Options in this section only apply to the configuration file section
for the specified backend. They are supported by every for the specified backend. They are supported by every
diff --git a/include/ldap.h b/include/ldap.h diff --git a/include/ldap.h b/include/ldap.h
index db6869da8..aae8bebd8 100644
--- a/include/ldap.h --- a/include/ldap.h
+++ b/include/ldap.h +++ b/include/ldap.h
@@ -158,6 +158,10 @@ LDAP_BEGIN_DECL @@ -158,6 +158,10 @@ LDAP_BEGIN_DECL
@ -125,7 +123,6 @@ index db6869da8..aae8bebd8 100644
#define LDAP_OPT_X_TLS_NEVER 0 #define LDAP_OPT_X_TLS_NEVER 0
#define LDAP_OPT_X_TLS_HARD 1 #define LDAP_OPT_X_TLS_HARD 1
diff --git a/libraries/libldap/Makefile.in b/libraries/libldap/Makefile.in diff --git a/libraries/libldap/Makefile.in b/libraries/libldap/Makefile.in
index 636b15506..a1445312f 100644
--- a/libraries/libldap/Makefile.in --- a/libraries/libldap/Makefile.in
+++ b/libraries/libldap/Makefile.in +++ b/libraries/libldap/Makefile.in
@@ -26,7 +26,7 @@ SRCS = bind.c open.c result.c error.c compare.c search.c \ @@ -26,7 +26,7 @@ SRCS = bind.c open.c result.c error.c compare.c search.c \
@ -147,7 +144,6 @@ index 636b15506..a1445312f 100644
assertion.lo deref.lo ldif.lo fetch.lo assertion.lo deref.lo ldif.lo fetch.lo
diff --git a/libraries/libldap/init.c b/libraries/libldap/init.c diff --git a/libraries/libldap/init.c b/libraries/libldap/init.c
index 39ad7ce7c..689144ca3 100644
--- a/libraries/libldap/init.c --- a/libraries/libldap/init.c
+++ b/libraries/libldap/init.c +++ b/libraries/libldap/init.c
@@ -137,7 +137,9 @@ static const struct ol_attribute { @@ -137,7 +137,9 @@ static const struct ol_attribute {
@ -172,7 +168,6 @@ index 39ad7ce7c..689144ca3 100644
gopts->ldo_keepalive_probes = 0; gopts->ldo_keepalive_probes = 0;
gopts->ldo_keepalive_interval = 0; gopts->ldo_keepalive_interval = 0;
diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h
index bcc58f367..d42b82627 100644
--- a/libraries/libldap/ldap-int.h --- a/libraries/libldap/ldap-int.h
+++ b/libraries/libldap/ldap-int.h +++ b/libraries/libldap/ldap-int.h
@@ -260,7 +260,8 @@ struct ldapoptions { @@ -260,7 +260,8 @@ struct ldapoptions {
@ -186,7 +181,6 @@ index bcc58f367..d42b82627 100644
#define LDAP_LDO_TLS_NULLARG #define LDAP_LDO_TLS_NULLARG
#endif #endif
diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c
index 8f842278a..878e1a0a8 100644
--- a/libraries/libldap/tls2.c --- a/libraries/libldap/tls2.c
+++ b/libraries/libldap/tls2.c +++ b/libraries/libldap/tls2.c
@@ -37,6 +37,8 @@ @@ -37,6 +37,8 @@
@ -287,10 +281,9 @@ index 8f842278a..878e1a0a8 100644
} }
diff --git a/libraries/libldap/tls_mc.c b/libraries/libldap/tls_mc.c diff --git a/libraries/libldap/tls_mc.c b/libraries/libldap/tls_mc.c
new file mode 100644 new file mode 100644
index 000000000..8383cb4ec
--- /dev/null --- /dev/null
+++ b/libraries/libldap/tls_mc.c +++ b/libraries/libldap/tls_mc.c
@@ -0,0 +1,1323 @@ @@ -0,0 +1,1179 @@
+#include "portable.h" +#include "portable.h"
+ +
+#ifdef HAVE_MOZNSS_COMPATIBILITY +#ifdef HAVE_MOZNSS_COMPATIBILITY
@ -382,10 +375,16 @@ index 000000000..8383cb4ec
+ perror("IO ERROR: could not set file mode"); + perror("IO ERROR: could not set file mode");
+ goto bail; + goto bail;
+ } + }
+ if ( 0 > close( fd ) ) { + if ( -1 >= fsync( fd ) ) {
+ perror("IO ERROR: could not close file"); + perror("IO ERROR: could not fsync the file");
+ goto bail; + goto bail;
+ } + }
+ if ( 0 > close( fd ) ) {
+ perror("IO ERROR: could not close file");
+ fd = -1;
+ goto bail;
+ }
+ fd = -1;
+ rv = 1; + rv = 1;
+bail: +bail:
+ if ( fd > -1 ) close( fd ); + if ( fd > -1 ) close( fd );
@ -393,23 +392,6 @@ index 000000000..8383cb4ec
+} +}
+ +
+ +
+void
+tlsmc_debug_nspr_msg()
+{
+ int _errno = errno;
+ PRInt32 oserror = PR_GetOSError();
+ char *errno_str = strerror(_errno);
+ char *errstr = PR_Malloc( PR_GetErrorTextLength() + 1 );
+ PR_GetErrorText( errstr );
+ Debug( LDAP_DEBUG_ANY,
+ "... NSPR error %d:`%s'\n",
+ PR_GetError(), errstr, 0 );
+ Debug( LDAP_DEBUG_ANY,
+ "... NSPR OS-error %d, errno %d:%s\n",
+ oserror, _errno, errno_str );
+ PR_Free( errstr );
+}
+
+/* BORROWED FROM tls_m.c */ +/* BORROWED FROM tls_m.c */
+static void +static void
+tlsmc_get_certdb_prefix( const char *certdir, char **realcertdir, char **prefix ) +tlsmc_get_certdb_prefix( const char *certdir, char **realcertdir, char **prefix )
@ -444,6 +426,7 @@ index 000000000..8383cb4ec
+} +}
+ +
+ +
+/* BORROWED FROM tls_m.c */
+static char * +static char *
+tlsmc_get_pin_from_file(const char *token_name, char *filename) +tlsmc_get_pin_from_file(const char *token_name, char *filename)
+{ +{
@ -530,6 +513,7 @@ index 000000000..8383cb4ec
+} +}
+ +
+ +
+/* BORROWED FROM tls_m.c */
+/* +/*
+ * Turn the echoing off on a tty. + * Turn the echoing off on a tty.
+ */ + */
@ -544,6 +528,7 @@ index 000000000..8383cb4ec
+ } + }
+} +}
+ +
+/* BORROWED FROM tls_m.c */
+/* +/*
+ * Turn the echoing on on a tty. + * Turn the echoing on on a tty.
+ */ + */
@ -560,7 +545,7 @@ index 000000000..8383cb4ec
+} +}
+ +
+ +
+/* Borrowed from tlsm_get_pin() */ +/* BORROWED FROM tls_m.c */
+char * +char *
+tlsmc_get_pin( PK11SlotInfo *slot, PRBool retry, void * filename) +tlsmc_get_pin( PK11SlotInfo *slot, PRBool retry, void * filename)
+{ +{
@ -605,7 +590,7 @@ index 000000000..8383cb4ec
+ +
+ +
+int +int
+tlsmc_hash( unsigned char **dest, char *src ) +tlsmc_hash( char **dest, const char *src )
+{ +{
+ int rv = 0; + int rv = 0;
+ unsigned char fp[SHA256_LENGTH]; + unsigned char fp[SHA256_LENGTH];
@ -633,35 +618,6 @@ index 000000000..8383cb4ec
+ +
+ +
+/* BORROWED FROM tls_m.c */ +/* BORROWED FROM tls_m.c */
+static PK11SlotInfo *
+tlsmc_init_open_certdb( const char *nssdb_dir, const char *prefix )
+{
+ PK11SlotInfo *slot = NULL;
+ char *config = NULL;
+
+ config = PR_smprintf( "configDir='%s' tokenDescription='%s' "
+ "certPrefix='%s' keyPrefix='%s' flags=readOnly",
+ nssdb_dir, TLSM_CERTDB_DESC,
+ prefix, prefix );
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_init_open_certdb: INFO: certdb config: `%s`.\n",
+ config, 0, 0 );
+
+ slot = SECMOD_OpenUserDB( config );
+ if ( !slot ) {
+ PRErrorCode errcode = PR_GetError();
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_init_open_certdb: ERROR: cannot open certdb `%s`, error `%d:%s`.\n",
+ nssdb_dir, errcode, PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) );
+ }
+
+ if ( config ) PR_smprintf_free( config );
+
+ return slot;
+}
+
+
+/* Borrowed from tlsm_deferred_init */
+int +int
+tlsmc_open_nssdb( char *ld_cacertdir, NSSInitContext **out_initctx, char **out_nssdb_dir, char **out_nssdb_prefix ) +tlsmc_open_nssdb( char *ld_cacertdir, NSSInitContext **out_initctx, char **out_nssdb_dir, char **out_nssdb_prefix )
+{ +{
@ -754,17 +710,6 @@ index 000000000..8383cb4ec
+} +}
+ +
+ +
+static int
+tlsmc_is_sql_nssdb( const char *ld_cacertdir )
+{
+ if ( 0 == strncmp( "sql:", ld_cacertdir, 4 ) ) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+int +int
+tlsmc_filestamp( char **filestamp, char *path ) +tlsmc_filestamp( char **filestamp, char *path )
+{ +{
@ -773,7 +718,7 @@ index 000000000..8383cb4ec
+ char stime[20]; + char stime[20];
+ +
+ if ( 0 != stat( path, &attr ) ) { + if ( 0 != stat( path, &attr ) ) {
+ perror("IO ERROR: could not stat file"); + rv = -1;
+ goto bail; + goto bail;
+ } + }
+ if ( 0 == strftime(stime, sizeof(stime), "%FT%T", localtime(&attr.st_mtime)) ) { + if ( 0 == strftime(stime, sizeof(stime), "%FT%T", localtime(&attr.st_mtime)) ) {
@ -812,31 +757,28 @@ index 000000000..8383cb4ec
+ "FILES:\n", + "FILES:\n",
+ nssdb_dir, nssdb_prefix, ld_cacertdir, ld_cert, ld_key, geteuid() ); + nssdb_dir, nssdb_prefix, ld_cacertdir, ld_cert, ld_key, geteuid() );
+ +
+ char *bdb_files[] = { "cert8.db", "key3.db", "secmod.db", NULL }; + char *files[] = { "cert8.db", "cert9.db", "key3.db", "key4.db", "secmod.db", NULL };
+ char *sql_files[] = { "cert9.db", "key4.db", "secmod.db", NULL }; + char **filep = NULL;
+ char **files = ( 1 == tlsmc_is_sql_nssdb( ld_cacertdir ) ) ? sql_files : bdb_files; // FIXME we should do all files as default prefix may (and will) change and thus change the semantics of the ld_cacertdir + for ( filep = files; NULL != *filep; filep++ ) {
+ char *file = *files;
+ while ( NULL != ( file = *(files++) ) ) {
+ char *filestamp = NULL; + char *filestamp = NULL;
+ char *path = NULL; + char *path = NULL;
+ path = PR_smprintf( "%s/%s%s", nssdb_dir, nssdb_prefix, file ); + path = PR_smprintf( "%s/%s%s", nssdb_dir, nssdb_prefix, *filep );
+ if ( 0 == tlsmc_filestamp( &filestamp, path ) ) { + if ( 0 == tlsmc_filestamp( &filestamp, path ) ) {
+ Debug( LDAP_DEBUG_ANY, + Debug( LDAP_DEBUG_ANY,
+ "tlsmc_compute_checksum: ERROR: could not stat file `%s'.\n", + "tlsmc_compute_checksum: INFO: could not check file `%s'.\n",
+ path, 0, 0 ); + path, 0, 0 );
+ rv = -1; + rv = -1;
+ } else { + } else {
+ data = PR_sprintf_append( data, "%s: %s\n", file, filestamp ); + data = PR_sprintf_append( data, "%s: %s\n", *filep, filestamp );
+ } + }
+ bail_one:
+ if ( filestamp ) PR_smprintf_free( filestamp ); + if ( filestamp ) PR_smprintf_free( filestamp );
+ if ( path ) PR_smprintf_free( path ); + if ( path ) PR_smprintf_free( path );
+ if ( -1 == rv ) goto bail; + if ( -1 == rv ) goto bail;
+ } + }
+ +
+ /* compute data checksum */ + /* compute data checksum */
+ unsigned char *checksum = NULL; + char *checksum = NULL;
+ if ( 1 != tlsmc_hash( &checksum, data ) ) { + if ( 1 != tlsmc_hash( &checksum, (const char*) data ) ) {
+ checksum = NULL; + checksum = NULL;
+ goto bail; + goto bail;
+ } + }
@ -857,8 +799,6 @@ index 000000000..8383cb4ec
+tlsmc_prepare_dir( char *dir ) +tlsmc_prepare_dir( char *dir )
+{ +{
+ int rv = 0; + int rv = 0;
+ PRFileInfo info;
+ PRStatus prv;
+ char *cacerts_dir = NULL; + char *cacerts_dir = NULL;
+ +
+ Debug( LDAP_DEBUG_TRACE, + Debug( LDAP_DEBUG_TRACE,
@ -897,6 +837,8 @@ index 000000000..8383cb4ec
+ return rv; + return rv;
+} +}
+ +
+
+/* BORROWED FROM 389ds: ssl.c */
+int +int
+tlsmc_extract_cert_to_file(CERTCertDBHandle *certdb_handle, CERTCertificate *cert, char *file_path) +tlsmc_extract_cert_to_file(CERTCertDBHandle *certdb_handle, CERTCertificate *cert, char *file_path)
+{ +{
@ -949,8 +891,7 @@ index 000000000..8383cb4ec
+} +}
+ +
+ +
+ +/* BORROWED FROM 389ds: ssl.c */
+/* borrowed from 389-ds-base, ssl.c, DecryptKey */
+int +int
+tlsmc_decrypt_key(SECKEYEncryptedPrivateKeyInfo *epki, +tlsmc_decrypt_key(SECKEYEncryptedPrivateKeyInfo *epki,
+ SECOidTag algTag, + SECOidTag algTag,
@ -1020,7 +961,7 @@ index 000000000..8383cb4ec
+} +}
+ +
+ +
+ +/* BORROWED FROM 389ds: ssl.c */
+int +int
+tlsmc_extract_key_of_cert_to_file(CERTCertificate *cert, +tlsmc_extract_key_of_cert_to_file(CERTCertificate *cert,
+ char *pin_filename, + char *pin_filename,
@ -1034,7 +975,6 @@ index 000000000..8383cb4ec
+ SECItem clearKeyDER; + SECItem clearKeyDER;
+ char *b64 = NULL; + char *b64 = NULL;
+ char *output = NULL; + char *output = NULL;
+ //SECItem *data = PK11_ExportDERPrivateKeyInfo(key, (void *)pin_filename); // FIXME NULL? // probably won't work
+ +
+ // establish password + // establish password
+ pwitem.data = "secretpw"; // FIXME use pin_filename + pwitem.data = "secretpw"; // FIXME use pin_filename
@ -1110,17 +1050,24 @@ index 000000000..8383cb4ec
+ return rv; + return rv;
+} +}
+ +
+//TODO drop? +
+/* BORROWED FROM 389ds: ssl.c */
+int +int
+tlsmc_extract_cert_key_pair(char *nickname, char *pin_filename, char *dir_name) +tlsmc_extract_cert_key_pair(char *nickname, char *pin_filename, char *dir_name)
+{ +{
+ int rv = 0; + int rv = 0;
+ int fd = -1;
+ CERTCertDBHandle *certHandle = NULL; + CERTCertDBHandle *certHandle = NULL;
+ CERTCertificate *cert = NULL; + CERTCertificate *cert = NULL;
+ char *cert_file_path = NULL; + char *cert_file_path = NULL;
+ char *key_file_path = NULL; + char *key_file_path = NULL;
+ +
+ if ( NULL == nickname ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_extract_cert_key_pair: WARN: supplied nickname is empty (NULL).\n",
+ 0, 0, 0 );
+ rv = 1;
+ goto bail;
+ }
+ if ( NULL == ( certHandle = CERT_GetDefaultCertDB() ) ) { + if ( NULL == ( certHandle = CERT_GetDefaultCertDB() ) ) {
+ // FIXME see same in tlsmc_extract_cacerts() + // FIXME see same in tlsmc_extract_cacerts()
+ Debug( LDAP_DEBUG_ANY, + Debug( LDAP_DEBUG_ANY,
@ -1169,106 +1116,7 @@ index 000000000..8383cb4ec
+} +}
+ +
+ +
+/* Adopted from 389DS. */ +/* BORROWED FROM 389ds: ssl.c */
+static int
+tlsmc_list_certs(CERTCertDBHandle *handle,
+ CERTCertificate *cert,
+ PK11SlotInfo *slot,
+ PRFileDesc *outfile,
+ void *pwarg)
+{
+ SECItem data;
+ int rv = 0;
+ CERTCertList *certs;
+ CERTCertListNode *node;
+ CERTCertificate *the_cert = NULL;
+ char *name = NULL;
+
+ if (!cert) {
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_list_certs: WARN: no cert given.\n",
+ 0, 0, 0 );
+ return rv;
+ }
+ name = cert->nickname;
+
+ if (!name) {
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_list_certs: WARN: no cert nickname.\n",
+ 0, 0, 0 );
+ return rv;
+ }
+ the_cert = CERT_FindCertByNicknameOrEmailAddr(handle, name);
+ if (!the_cert) {
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_list_certs: WARN: could not find cert: %s.\n",
+ name, 0, 0 );
+ return 0;
+ }
+
+ PR_fprintf(outfile, "%s\n", DONOTEDIT);
+ /* Here, we have one cert with the desired nickname or email
+ * address. Now, we will attempt to get a list of ALL certs
+ * with the same subject name as the cert we have. That list
+ * should contain, at a minimum, the one cert we have already found.
+ * If the list of certs is empty (NULL), the libraries have failed.
+ */
+ certs = CERT_CreateSubjectCertList(NULL, handle, &the_cert->derSubject,
+ PR_Now(), PR_FALSE);
+ CERT_DestroyCertificate(the_cert);
+ if (!certs) {
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_list_certs: WARN: problem printing certificates.\n",
+ 0, 0, 0 );
+ return 0;
+ }
+ for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node,certs); node = CERT_LIST_NEXT(node)) {
+ the_cert = node->cert;
+ PR_fprintf(outfile, "Issuer: %s\n", the_cert->issuerName);
+ PR_fprintf(outfile, "Subject: %s\n", the_cert->subjectName);
+ /* now get the subjectList that matches this cert */
+ data.data = the_cert->derCert.data;
+ data.len = the_cert->derCert.len;
+ PR_fprintf(outfile, "\n%s\n%s\n%s\n",
+ PEM_CERT_HEADER,
+ BTOA_DataToAscii(data.data, data.len),
+ PEM_CERT_FOOTER);
+ rv = 1;
+ }
+ if (certs) {
+ CERT_DestroyCertList(certs);
+ }
+ if (rv) {
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_list_certs: WARN: problem printing certificate nicknames.\n",
+ 0, 0, 0 );
+ return 0;
+ }
+
+ return rv;
+}
+
+static char*
+tlsmc_extract_key()
+{
+ return NULL;
+}
+
+/* Adopted from 389DS. */
+static int
+tlsmc_extract_cert(char *token_colon_name, char *filename)
+{
+ CERTCertListNode *node;
+ CERTCertList *list = PK11_ListCerts(PK11CertListAll, NULL);
+ for (node = CERT_LIST_HEAD(list);
+ !CERT_LIST_END(node, list);
+ node = CERT_LIST_NEXT(node)) {
+ CERTCertificate *cert = node->cert;
+ CERTCertTrust trust;
+ }
+ return 0;
+}
+
+int +int
+tlsmc_extract_cacerts( char *dir_name ) +tlsmc_extract_cacerts( char *dir_name )
+{ +{
@ -1376,14 +1224,6 @@ index 000000000..8383cb4ec
+ 0, 0, 0 ); + 0, 0, 0 );
+ } + }
+ +
+ if ( ( ! *ld_cert ) || ( ! *ld_key ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_extract_nssdb: ERROR: cert or key empty.\n",
+ 0, 0, 0 );
+ rv = -1;
+ goto bail;
+ }
+
+ if ( 0 == tlsmc_extract_cert_key_pair( *ld_cert, *ld_key, dir_name ) ) { + if ( 0 == tlsmc_extract_cert_key_pair( *ld_cert, *ld_key, dir_name ) ) {
+ Debug( LDAP_DEBUG_ANY, + Debug( LDAP_DEBUG_ANY,
+ "tlsmc_extract_nssdb: ERROR: could not export user cert and/or key.\n", + "tlsmc_extract_nssdb: ERROR: could not export user cert and/or key.\n",
@ -1397,6 +1237,8 @@ index 000000000..8383cb4ec
+ return rv; + return rv;
+} +}
+ +
+
+/* BORROWED FROM tls_m.c */
+int +int
+tlsmc_close_nssdb(NSSInitContext **initctx) +tlsmc_close_nssdb(NSSInitContext **initctx)
+{ +{
@ -1411,6 +1253,7 @@ index 000000000..8383cb4ec
+ } + }
+} +}
+ +
+
+int +int
+tlsmc_convert( char **ld_cacertdir, char **ld_cert, char **ld_key ) +tlsmc_convert( char **ld_cacertdir, char **ld_cert, char **ld_key )
+{ +{
@ -1419,14 +1262,11 @@ index 000000000..8383cb4ec
+ +
+ NSSInitContext *nss_ctx = NULL; + NSSInitContext *nss_ctx = NULL;
+ char *nssdb_dir_path = NULL; + char *nssdb_dir_path = NULL;
+ char *nssdb_dir_name = NULL;
+ char *nssdb_prefix = NULL; + char *nssdb_prefix = NULL;
+ char *pem_dirs[] = { NULL, NULL, NULL }; + char *pem_dir = NULL;
+ char *readme_path = NULL; + char *readme_path = NULL;
+ char *data = NULL; // data before checksum + char *data = NULL; // data before checksum
+ char *checksum = NULL; // checksummed data + char *checksum = NULL; // checksummed data
+ char **dirs = pem_dirs;
+ char *dir = *dirs;
+ struct stat stat_buf; + struct stat stat_buf;
+ +
+#ifdef LDAP_R_COMPILE +#ifdef LDAP_R_COMPILE
@ -1436,6 +1276,13 @@ index 000000000..8383cb4ec
+ Debug( LDAP_DEBUG_TRACE, + Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_convert: INFO: trying to open NSS DB with CACertDir = `%s'.\n", + "tlsmc_convert: INFO: trying to open NSS DB with CACertDir = `%s'.\n",
+ *ld_cacertdir, 0, 0 ); + *ld_cacertdir, 0, 0 );
+ if ( NULL == ld_cacertdir || NULL == ld_cert || NULL == ld_key ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: ERROR: cannot proceed, some of the arguments are NULL.\n",
+ 0, 0, 0 );
+ rv = 1;
+ goto bail;
+ }
+ if ( 0 == tlsmc_open_nssdb( *ld_cacertdir, &nss_ctx, &nssdb_dir_path, &nssdb_prefix ) ) { + if ( 0 == tlsmc_open_nssdb( *ld_cacertdir, &nss_ctx, &nssdb_dir_path, &nssdb_prefix ) ) {
+ Debug( LDAP_DEBUG_ANY, + Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: INFO: cannot open the NSS DB, expecting PEM configuration is present.\n", + "tlsmc_convert: INFO: cannot open the NSS DB, expecting PEM configuration is present.\n",
@ -1453,58 +1300,61 @@ index 000000000..8383cb4ec
+ goto bail; + goto bail;
+ } + }
+ +
+ pem_dirs[0] = PR_smprintf( "%s-%s-tlsmc-%s", nssdb_dir_path, nssdb_prefix, checksum ); + if ( NULL == ( pem_dir = PR_smprintf( "/tmp/openldap-tlsmc-%s-%s-%s",
+ pem_dirs[1] = PR_smprintf( "/tmp/%s", tlsmc_path2name( pem_dirs[0] ) ); + tlsmc_path2name( nssdb_dir_path ),
+ + nssdb_prefix,
+ int i=0; + checksum) ) ) {
+ while ( NULL != ( dir = *(dirs++) ) ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_convert: INFO: trying with PEM dir = `%s'.\n",
+ dir, 0, 0 );
+ if ( 0 == stat( dir, &stat_buf ) ) {
+ if ( S_ISDIR(stat_buf.st_mode) ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_convert: INFO: using the existing PEM dir.\n",
+ 0, 0, 0 );
+ break;
+ } else {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: WARN: tried to stat the PEM dir but it is not a directory, will try another one.\n",
+ 0, 0, 0 );
+ continue;
+ }
+ }
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_convert: WARN: could not stat PEM dir, will try to create it.\n",
+ 0, 0, 0 );
+ if ( 0 == tlsmc_prepare_dir( dir ) ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_convert: WARN: cannot prepare the PEM dir, will try another one.\n",
+ 0, 0, 0 );
+ continue;
+ }
+ if ( 0 == tlsmc_extract_nssdb( dir, ld_cacertdir, ld_cert, ld_key ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: FATAL: could not extract from the NSS DB.\n",
+ 0, 0, 0 );
+ goto bail;
+ }
+
+ readme_path = PR_smprintf( "%s/" TLSMC_README_FILE_NAME, dir );
+ tlsmc_write_file( readme_path, data, S_IRUSR );
+ rv = 1;
+ break;
+ }
+
+ if ( dir == NULL ) {
+ Debug( LDAP_DEBUG_ANY, + Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: FATAL: no usable PEM dir.\n", + "tlsmc_convert: FATAL: could not allocate memory.\n",
+ 0, 0, 0 ); + 0, 0, 0 );
+ goto bail; + goto bail;
+ } + }
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_convert: INFO: trying with PEM dir = `%s'.\n",
+ pem_dir, 0, 0 );
+ if ( 0 == stat( pem_dir, &stat_buf ) ) {
+ if ( S_ISDIR(stat_buf.st_mode) ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_convert: INFO: using the existing PEM dir.\n",
+ 0, 0, 0 );
+ goto pem_dir_exists;
+ } else {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: FATAL: tried to stat the PEM dir but it is not a directory.\n",
+ 0, 0, 0 );
+ goto bail;
+ }
+ }
+ Debug( LDAP_DEBUG_TRACE,
+ "tlsmc_convert: WARN: could not find the PEM dir, will try to create it.\n",
+ 0, 0, 0 );
+ if ( 0 == tlsmc_prepare_dir( pem_dir ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: FATAL: cannot prepare the PEM dir.\n",
+ 0, 0, 0 );
+ goto bail;
+ }
+ if ( 0 == tlsmc_extract_nssdb( pem_dir, ld_cacertdir, ld_cert, ld_key ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: FATAL: could not extract from the NSS DB.\n",
+ 0, 0, 0 );
+ goto bail;
+ }
+ if ( NULL == ( readme_path = PR_smprintf( "%s/" TLSMC_README_FILE_NAME, pem_dir ) ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: FATAL: could not allocate memory.\n",
+ 0, 0, 0 );
+ goto bail;
+ }
+ if ( 0 == tlsmc_write_file( readme_path, data, S_IRUSR ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_convert: ERROR: could not create README file.\n",
+ 0, 0, 0 );
+ }
+ +
+pem_dir_exists:
+ if (*ld_cacertdir) free(*ld_cacertdir); + if (*ld_cacertdir) free(*ld_cacertdir);
+ *ld_cacertdir = PR_smprintf( "%s/" TLSMC_CACERTS_DIR_NAME, dir ); + *ld_cacertdir = PR_smprintf( "%s/" TLSMC_CACERTS_DIR_NAME, pem_dir );
+ if ( ! ( ( 0 == stat( *ld_cacertdir, &stat_buf ) ) + if ( ! ( ( 0 == stat( *ld_cacertdir, &stat_buf ) )
+ && S_ISDIR(stat_buf.st_mode) ) ) { + && S_ISDIR(stat_buf.st_mode) ) ) {
+ Debug( LDAP_DEBUG_ANY, + Debug( LDAP_DEBUG_ANY,
@ -1514,7 +1364,7 @@ index 000000000..8383cb4ec
+ } + }
+ +
+ if (*ld_cert) free(*ld_cert); + if (*ld_cert) free(*ld_cert);
+ *ld_cert = PR_smprintf( "%s/" TLSMC_CERT_FILE_NAME, dir ); + *ld_cert = PR_smprintf( "%s/" TLSMC_CERT_FILE_NAME, pem_dir );
+ if ( ! ( ( 0 == stat( *ld_cert, &stat_buf ) ) + if ( ! ( ( 0 == stat( *ld_cert, &stat_buf ) )
+ && S_ISREG(stat_buf.st_mode) ) ) { + && S_ISREG(stat_buf.st_mode) ) ) {
+ Debug( LDAP_DEBUG_ANY, + Debug( LDAP_DEBUG_ANY,
@ -1524,7 +1374,7 @@ index 000000000..8383cb4ec
+ } + }
+ +
+ if (*ld_key) free(*ld_key); + if (*ld_key) free(*ld_key);
+ *ld_key = PR_smprintf( "%s/" TLSMC_KEY_FILE_NAME, dir ); + *ld_key = PR_smprintf( "%s/" TLSMC_KEY_FILE_NAME, pem_dir );
+ if ( ! ( ( 0 == stat( *ld_key, &stat_buf ) ) + if ( ! ( ( 0 == stat( *ld_key, &stat_buf ) )
+ && S_ISREG(stat_buf.st_mode) ) ) { + && S_ISREG(stat_buf.st_mode) ) ) {
+ Debug( LDAP_DEBUG_ANY, + Debug( LDAP_DEBUG_ANY,
@ -1536,8 +1386,8 @@ index 000000000..8383cb4ec
+ rv = 1; + rv = 1;
+ +
+bail: +bail:
+ if ( pem_dirs[0] ) PR_smprintf_free( pem_dirs[0] ); + if ( pem_dir ) PR_smprintf_free( pem_dir );
+ if ( pem_dirs[1] ) PR_smprintf_free( pem_dirs[1] ); + if ( data ) free( data );
+ if ( nssdb_prefix ) free( nssdb_prefix ); + if ( nssdb_prefix ) free( nssdb_prefix );
+ if ( nssdb_dir_path ) free( nssdb_dir_path ); + if ( nssdb_dir_path ) free( nssdb_dir_path );
+ if ( nss_ctx ) tlsmc_close_nssdb( &nss_ctx ); + if ( nss_ctx ) tlsmc_close_nssdb( &nss_ctx );
@ -1550,8 +1400,6 @@ index 000000000..8383cb4ec
+} +}
+ +
+ +
+
+
+// returns 0 when successful +// returns 0 when successful
+int +int
+tlsmc_intercept_initialization( struct ldapoptions *lo, int is_server ) +tlsmc_intercept_initialization( struct ldapoptions *lo, int is_server )
@ -1606,6 +1454,7 @@ index 000000000..8383cb4ec
+ return rv; + return rv;
+} +}
+ +
+
+#endif /* HAVE_MOZNSS_COMPATIBILITY */ +#endif /* HAVE_MOZNSS_COMPATIBILITY */
+/* +/*
+ emacs settings + emacs settings
@ -1616,7 +1465,6 @@ index 000000000..8383cb4ec
+*/ +*/
diff --git a/libraries/libldap/tls_mc.h b/libraries/libldap/tls_mc.h diff --git a/libraries/libldap/tls_mc.h b/libraries/libldap/tls_mc.h
new file mode 100644 new file mode 100644
index 000000000..2e6e567dc
--- /dev/null --- /dev/null
+++ b/libraries/libldap/tls_mc.h +++ b/libraries/libldap/tls_mc.h
@@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
@ -1640,10 +1488,9 @@ index 000000000..2e6e567dc
+#endif /* _LDAP_TLSMC_H */ +#endif /* _LDAP_TLSMC_H */
diff --git a/libraries/libldap/tls_mc_ossl.c b/libraries/libldap/tls_mc_ossl.c diff --git a/libraries/libldap/tls_mc_ossl.c b/libraries/libldap/tls_mc_ossl.c
new file mode 100644 new file mode 100644
index 000000000..d61ec207c
--- /dev/null --- /dev/null
+++ b/libraries/libldap/tls_mc_ossl.c +++ b/libraries/libldap/tls_mc_ossl.c
@@ -0,0 +1,90 @@ @@ -0,0 +1,95 @@
+#include "portable.h" +#include "portable.h"
+ +
+/* This file contains functions that require OpenSSL headers due to some +/* This file contains functions that require OpenSSL headers due to some
@ -1695,12 +1542,17 @@ index 000000000..d61ec207c
+ last_slash_p = strrchr( cert_path, '/' ); + last_slash_p = strrchr( cert_path, '/' );
+ cert_filename_p = last_slash_p ? last_slash_p + 1 : cert_path; + cert_filename_p = last_slash_p ? last_slash_p + 1 : cert_path;
+ for ( cnt = 0; cnt < 10; cnt++ ) { + for ( cnt = 0; cnt < 10; cnt++ ) {
+ symlink_path = PR_smprintf( "%s/%08lx.%d", cacerts_dir, hash, cnt ); + if ( NULL == ( symlink_path = PR_smprintf( "%s/%08lx.%d", cacerts_dir, hash, cnt ) ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "tlsmc_cert_create_hash_symlink: ERROR: memory allocation error.\n",
+ 0, 0, 0 );
+ continue;
+ }
+ if ( 0 != symlink( cert_filename_p, symlink_path ) ) { + if ( 0 != symlink( cert_filename_p, symlink_path ) ) {
+ if ( errno == EEXIST ) { + if ( errno == EEXIST ) {
+ Debug( LDAP_DEBUG_ANY, + Debug( LDAP_DEBUG_ANY,
+ "tlsmc_cert_create_hash_symlink: INFO: symlink `%s' already exists.\n", + "tlsmc_cert_create_hash_symlink: INFO: symlink `%s' already exists.\n",
+ 0, 0, 0 ); + symlink_path, 0, 0 );
+ if ( symlink_path ) PR_smprintf( symlink_path ); + if ( symlink_path ) PR_smprintf( symlink_path );
+ continue; + continue;
+ } + }
@ -1736,7 +1588,6 @@ index 000000000..d61ec207c
+*/ +*/
diff --git a/libraries/libldap/tls_mc_ossl.h b/libraries/libldap/tls_mc_ossl.h diff --git a/libraries/libldap/tls_mc_ossl.h b/libraries/libldap/tls_mc_ossl.h
new file mode 100644 new file mode 100644
index 000000000..1b4284576
--- /dev/null --- /dev/null
+++ b/libraries/libldap/tls_mc_ossl.h +++ b/libraries/libldap/tls_mc_ossl.h
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
@ -1753,7 +1604,6 @@ index 000000000..1b4284576
+#endif +#endif
+#endif +#endif
diff --git a/libraries/libldap_r/Makefile.in b/libraries/libldap_r/Makefile.in diff --git a/libraries/libldap_r/Makefile.in b/libraries/libldap_r/Makefile.in
index cdf4070dd..c7a86c95f 100644
--- a/libraries/libldap_r/Makefile.in --- a/libraries/libldap_r/Makefile.in
+++ b/libraries/libldap_r/Makefile.in +++ b/libraries/libldap_r/Makefile.in
@@ -28,7 +28,7 @@ XXSRCS = apitest.c test.c \ @@ -28,7 +28,7 @@ XXSRCS = apitest.c test.c \

View File

@ -5,7 +5,7 @@
Name: openldap Name: openldap
Version: 2.4.45 Version: 2.4.45
Release: 4%{?dist} Release: 5%{?dist}
Summary: LDAP support libraries Summary: LDAP support libraries
Group: System Environment/Daemons Group: System Environment/Daemons
License: OpenLDAP License: OpenLDAP
@ -516,6 +516,14 @@ exit 0
%{_mandir}/man3/* %{_mandir}/man3/*
%changelog %changelog
* Wed Dec 6 2017 Matus Honek <mhonek@redhat.com> - 2.4.45-5
- Fix issues in MozNSS compatibility layer (#1400570)
+ Force write file with fsync to avoid race conditions
+ Always filestamp both sql and dbm NSS DB variants to not rely on default DB type prefix
+ Allow missing cert and key which is a valid usecase
+ Create extraction folder only in /tmp to simplify selinux rules
+ Fix Covscan issues
* Fri Nov 3 2017 Matus Honek <mhonek@redhat.com> - 2.4.45-4 * Fri Nov 3 2017 Matus Honek <mhonek@redhat.com> - 2.4.45-4
- Build with OpenSSL with MozNSS compatibility layer (#1400570) - Build with OpenSSL with MozNSS compatibility layer (#1400570)