diff options
Diffstat (limited to 'src/backend/libpq/be-secure.c')
-rw-r--r-- | src/backend/libpq/be-secure.c | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c index 5612c29f8b2..1663f36b6b8 100644 --- a/src/backend/libpq/be-secure.c +++ b/src/backend/libpq/be-secure.c @@ -109,18 +109,51 @@ secure_loaded_verify_locations(void) int secure_open_server(Port *port) { +#ifdef USE_SSL int r = 0; + ssize_t len; + + /* push unencrypted buffered data back through SSL setup */ + len = pq_buffer_remaining_data(); + if (len > 0) + { + char *buf = palloc(len); + + pq_startmsgread(); + if (pq_getbytes(buf, len) == EOF) + return STATUS_ERROR; /* shouldn't be possible */ + pq_endmsgread(); + port->raw_buf = buf; + port->raw_buf_remaining = len; + port->raw_buf_consumed = 0; + } + Assert(pq_buffer_remaining_data() == 0); -#ifdef USE_SSL r = be_tls_open_server(port); + if (port->raw_buf_remaining > 0) + { + /* + * This shouldn't be possible -- it would mean the client sent + * encrypted data before we established a session key... + */ + elog(LOG, "buffered unencrypted data remains after negotiating SSL connection"); + return STATUS_ERROR; + } + if (port->raw_buf != NULL) + { + pfree(port->raw_buf); + port->raw_buf = NULL; + } + ereport(DEBUG2, (errmsg_internal("SSL connection from DN:\"%s\" CN:\"%s\"", port->peer_dn ? port->peer_dn : "(anonymous)", port->peer_cn ? port->peer_cn : "(anonymous)"))); -#endif - return r; +#else + return 0; +#endif } /* @@ -232,6 +265,19 @@ secure_raw_read(Port *port, void *ptr, size_t len) { ssize_t n; + /* Read from the "unread" buffered data first. c.f. libpq-be.h */ + if (port->raw_buf_remaining > 0) + { + /* consume up to len bytes from the raw_buf */ + if (len > port->raw_buf_remaining) + len = port->raw_buf_remaining; + Assert(port->raw_buf); + memcpy(ptr, port->raw_buf + port->raw_buf_consumed, len); + port->raw_buf_consumed += len; + port->raw_buf_remaining -= len; + return len; + } + /* * Try to read from the socket without blocking. If it succeeds we're * done, otherwise we'll wait for the socket using the latch mechanism. |