aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/libpq/fe-secure.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2011-07-24 16:29:07 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2011-07-24 16:29:07 -0400
commitfee476da952a1f02f7ccf6e233fb4824c2bf6af4 (patch)
tree1b19ff0e0542d2ffc97afdc8561bf0c7efd24ca1 /src/interfaces/libpq/fe-secure.c
parentd0c23026b2499ba9d6797359241ade076a5a677d (diff)
downloadpostgresql-fee476da952a1f02f7ccf6e233fb4824c2bf6af4.tar.gz
postgresql-fee476da952a1f02f7ccf6e233fb4824c2bf6af4.zip
Improve libpq's error reporting for SSL failures.
In many cases, pqsecure_read/pqsecure_write set up useful error messages, which were then overwritten with useless ones by their callers. Fix this by defining the responsibility to set an error message to be entirely that of the lower-level function when using SSL. Back-patch to 8.3; the code is too different in 8.2 to be worth the trouble.
Diffstat (limited to 'src/interfaces/libpq/fe-secure.c')
-rw-r--r--src/interfaces/libpq/fe-secure.c61
1 files changed, 50 insertions, 11 deletions
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index 9319f972c81..6e0fbd3a390 100644
--- a/src/interfaces/libpq/fe-secure.c
+++ b/src/interfaces/libpq/fe-secure.c
@@ -302,6 +302,11 @@ pqsecure_close(PGconn *conn)
/*
* Read data from a secure connection.
+ *
+ * If SSL is in use, this function is responsible for putting a suitable
+ * message into conn->errorMessage upon error; but the caller does that
+ * when not using SSL. In either case, caller uses the returned errno
+ * to decide whether to continue/retry after error.
*/
ssize_t
pqsecure_read(PGconn *conn, void *ptr, size_t len)
@@ -325,6 +330,13 @@ rloop:
switch (err)
{
case SSL_ERROR_NONE:
+ if (n < 0)
+ {
+ printfPQExpBuffer(&conn->errorMessage,
+ libpq_gettext("SSL_read failed but did not provide error information\n"));
+ /* assume the connection is broken */
+ SOCK_ERRNO_SET(ECONNRESET);
+ }
break;
case SSL_ERROR_WANT_READ:
n = 0;
@@ -342,7 +354,7 @@ rloop:
{
char sebuf[256];
- if (n == -1)
+ if (n < 0)
{
REMEMBER_EPIPE(spinfo, SOCK_ERRNO == EPIPE);
printfPQExpBuffer(&conn->errorMessage,
@@ -353,7 +365,7 @@ rloop:
{
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("SSL SYSCALL error: EOF detected\n"));
-
+ /* assume the connection is broken */
SOCK_ERRNO_SET(ECONNRESET);
n = -1;
}
@@ -361,14 +373,19 @@ rloop:
}
case SSL_ERROR_SSL:
{
- char *err = SSLerrmessage();
+ char *errm = SSLerrmessage();
printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("SSL error: %s\n"), err);
- SSLerrfree(err);
+ libpq_gettext("SSL error: %s\n"), errm);
+ SSLerrfree(errm);
+ /* assume the connection is broken */
+ SOCK_ERRNO_SET(ECONNRESET);
+ n = -1;
+ break;
}
- /* fall through */
case SSL_ERROR_ZERO_RETURN:
+ printfPQExpBuffer(&conn->errorMessage,
+ libpq_gettext("SSL connection has been closed unexpectedly\n"));
SOCK_ERRNO_SET(ECONNRESET);
n = -1;
break;
@@ -376,6 +393,8 @@ rloop:
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("unrecognized SSL error code: %d\n"),
err);
+ /* assume the connection is broken */
+ SOCK_ERRNO_SET(ECONNRESET);
n = -1;
break;
}
@@ -391,6 +410,11 @@ rloop:
/*
* Write data to a secure connection.
+ *
+ * If SSL is in use, this function is responsible for putting a suitable
+ * message into conn->errorMessage upon error; but the caller does that
+ * when not using SSL. In either case, caller uses the returned errno
+ * to decide whether to continue/retry after error.
*/
ssize_t
pqsecure_write(PGconn *conn, const void *ptr, size_t len)
@@ -412,6 +436,13 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len)
switch (err)
{
case SSL_ERROR_NONE:
+ if (n < 0)
+ {
+ printfPQExpBuffer(&conn->errorMessage,
+ libpq_gettext("SSL_write failed but did not provide error information\n"));
+ /* assume the connection is broken */
+ SOCK_ERRNO_SET(ECONNRESET);
+ }
break;
case SSL_ERROR_WANT_READ:
@@ -429,7 +460,7 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len)
{
char sebuf[256];
- if (n == -1)
+ if (n < 0)
{
REMEMBER_EPIPE(spinfo, SOCK_ERRNO == EPIPE);
printfPQExpBuffer(&conn->errorMessage,
@@ -440,6 +471,7 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len)
{
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("SSL SYSCALL error: EOF detected\n"));
+ /* assume the connection is broken */
SOCK_ERRNO_SET(ECONNRESET);
n = -1;
}
@@ -447,14 +479,19 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len)
}
case SSL_ERROR_SSL:
{
- char *err = SSLerrmessage();
+ char *errm = SSLerrmessage();
printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("SSL error: %s\n"), err);
- SSLerrfree(err);
+ libpq_gettext("SSL error: %s\n"), errm);
+ SSLerrfree(errm);
+ /* assume the connection is broken */
+ SOCK_ERRNO_SET(ECONNRESET);
+ n = -1;
+ break;
}
- /* fall through */
case SSL_ERROR_ZERO_RETURN:
+ printfPQExpBuffer(&conn->errorMessage,
+ libpq_gettext("SSL connection has been closed unexpectedly\n"));
SOCK_ERRNO_SET(ECONNRESET);
n = -1;
break;
@@ -462,6 +499,8 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len)
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("unrecognized SSL error code: %d\n"),
err);
+ /* assume the connection is broken */
+ SOCK_ERRNO_SET(ECONNRESET);
n = -1;
break;
}