mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
In initialize_SSL, don't fail unnecessarily when home dir is unavailable.
Instead, just act as though the certificate file(s) are not present.
There is only one case where this need be a hard failure condition: when
sslmode is verify-ca or verify-full, not having a root cert file is an
error. Change the logic so that we complain only in that case, and
otherwise fall through cleanly. This is how it used to behave pre-9.0,
but my patch 4ed4b6c54e
of 2010-05-26 broke
the case. Per report from Christian Kastner.
This commit is contained in:
parent
ee3838b1d3
commit
bd58d9d883
@ -825,37 +825,37 @@ initialize_SSL(PGconn *conn)
|
|||||||
char homedir[MAXPGPATH];
|
char homedir[MAXPGPATH];
|
||||||
char fnbuf[MAXPGPATH];
|
char fnbuf[MAXPGPATH];
|
||||||
char sebuf[256];
|
char sebuf[256];
|
||||||
|
bool have_homedir;
|
||||||
bool have_cert;
|
bool have_cert;
|
||||||
EVP_PKEY *pkey = NULL;
|
EVP_PKEY *pkey = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We'll need the home directory if any of the relevant parameters are
|
* We'll need the home directory if any of the relevant parameters are
|
||||||
* defaulted.
|
* defaulted. If pqGetHomeDirectory fails, act as though none of the
|
||||||
|
* files could be found.
|
||||||
*/
|
*/
|
||||||
if (!(conn->sslcert && strlen(conn->sslcert) > 0) ||
|
if (!(conn->sslcert && strlen(conn->sslcert) > 0) ||
|
||||||
!(conn->sslkey && strlen(conn->sslkey) > 0) ||
|
!(conn->sslkey && strlen(conn->sslkey) > 0) ||
|
||||||
!(conn->sslrootcert && strlen(conn->sslrootcert) > 0) ||
|
!(conn->sslrootcert && strlen(conn->sslrootcert) > 0) ||
|
||||||
!(conn->sslcrl && strlen(conn->sslcrl) > 0))
|
!(conn->sslcrl && strlen(conn->sslcrl) > 0))
|
||||||
{
|
have_homedir = pqGetHomeDirectory(homedir, sizeof(homedir));
|
||||||
if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
|
else /* won't need it */
|
||||||
{
|
have_homedir = false;
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
|
||||||
libpq_gettext("could not get home directory to locate client certificate files\n"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
homedir[0] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the client certificate file */
|
/* Read the client certificate file */
|
||||||
if (conn->sslcert && strlen(conn->sslcert) > 0)
|
if (conn->sslcert && strlen(conn->sslcert) > 0)
|
||||||
strncpy(fnbuf, conn->sslcert, sizeof(fnbuf));
|
strncpy(fnbuf, conn->sslcert, sizeof(fnbuf));
|
||||||
else
|
else if (have_homedir)
|
||||||
snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_CERT_FILE);
|
snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_CERT_FILE);
|
||||||
|
else
|
||||||
|
fnbuf[0] = '\0';
|
||||||
|
|
||||||
if (stat(fnbuf, &buf) != 0)
|
if (fnbuf[0] == '\0')
|
||||||
|
{
|
||||||
|
/* no home directory, proceed without a client cert */
|
||||||
|
have_cert = false;
|
||||||
|
}
|
||||||
|
else if (stat(fnbuf, &buf) != 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If file is not present, just go on without a client cert; server
|
* If file is not present, just go on without a client cert; server
|
||||||
@ -1001,11 +1001,13 @@ initialize_SSL(PGconn *conn)
|
|||||||
strncpy(fnbuf, conn->sslkey, sizeof(fnbuf));
|
strncpy(fnbuf, conn->sslkey, sizeof(fnbuf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (have_homedir)
|
||||||
{
|
{
|
||||||
/* No PGSSLKEY specified, load default file */
|
/* No PGSSLKEY specified, load default file */
|
||||||
snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_KEY_FILE);
|
snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_KEY_FILE);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
fnbuf[0] = '\0';
|
||||||
|
|
||||||
if (have_cert && fnbuf[0] != '\0')
|
if (have_cert && fnbuf[0] != '\0')
|
||||||
{
|
{
|
||||||
@ -1060,10 +1062,13 @@ initialize_SSL(PGconn *conn)
|
|||||||
*/
|
*/
|
||||||
if (conn->sslrootcert && strlen(conn->sslrootcert) > 0)
|
if (conn->sslrootcert && strlen(conn->sslrootcert) > 0)
|
||||||
strncpy(fnbuf, conn->sslrootcert, sizeof(fnbuf));
|
strncpy(fnbuf, conn->sslrootcert, sizeof(fnbuf));
|
||||||
else
|
else if (have_homedir)
|
||||||
snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CERT_FILE);
|
snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CERT_FILE);
|
||||||
|
else
|
||||||
|
fnbuf[0] = '\0';
|
||||||
|
|
||||||
if (stat(fnbuf, &buf) == 0)
|
if (fnbuf[0] != '\0' &&
|
||||||
|
stat(fnbuf, &buf) == 0)
|
||||||
{
|
{
|
||||||
X509_STORE *cvstore;
|
X509_STORE *cvstore;
|
||||||
|
|
||||||
@ -1082,11 +1087,14 @@ initialize_SSL(PGconn *conn)
|
|||||||
{
|
{
|
||||||
if (conn->sslcrl && strlen(conn->sslcrl) > 0)
|
if (conn->sslcrl && strlen(conn->sslcrl) > 0)
|
||||||
strncpy(fnbuf, conn->sslcrl, sizeof(fnbuf));
|
strncpy(fnbuf, conn->sslcrl, sizeof(fnbuf));
|
||||||
else
|
else if (have_homedir)
|
||||||
snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CRL_FILE);
|
snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CRL_FILE);
|
||||||
|
else
|
||||||
|
fnbuf[0] = '\0';
|
||||||
|
|
||||||
/* Set the flags to check against the complete CRL chain */
|
/* Set the flags to check against the complete CRL chain */
|
||||||
if (X509_STORE_load_locations(cvstore, fnbuf, NULL) == 1)
|
if (fnbuf[0] != '\0' &&
|
||||||
|
X509_STORE_load_locations(cvstore, fnbuf, NULL) == 1)
|
||||||
{
|
{
|
||||||
/* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */
|
/* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */
|
||||||
#ifdef X509_V_FLAG_CRL_CHECK
|
#ifdef X509_V_FLAG_CRL_CHECK
|
||||||
@ -1116,6 +1124,16 @@ initialize_SSL(PGconn *conn)
|
|||||||
*/
|
*/
|
||||||
if (conn->sslmode[0] == 'v') /* "verify-ca" or "verify-full" */
|
if (conn->sslmode[0] == 'v') /* "verify-ca" or "verify-full" */
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* The only way to reach here with an empty filename is if
|
||||||
|
* pqGetHomeDirectory failed. That's a sufficiently unusual case
|
||||||
|
* that it seems worth having a specialized error message for it.
|
||||||
|
*/
|
||||||
|
if (fnbuf[0] == '\0')
|
||||||
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
|
libpq_gettext("could not get home directory to locate root certificate file\n"
|
||||||
|
"Either provide the file or change sslmode to disable server certificate verification.\n"));
|
||||||
|
else
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("root certificate file \"%s\" does not exist\n"
|
libpq_gettext("root certificate file \"%s\" does not exist\n"
|
||||||
"Either provide the file or change sslmode to disable server certificate verification.\n"), fnbuf);
|
"Either provide the file or change sslmode to disable server certificate verification.\n"), fnbuf);
|
||||||
|
Loading…
Reference in New Issue
Block a user