mirror of
https://github.com/postgres/postgres.git
synced 2025-09-11 00:12:06 +03:00
Fix error recovery for SSL_read/SSL_write calls.
This commit is contained in:
@@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/libpq/be-secure.c,v 1.15.2.10 2003/03/30 21:36:44 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/libpq/be-secure.c,v 1.15.2.11 2003/04/10 23:03:13 tgl Exp $
|
||||||
*
|
*
|
||||||
* Since the server static private key ($DataDir/server.key)
|
* Since the server static private key ($DataDir/server.key)
|
||||||
* will normally be stored unencrypted so that the database
|
* will normally be stored unencrypted so that the database
|
||||||
@@ -273,6 +273,7 @@ secure_read(Port *port, void *ptr, size_t len)
|
|||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
if (port->ssl)
|
if (port->ssl)
|
||||||
{
|
{
|
||||||
|
rloop:
|
||||||
n = SSL_read(port->ssl, ptr, len);
|
n = SSL_read(port->ssl, ptr, len);
|
||||||
switch (SSL_get_error(port->ssl, n))
|
switch (SSL_get_error(port->ssl, n))
|
||||||
{
|
{
|
||||||
@@ -280,14 +281,13 @@ secure_read(Port *port, void *ptr, size_t len)
|
|||||||
port->count += n;
|
port->count += n;
|
||||||
break;
|
break;
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
n = secure_read(port, ptr, len);
|
|
||||||
break;
|
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
n = secure_write(port, ptr, len);
|
goto rloop;
|
||||||
break;
|
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
if (n == -1)
|
if (n == -1)
|
||||||
elog(COMMERROR, "SSL SYSCALL error: %s", strerror(errno));
|
elog(COMMERROR, "SSL SYSCALL error: %m");
|
||||||
|
else
|
||||||
|
elog(COMMERROR, "SSL SYSCALL error: EOF detected");
|
||||||
break;
|
break;
|
||||||
case SSL_ERROR_SSL:
|
case SSL_ERROR_SSL:
|
||||||
elog(COMMERROR, "SSL error: %s", SSLerrmessage());
|
elog(COMMERROR, "SSL error: %s", SSLerrmessage());
|
||||||
@@ -297,6 +297,9 @@ secure_read(Port *port, void *ptr, size_t len)
|
|||||||
errno = ECONNRESET;
|
errno = ECONNRESET;
|
||||||
n = -1;
|
n = -1;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
elog(COMMERROR, "Unknown SSL error code");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -323,18 +326,19 @@ secure_write(Port *port, void *ptr, size_t len)
|
|||||||
{
|
{
|
||||||
if (port->count > RENEGOTIATION_LIMIT)
|
if (port->count > RENEGOTIATION_LIMIT)
|
||||||
{
|
{
|
||||||
SSL_set_session_id_context(port->ssl, (void *)&SSL_context, sizeof(SSL_context));
|
SSL_set_session_id_context(port->ssl, (void *) &SSL_context,
|
||||||
|
sizeof(SSL_context));
|
||||||
if (SSL_renegotiate(port->ssl) <= 0)
|
if (SSL_renegotiate(port->ssl) <= 0)
|
||||||
elog(COMMERROR, "SSL renegotiation failure");
|
elog(COMMERROR, "SSL renegotiation failure");
|
||||||
if (SSL_do_handshake(port->ssl) <= 0)
|
if (SSL_do_handshake(port->ssl) <= 0)
|
||||||
elog(COMMERROR, "SSL renegotiation failure");
|
elog(COMMERROR, "SSL renegotiation failure");
|
||||||
port->ssl->state=SSL_ST_ACCEPT;
|
port->ssl->state = SSL_ST_ACCEPT;
|
||||||
if (SSL_do_handshake(port->ssl) <= 0)
|
if (SSL_do_handshake(port->ssl) <= 0)
|
||||||
elog(COMMERROR, "SSL renegotiation failure");
|
elog(COMMERROR, "SSL renegotiation failure");
|
||||||
port->count = 0;
|
port->count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wloop:
|
||||||
n = SSL_write(port->ssl, ptr, len);
|
n = SSL_write(port->ssl, ptr, len);
|
||||||
switch (SSL_get_error(port->ssl, n))
|
switch (SSL_get_error(port->ssl, n))
|
||||||
{
|
{
|
||||||
@@ -342,14 +346,13 @@ secure_write(Port *port, void *ptr, size_t len)
|
|||||||
port->count += n;
|
port->count += n;
|
||||||
break;
|
break;
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
n = secure_read(port, ptr, len);
|
|
||||||
break;
|
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
n = secure_write(port, ptr, len);
|
goto wloop;
|
||||||
break;
|
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
if (n == -1)
|
if (n == -1)
|
||||||
elog(COMMERROR, "SSL SYSCALL error: %s", strerror(errno));
|
elog(COMMERROR, "SSL SYSCALL error: %m");
|
||||||
|
else
|
||||||
|
elog(COMMERROR, "SSL SYSCALL error: EOF detected");
|
||||||
break;
|
break;
|
||||||
case SSL_ERROR_SSL:
|
case SSL_ERROR_SSL:
|
||||||
elog(COMMERROR, "SSL error: %s", SSLerrmessage());
|
elog(COMMERROR, "SSL error: %s", SSLerrmessage());
|
||||||
@@ -359,6 +362,9 @@ secure_write(Port *port, void *ptr, size_t len)
|
|||||||
errno = ECONNRESET;
|
errno = ECONNRESET;
|
||||||
n = -1;
|
n = -1;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
elog(COMMERROR, "Unknown SSL error code");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-secure.c,v 1.15.2.4 2003/01/08 23:18:35 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-secure.c,v 1.15.2.5 2003/04/10 23:03:13 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* The client *requires* a valid server certificate. Since
|
* The client *requires* a valid server certificate. Since
|
||||||
@@ -262,18 +262,24 @@ pqsecure_read(PGconn *conn, void *ptr, size_t len)
|
|||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
if (conn->ssl)
|
if (conn->ssl)
|
||||||
{
|
{
|
||||||
|
rloop:
|
||||||
n = SSL_read(conn->ssl, ptr, len);
|
n = SSL_read(conn->ssl, ptr, len);
|
||||||
switch (SSL_get_error(conn->ssl, n))
|
switch (SSL_get_error(conn->ssl, n))
|
||||||
{
|
{
|
||||||
case SSL_ERROR_NONE:
|
case SSL_ERROR_NONE:
|
||||||
break;
|
break;
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
n = pqsecure_read(conn, ptr, len);
|
case SSL_ERROR_WANT_WRITE:
|
||||||
break;
|
/* XXX to support nonblock I/O, we should return 0 here */
|
||||||
|
goto rloop;
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
|
if (n == -1)
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("SSL SYSCALL error: %s\n"),
|
libpq_gettext("SSL SYSCALL error: %s\n"),
|
||||||
SOCK_STRERROR(SOCK_ERRNO));
|
SOCK_STRERROR(SOCK_ERRNO));
|
||||||
|
else
|
||||||
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
|
libpq_gettext("SSL SYSCALL error: EOF detected\n"));
|
||||||
break;
|
break;
|
||||||
case SSL_ERROR_SSL:
|
case SSL_ERROR_SSL:
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
@@ -284,6 +290,10 @@ pqsecure_read(PGconn *conn, void *ptr, size_t len)
|
|||||||
SOCK_ERRNO = ECONNRESET;
|
SOCK_ERRNO = ECONNRESET;
|
||||||
n = -1;
|
n = -1;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
|
libpq_gettext("Unknown SSL error code\n"));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -308,18 +318,24 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len)
|
|||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
if (conn->ssl)
|
if (conn->ssl)
|
||||||
{
|
{
|
||||||
|
wloop:
|
||||||
n = SSL_write(conn->ssl, ptr, len);
|
n = SSL_write(conn->ssl, ptr, len);
|
||||||
switch (SSL_get_error(conn->ssl, n))
|
switch (SSL_get_error(conn->ssl, n))
|
||||||
{
|
{
|
||||||
case SSL_ERROR_NONE:
|
case SSL_ERROR_NONE:
|
||||||
break;
|
break;
|
||||||
|
case SSL_ERROR_WANT_READ:
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
n = pqsecure_write(conn, ptr, len);
|
/* XXX to support nonblock I/O, we should return 0 here */
|
||||||
break;
|
goto wloop;
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
|
if (n == -1)
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("SSL SYSCALL error: %s\n"),
|
libpq_gettext("SSL SYSCALL error: %s\n"),
|
||||||
SOCK_STRERROR(SOCK_ERRNO));
|
SOCK_STRERROR(SOCK_ERRNO));
|
||||||
|
else
|
||||||
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
|
libpq_gettext("SSL SYSCALL error: EOF detected\n"));
|
||||||
break;
|
break;
|
||||||
case SSL_ERROR_SSL:
|
case SSL_ERROR_SSL:
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
@@ -330,6 +346,10 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len)
|
|||||||
SOCK_ERRNO = ECONNRESET;
|
SOCK_ERRNO = ECONNRESET;
|
||||||
n = -1;
|
n = -1;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
|
libpq_gettext("Unknown SSL error code\n"));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user