Defend against possibility that SSL error reporting mechanism returns

a NULL pointer.  Per report from Stephen Pillinger 8-Nov-01.
This commit is contained in:
Tom Lane 2001-11-11 02:09:05 +00:00
parent f6ee99a062
commit 15c21bf8e1
2 changed files with 76 additions and 11 deletions

View File

@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.259 2001/11/10 23:06:12 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.260 2001/11/11 02:09:05 tgl Exp $
* *
* NOTES * NOTES
* *
@ -271,6 +271,7 @@ __attribute__((format(printf, 1, 2)));
#ifdef USE_SSL #ifdef USE_SSL
static void InitSSL(void); static void InitSSL(void);
static const char *SSLerrmessage(void);
#endif #endif
@ -1108,8 +1109,8 @@ ProcessStartupPacket(Port *port, bool SSLdone)
!SSL_set_fd(port->ssl, port->sock) || !SSL_set_fd(port->ssl, port->sock) ||
SSL_accept(port->ssl) <= 0) SSL_accept(port->ssl) <= 0)
{ {
elog(DEBUG, "failed to initialize SSL connection: %s (%s)", elog(DEBUG, "failed to initialize SSL connection: %s (%m)",
ERR_reason_error_string(ERR_get_error()), strerror(errno)); SSLerrmessage());
return STATUS_ERROR; return STATUS_ERROR;
} }
} }
@ -2379,6 +2380,7 @@ CountChildren(void)
} }
#ifdef USE_SSL #ifdef USE_SSL
/* /*
* Initialize SSL library and structures * Initialize SSL library and structures
*/ */
@ -2393,31 +2395,56 @@ InitSSL(void)
if (!SSL_context) if (!SSL_context)
{ {
postmaster_error("failed to create SSL context: %s", postmaster_error("failed to create SSL context: %s",
ERR_reason_error_string(ERR_get_error())); SSLerrmessage());
ExitPostmaster(1); ExitPostmaster(1);
} }
snprintf(fnbuf, sizeof(fnbuf), "%s/server.crt", DataDir); snprintf(fnbuf, sizeof(fnbuf), "%s/server.crt", DataDir);
if (!SSL_CTX_use_certificate_file(SSL_context, fnbuf, SSL_FILETYPE_PEM)) if (!SSL_CTX_use_certificate_file(SSL_context, fnbuf, SSL_FILETYPE_PEM))
{ {
postmaster_error("failed to load server certificate (%s): %s", postmaster_error("failed to load server certificate (%s): %s",
fnbuf, ERR_reason_error_string(ERR_get_error())); fnbuf, SSLerrmessage());
ExitPostmaster(1); ExitPostmaster(1);
} }
snprintf(fnbuf, sizeof(fnbuf), "%s/server.key", DataDir); snprintf(fnbuf, sizeof(fnbuf), "%s/server.key", DataDir);
if (!SSL_CTX_use_PrivateKey_file(SSL_context, fnbuf, SSL_FILETYPE_PEM)) if (!SSL_CTX_use_PrivateKey_file(SSL_context, fnbuf, SSL_FILETYPE_PEM))
{ {
postmaster_error("failed to load private key file (%s): %s", postmaster_error("failed to load private key file (%s): %s",
fnbuf, ERR_reason_error_string(ERR_get_error())); fnbuf, SSLerrmessage());
ExitPostmaster(1); ExitPostmaster(1);
} }
if (!SSL_CTX_check_private_key(SSL_context)) if (!SSL_CTX_check_private_key(SSL_context))
{ {
postmaster_error("check of private key failed: %s", postmaster_error("check of private key failed: %s",
ERR_reason_error_string(ERR_get_error())); SSLerrmessage());
ExitPostmaster(1); ExitPostmaster(1);
} }
} }
#endif
/*
* Obtain reason string for last SSL error
*
* Some caution is needed here since ERR_reason_error_string will
* return NULL if it doesn't recognize the error code. We don't
* want to return NULL ever.
*/
static const char *
SSLerrmessage(void)
{
unsigned long errcode;
const char *errreason;
static char errbuf[32];
errcode = ERR_get_error();
if (errcode == 0)
return "No SSL error reported";
errreason = ERR_reason_error_string(errcode);
if (errreason != NULL)
return errreason;
snprintf(errbuf, sizeof(errbuf), "SSL error code %lu", errcode);
return errbuf;
}
#endif /* USE_SSL */
/* /*
* Fire off a subprocess for startup/shutdown/checkpoint. * Fire off a subprocess for startup/shutdown/checkpoint.

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.180 2001/11/05 17:46:37 momjian Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.181 2001/11/11 02:09:05 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -186,6 +186,9 @@ static char *conninfo_getval(PQconninfoOption *connOptions,
static void defaultNoticeProcessor(void *arg, const char *message); static void defaultNoticeProcessor(void *arg, const char *message);
static int parseServiceInfo(PQconninfoOption *options, static int parseServiceInfo(PQconninfoOption *options,
PQExpBuffer errorMessage); PQExpBuffer errorMessage);
#ifdef USE_SSL
static const char *SSLerrmessage(void);
#endif
/* /*
@ -961,7 +964,7 @@ connectDBStart(PGconn *conn)
{ {
printfPQExpBuffer(&conn->errorMessage, printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not create SSL context: %s\n"), libpq_gettext("could not create SSL context: %s\n"),
ERR_reason_error_string(ERR_get_error())); SSLerrmessage());
goto connect_errReturn; goto connect_errReturn;
} }
} }
@ -971,7 +974,7 @@ connectDBStart(PGconn *conn)
{ {
printfPQExpBuffer(&conn->errorMessage, printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not establish SSL connection: %s\n"), libpq_gettext("could not establish SSL connection: %s\n"),
ERR_reason_error_string(ERR_get_error())); SSLerrmessage());
goto connect_errReturn; goto connect_errReturn;
} }
/* SSL connection finished. Continue to send startup packet */ /* SSL connection finished. Continue to send startup packet */
@ -981,7 +984,12 @@ connectDBStart(PGconn *conn)
/* Received error - probably protocol mismatch */ /* Received error - probably protocol mismatch */
if (conn->Pfdebug) if (conn->Pfdebug)
fprintf(conn->Pfdebug, "Postmaster reports error, attempting fallback to pre-7.0.\n"); fprintf(conn->Pfdebug, "Postmaster reports error, attempting fallback to pre-7.0.\n");
#ifdef WIN32
closesocket(conn->sock);
#else
close(conn->sock); close(conn->sock);
#endif
conn->sock = -1;
conn->allow_ssl_try = FALSE; conn->allow_ssl_try = FALSE;
return connectDBStart(conn); return connectDBStart(conn);
} }
@ -2610,6 +2618,36 @@ PQconninfoFree(PQconninfoOption *connOptions)
free(connOptions); free(connOptions);
} }
#ifdef USE_SSL
/*
* Obtain reason string for last SSL error
*
* Some caution is needed here since ERR_reason_error_string will
* return NULL if it doesn't recognize the error code. We don't
* want to return NULL ever.
*/
static const char *
SSLerrmessage(void)
{
unsigned long errcode;
const char *errreason;
static char errbuf[32];
errcode = ERR_get_error();
if (errcode == 0)
return "No SSL error reported";
errreason = ERR_reason_error_string(errcode);
if (errreason != NULL)
return errreason;
snprintf(errbuf, sizeof(errbuf), "SSL error code %lu", errcode);
return errbuf;
}
#endif /* USE_SSL */
/* =========== accessor functions for PGconn ========= */ /* =========== accessor functions for PGconn ========= */
char * char *
PQdb(const PGconn *conn) PQdb(const PGconn *conn)