Re: new libpq SSL connection option - Mailing list pgsql-hackers
From | Magnus Hagander |
---|---|
Subject | Re: new libpq SSL connection option |
Date | |
Msg-id | 495DE8B6.4040505@hagander.net Whole thread Raw |
In response to | Re: new libpq SSL connection option (Andrew Chernow <ac@esilo.com>) |
Responses |
Re: new libpq SSL connection option
Re: new libpq SSL connection option |
List | pgsql-hackers |
Andrew Chernow wrote: > Magnus Hagander wrote: >> Alex Hunsaker wrote: >>> On Sat, Dec 27, 2008 at 11:50, Andrew Chernow <ac@esilo.com> wrote: >>>> Why does pqGetHomeDirectory have to succeed to use >>>> conn->sslrootcert. Maybe >>>> this should be an OR of the two since sslrootcert is not dependent on >>>> homedir? >>>> >>>> around line 970 src/interfaces/libpq/fe-secure.c >>>> >>>> if (conn->sslrootcert || pqGetHomeDirectory(homedir, sizeof(homedir))) >>> >>> Certainly, did we miss anywhere else? >>> > > Yes, the homedir variable is used again later in the function. homedir > could be invalid since pqGetHomeDirectory might not get called. Maybe > something like below would do the trick: > > /* when used, it can't be an empty string. */ > *homedir = 0; > > /* If either are NULL, homedir is needed */ > if (!conn->sslrootcert || !conn->sslcrl) > pqGetHomeDirectory(homedir, sizeof(homedir)); > > /* one of them must be valid */ > if (conn->sslrootcert || *homedir) How about this patch? There's a lot of whitespace change due to indentation change, so I've included a version without it for reference. Also, it looks like we have the same problem with the private key, in client_cert_cb(), agreed? //Magnus diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c index ca2d33e..6957542 100644 --- a/src/interfaces/libpq/fe-secure.c +++ b/src/interfaces/libpq/fe-secure.c @@ -964,76 +964,85 @@ initialize_SSL(PGconn *conn) * If sslverify is set to anything other than "none", perform certificate * verification. If set to "cn" we will also do further verifications after * the connection has been completed. + * + * If we are going to look for either root certificate or CRL in the home directory, + * we need pqGetHomeDirectory() to succeed. In other cases, we don't need to + * get the home directory explicitly. */ - - /* Set up to verify server cert, if root.crt is present */ - if (pqGetHomeDirectory(homedir, sizeof(homedir))) + if (!conn->sslrootcert || !conn->sslcrl) { - if (conn->sslrootcert) - strncpy(fnbuf, conn->sslrootcert, sizeof(fnbuf)); - else - snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CERT_FILE); - - if (stat(fnbuf, &buf) == 0) + if (!pqGetHomeDirectory(homedir, sizeof(homedir))) { - X509_STORE *cvstore; - - if (!SSL_CTX_load_verify_locations(SSL_context, fnbuf, NULL)) + if (strcmp(conn->sslverify, "none") != 0) { - char *err = SSLerrmessage(); - printfPQExpBuffer(&conn->errorMessage, - libpq_gettext("could not read root certificate file \"%s\": %s\n"), - fnbuf, err); - SSLerrfree(err); + libpq_gettext("cannot find home directory to locate root certificate file")); return -1; } + } + } + else + { + homedir[0] = '\0'; + } - if ((cvstore = SSL_CTX_get_cert_store(SSL_context)) != NULL) - { - if (conn->sslcrl) - strncpy(fnbuf, conn->sslcrl, sizeof(fnbuf)); - else - snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CRL_FILE); - /* setting the flags to check against the complete CRL chain */ - if (X509_STORE_load_locations(cvstore, fnbuf, NULL) != 0) -/* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */ -#ifdef X509_V_FLAG_CRL_CHECK - X509_STORE_set_flags(cvstore, - X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); - /* if not found, silently ignore; we do not require CRL */ -#else - { - char *err = SSLerrmessage(); - printfPQExpBuffer(&conn->errorMessage, - libpq_gettext("SSL library does not support CRL certificates (file \"%s\")\n"), - fnbuf); - SSLerrfree(err); - return -1; - } -#endif - } + if (conn->sslrootcert) + strncpy(fnbuf, conn->sslrootcert, sizeof(fnbuf)); + else + snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CERT_FILE); + + if (stat(fnbuf, &buf) == 0) + { + X509_STORE *cvstore; + + if (!SSL_CTX_load_verify_locations(SSL_context, fnbuf, NULL)) + { + char *err = SSLerrmessage(); - SSL_CTX_set_verify(SSL_context, SSL_VERIFY_PEER, verify_cb); + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("could not read root certificate file \"%s\": %s\n"), + fnbuf, err); + SSLerrfree(err); + return -1; } - else + + if ((cvstore = SSL_CTX_get_cert_store(SSL_context)) != NULL) { - if (strcmp(conn->sslverify, "none") != 0) + if (conn->sslcrl) + strncpy(fnbuf, conn->sslcrl, sizeof(fnbuf)); + else + snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CRL_FILE); + + /* setting the flags to check against the complete CRL chain */ + if (X509_STORE_load_locations(cvstore, fnbuf, NULL) != 0) +/* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */ +#ifdef X509_V_FLAG_CRL_CHECK + X509_STORE_set_flags(cvstore, + X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); + /* if not found, silently ignore; we do not require CRL */ +#else { + char *err = SSLerrmessage(); + printfPQExpBuffer(&conn->errorMessage, - libpq_gettext("root certificate file (%s) not found"), fnbuf); + libpq_gettext("SSL library does not support CRL certificates (file \"%s\")\n"), + fnbuf); + SSLerrfree(err); return -1; } +#endif } - } + + SSL_CTX_set_verify(SSL_context, SSL_VERIFY_PEER, verify_cb); + } /* root certificate exists */ else { if (strcmp(conn->sslverify, "none") != 0) { printfPQExpBuffer(&conn->errorMessage, - libpq_gettext("cannot find home directory to locate root certificate file")); + libpq_gettext("root certificate file (%s) not found"), fnbuf); return -1; } } diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c index ca2d33e..6957542 100644 --- a/src/interfaces/libpq/fe-secure.c +++ b/src/interfaces/libpq/fe-secure.c @@ -964,11 +964,30 @@ initialize_SSL(PGconn *conn) * If sslverify is set to anything other than "none", perform certificate * verification. If set to "cn" we will also do further verifications after * the connection has been completed. + * + * If we are going to look for either root certificate or CRL in the home directory, + * we need pqGetHomeDirectory() to succeed. In other cases, we don't need to + * get the home directory explicitly. */ - - /* Set up to verify server cert, if root.crt is present */ - if (pqGetHomeDirectory(homedir, sizeof(homedir))) + if (!conn->sslrootcert || !conn->sslcrl) + { + if (!pqGetHomeDirectory(homedir, sizeof(homedir))) { + if (strcmp(conn->sslverify, "none") != 0) + { + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("cannot find home directory to locate root certificate file")); + return -1; + } + } + } + else + { + homedir[0] = '\0'; + } + + + if (conn->sslrootcert) strncpy(fnbuf, conn->sslrootcert, sizeof(fnbuf)); else @@ -1017,7 +1036,7 @@ initialize_SSL(PGconn *conn) } SSL_CTX_set_verify(SSL_context, SSL_VERIFY_PEER, verify_cb); - } + } /* root certificate exists */ else { if (strcmp(conn->sslverify, "none") != 0) @@ -1027,16 +1046,6 @@ initialize_SSL(PGconn *conn) return -1; } } - } - else - { - if (strcmp(conn->sslverify, "none") != 0) - { - printfPQExpBuffer(&conn->errorMessage, - libpq_gettext("cannot find home directory to locate root certificate file")); - return -1; - } - } /* set up mechanism to provide client certificate, if available */ SSL_CTX_set_client_cert_cb(SSL_context, client_cert_cb);
pgsql-hackers by date: