1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Improve error reporting for SSL connection failures. Remove redundant

free operations in client_cert_cb --- openssl will also attempt to free
these structures, resulting in core dumps.
This commit is contained in:
Tom Lane
2004-11-20 00:18:18 +00:00
parent 88969ea11a
commit 7506677b62
2 changed files with 69 additions and 50 deletions

View File

@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.53 2004/11/17 04:05:42 neilc Exp $
* $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.54 2004/11/20 00:18:13 tgl Exp $
*
* Since the server static private key ($DataDir/server.key)
* will normally be stored unencrypted so that the database
@ -727,37 +727,6 @@ initialize_SSL(void)
return 0;
}
#ifdef WIN32
/*
* Win32 socket code uses nonblocking sockets. We ned to deal with that
* by waiting on the socket if the SSL accept operation didn't complete
* right away.
*/
static int pgwin32_SSL_accept(SSL *ssl)
{
int r;
while (1)
{
int rc;
int waitfor;
r = SSL_accept(ssl);
if (r == 1)
return 1;
rc = SSL_get_error(ssl, r);
if (rc != SSL_ERROR_WANT_READ && rc != SSL_ERROR_WANT_WRITE)
return r;
waitfor = (rc == SSL_ERROR_WANT_READ)?FD_READ|FD_CLOSE|FD_ACCEPT:FD_WRITE|FD_CLOSE;
if (pgwin32_waitforsinglesocket(SSL_get_fd(ssl), waitfor) == 0)
return -1;
}
}
#define SSL_accept(ssl) pgwin32_SSL_accept(ssl)
#endif
/*
* Destroy global SSL context.
*/
@ -777,7 +746,9 @@ destroy_SSL(void)
static int
open_server_SSL(Port *port)
{
int r;
int r;
int err;
Assert(!port->ssl);
Assert(!port->peer);
@ -799,12 +770,50 @@ open_server_SSL(Port *port)
close_SSL(port);
return -1;
}
if ((r=SSL_accept(port->ssl)) <= 0)
aloop:
r = SSL_accept(port->ssl);
if (r <= 0)
{
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("could not accept SSL connection: %i",
SSL_get_error(port->ssl,r))));
err = SSL_get_error(port->ssl, r);
switch (err)
{
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
#ifdef WIN32
pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
(err==SSL_ERROR_WANT_READ) ?
FD_READ|FD_CLOSE|FD_ACCEPT : FD_WRITE|FD_CLOSE);
#endif
goto aloop;
case SSL_ERROR_SYSCALL:
if (r < 0)
ereport(COMMERROR,
(errcode_for_socket_access(),
errmsg("could not accept SSL connection: %m")));
else
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("could not accept SSL connection: EOF detected")));
break;
case SSL_ERROR_SSL:
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("could not accept SSL connection: %s",
SSLerrmessage())));
break;
case SSL_ERROR_ZERO_RETURN:
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("could not accept SSL connection: EOF detected")));
break;
default:
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("unrecognized SSL error code: %d",
err)));
break;
}
close_SSL(port);
return -1;
}