Skip to content

Commit

Permalink
Issue 6349 - RFE - Use previously extracted key path (#6363)
Browse files Browse the repository at this point in the history
Bug Description: slapd_SSL_client_auth uses the values of
KeyExtractFile and CertExtractFile from the configuration
entry, and each time it's called attempts to determine if
this is an absolute or relative path. If the path is
relative, it prepends a /tmp location based on if the
running system /tmp is a private namespace or not. This
causes a replication client that uses TLS certificate
authentication to repeatedly emit warnings that the
key extraction occurred to non-private tmp in a
container.

Fix Description: During key extraction, we extract
keys and files using the "last token" from nss as the
item that we extract. Because of this, we know that there
can only be a single extracted key and cert, allowing
us to extract these and store the full abs path of
the extracted files rather than deriving them during
each client iteration.

fixes: #6349

Author: William Brown <[email protected]>

Review by: @tbordaz @progier389 @droideck (Thanks!)
  • Loading branch information
Firstyear authored Oct 18, 2024
1 parent ffb9e8a commit b1b4356
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 35 deletions.
1 change: 1 addition & 0 deletions ldap/servers/slapd/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1161,6 +1161,7 @@ main(int argc, char **argv)
compute_terminate();
SSL_ShutdownServerSessionIDCache();
SSL_ClearSessionCache();
slapd_ssl_destroy();
ndn_cache_destroy();
NSS_Shutdown();
dse_destroy_backup_lock();
Expand Down
1 change: 1 addition & 0 deletions ldap/servers/slapd/proto-slap.h
Original file line number Diff line number Diff line change
Expand Up @@ -1164,6 +1164,7 @@ void do_search(Slapi_PBlock *pb);
char *check_private_certdir(void);
int slapd_nss_init(int init_ssl, int config_available);
int slapd_ssl_init(void);
void slapd_ssl_destroy(void);
int slapd_ssl_init2(PRFileDesc **fd, int startTLS);
int slapd_security_library_is_initialized(void);
int slapd_ssl_listener_is_initialized(void);
Expand Down
61 changes: 26 additions & 35 deletions ldap/servers/slapd/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ static int stimeout;
static char *ciphers = NULL;
static char *configDN = "cn=encryption,cn=config";

/* The paths of extracted key and certs if any. */
static char *key_extract_file = NULL;
static char *cert_extract_file = NULL;


/* Copied from libadmin/libadmin.h public/nsapi.h */
#define SERVER_KEY_NAME "Server-Key"
Expand Down Expand Up @@ -1341,6 +1345,13 @@ slapd_ssl_init()
return 0;
}

void
slapd_ssl_destroy(void)
{
slapi_ch_free_string(&key_extract_file);
slapi_ch_free_string(&cert_extract_file);
}

/*
* val: sslVersionMin/Max value set in cn=encryption,cn=config (INPUT)
* rval: Corresponding value to set SSLVersionRange (OUTPUT)
Expand Down Expand Up @@ -2063,8 +2074,6 @@ slapd_SSL_client_auth(LDAP *ld)
SVRCOREStdPinObj *StdPinObj;
SVRCOREError err = SVRCORE_Success;
char *finalpersonality = NULL;
char *CertExtractFile = NULL;
char *KeyExtractFile = NULL;

if ((family_list = getChildren(configDN))) {
char **family;
Expand Down Expand Up @@ -2169,11 +2178,6 @@ slapd_SSL_client_auth(LDAP *ld)
slapi_ch_free_string(&finalpersonality);
finalpersonality = personality;
slapi_ch_free_string(&cipher);
/* Get ServerCert/KeyExtractFile from given entry if any. */
slapi_ch_free_string(&CertExtractFile);
CertExtractFile = slapi_entry_attr_get_charptr(entry, "ServerCertExtractFile");
slapi_ch_free_string(&KeyExtractFile);
KeyExtractFile = slapi_entry_attr_get_charptr(entry, "ServerKeyExtractFile");
freeConfigEntry(&entry);
} /* end of for */

Expand All @@ -2191,37 +2195,12 @@ slapd_SSL_client_auth(LDAP *ld)
"(no password). (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
errorCode, slapd_pr_strerror(errorCode));
} else {
if (slapi_client_uses_non_nss(ld) && config_get_extract_pem()) {
char *certdir;
char *keyfile = NULL;
char *certfile = NULL;
if (slapi_client_uses_non_nss(ld) && key_extract_file && cert_extract_file) {
char *keyfile = slapi_ch_strdup(key_extract_file);
char *certfile = slapi_ch_strdup(cert_extract_file);
/* If a private tmp namespace exists
* it is the place where PEM files will be extracted
*/
if ((certdir = check_private_certdir()) == NULL) {
certdir = config_get_certdir();
}
if (KeyExtractFile) {
if ('/' == *KeyExtractFile) {
keyfile = KeyExtractFile;
} else {
keyfile = slapi_ch_smprintf("%s/%s", certdir, KeyExtractFile);
slapi_ch_free_string(&KeyExtractFile);
}
} else {
keyfile = slapi_ch_smprintf("%s/%s-Key%s", certdir, finalpersonality, PEMEXT);
}
if (CertExtractFile) {
if ('/' == *CertExtractFile) {
certfile = CertExtractFile;
} else {
certfile = slapi_ch_smprintf("%s/%s", certdir, CertExtractFile);
slapi_ch_free_string(&CertExtractFile);
}
} else {
certfile = slapi_ch_smprintf("%s/%s%s", certdir, finalpersonality, PEMEXT);
}
slapi_ch_free_string(&certdir);
if (PR_SUCCESS != PR_Access(keyfile, PR_ACCESS_EXISTS)) {
slapi_ch_free_string(&keyfile);
slapd_SSL_warn("SSL key file (%s) for client authentication does not exist. "
Expand Down Expand Up @@ -2254,6 +2233,10 @@ slapd_SSL_client_auth(LDAP *ld)
slapi_ch_free_string(&certfile);
}
} else {
if (config_get_extract_pem() && (key_extract_file == NULL || cert_extract_file == NULL)) {
slapd_SSL_warn("SSL key or certificate file were not extracted during initialisation.");
}

rc = ldap_set_option(ld, LDAP_OPT_X_TLS_KEYFILE, SERVER_KEY_NAME);
if (rc) {
slapd_SSL_warn("SSL client authentication cannot be used "
Expand Down Expand Up @@ -2659,6 +2642,10 @@ slapd_extract_cert(Slapi_Entry *entry, int isCA)
}
}
rv = SECSuccess;

slapi_ch_free_string(&cert_extract_file);
cert_extract_file = slapi_ch_strdup(certfile);

bail:
CERT_DestroyCertList(list);
slapi_ch_free_string(&CertExtractFile);
Expand Down Expand Up @@ -3012,6 +2999,10 @@ slapd_extract_key(Slapi_Entry *entry, char *token __attribute__((unused)), PK11S
PR_fprintf(outFile, "\n%s\n", KEY_TRAILER);
#endif
rv = SECSuccess;

slapi_ch_free_string(&key_extract_file);
key_extract_file = slapi_ch_strdup(keyfile);

bail:
slapi_ch_free_string(&certdir);
slapi_ch_free_string(&KeyExtractFile);
Expand Down

0 comments on commit b1b4356

Please sign in to comment.