mirror of
https://github.com/postgres/postgres.git
synced 2025-11-19 13:42:17 +03:00
Lots of patches coming in from me today :-)
When drawing up a very simple "text-drawing" of how the negotiation is done, I realised I had done this last part (fallback) in a very stupid way. Patch #4 fixes this, and does it in a much better way. Included is also the simple text-drawing of how the negotiation is done. //Magnus
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.102 1999/08/31 01:37:36 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.103 1999/09/27 03:13:16 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -40,6 +40,10 @@
|
||||
#include "mb/pg_wchar.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_SSL
|
||||
static SSL_CTX *SSL_context = NULL;
|
||||
#endif
|
||||
|
||||
static ConnStatusType connectDB(PGconn *conn);
|
||||
static PGconn *makeEmptyPGconn(void);
|
||||
static void freePGconn(PGconn *conn);
|
||||
@@ -508,6 +512,12 @@ connectDB(PGconn *conn)
|
||||
family;
|
||||
char beresp;
|
||||
int on = 1;
|
||||
#ifdef USE_SSL
|
||||
StartupPacket np; /* Used to negotiate SSL connection */
|
||||
char SSLok;
|
||||
static int allow_ssl_try = 1; /* Allowed to do SSL negotiation */
|
||||
int tried_ssl = 0; /* Set if SSL negotiation was tried */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* parse dbName to get all additional info in it, if any
|
||||
@@ -591,6 +601,70 @@ connectDB(PGconn *conn)
|
||||
goto connect_errReturn;
|
||||
}
|
||||
|
||||
/* This needs to be done before we set into nonblocking, since SSL negotiation
|
||||
* does not like that mode */
|
||||
|
||||
#ifdef USE_SSL
|
||||
/* Attempt to negotiate SSL usage */
|
||||
if (allow_ssl_try) {
|
||||
tried_ssl = 1;
|
||||
memset((char *)&np, 0, sizeof(np));
|
||||
np.protoVersion = htonl(NEGOTIATE_SSL_CODE);
|
||||
if (pqPacketSend(conn, (char *) &np, sizeof(StartupPacket)) != STATUS_OK)
|
||||
{
|
||||
sprintf(conn->errorMessage,
|
||||
"connectDB() -- couldn't send SSL negotiation packet: errno=%d\n%s\n",
|
||||
errno, strerror(errno));
|
||||
goto connect_errReturn;
|
||||
}
|
||||
/* Now receive the backends response */
|
||||
if (recv(conn->sock, &SSLok, 1, 0) != 1) {
|
||||
sprintf(conn->errorMessage, "PQconnectDB() -- couldn't read backend response: errno=%d\n%s\n",
|
||||
errno, strerror(errno));
|
||||
goto connect_errReturn;
|
||||
}
|
||||
if (SSLok == 'S') {
|
||||
if (!SSL_context)
|
||||
{
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
SSL_context = SSL_CTX_new(SSLv23_method());
|
||||
if (!SSL_context) {
|
||||
sprintf(conn->errorMessage,
|
||||
"connectDB() -- couldn't create SSL context: %s\n",
|
||||
ERR_reason_error_string(ERR_get_error()));
|
||||
goto connect_errReturn;
|
||||
}
|
||||
}
|
||||
if (!(conn->ssl = SSL_new(SSL_context)) ||
|
||||
!SSL_set_fd(conn->ssl, conn->sock) ||
|
||||
SSL_connect(conn->ssl) <= 0)
|
||||
{
|
||||
sprintf(conn->errorMessage,
|
||||
"connectDB() -- couldn't establish SSL connection: %s\n",
|
||||
ERR_reason_error_string(ERR_get_error()));
|
||||
goto connect_errReturn;
|
||||
}
|
||||
/* SSL connection finished. Continue to send startup packet */
|
||||
}
|
||||
else if (SSLok == 'E') {
|
||||
/* Received error - probably protocol mismatch */
|
||||
if (conn->Pfdebug)
|
||||
fprintf(conn->Pfdebug, "Backend reports error, attempting fallback to pre-6.6.\n");
|
||||
close(conn->sock);
|
||||
allow_ssl_try = 0;
|
||||
return connectDB(conn);
|
||||
}
|
||||
else if (SSLok != 'N') {
|
||||
strcpy(conn->errorMessage,
|
||||
"Received invalid negotiation response.\n");
|
||||
goto connect_errReturn;
|
||||
}
|
||||
}
|
||||
else
|
||||
allow_ssl_try = 1; /* We'll allow an attempt to use SSL next time */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set the right options. We need nonblocking I/O, and we don't want
|
||||
* delay of outgoing data.
|
||||
@@ -896,6 +970,10 @@ freePGconn(PGconn *conn)
|
||||
if (!conn)
|
||||
return;
|
||||
pqClearAsyncResult(conn); /* deallocate result and curTuple */
|
||||
#ifdef USE_SSL
|
||||
if (conn->ssl)
|
||||
SSL_free(conn->ssl);
|
||||
#endif
|
||||
if (conn->sock >= 0)
|
||||
#ifdef WIN32
|
||||
closesocket(conn->sock);
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.30 1999/09/13 03:00:19 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.31 1999/09/27 03:13:16 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -351,7 +351,13 @@ pqReadData(PGconn *conn)
|
||||
|
||||
/* OK, try to read some data */
|
||||
tryAgain:
|
||||
nread = recv(conn->sock, conn->inBuffer + conn->inEnd,
|
||||
#ifdef USE_SSL
|
||||
if (conn->ssl)
|
||||
nread = SSL_read(conn->ssl, conn->inBuffer + conn->inEnd,
|
||||
conn->inBufSize - conn->inEnd);
|
||||
else
|
||||
#endif
|
||||
nread = recv(conn->sock, conn->inBuffer + conn->inEnd,
|
||||
conn->inBufSize - conn->inEnd, 0);
|
||||
if (nread < 0)
|
||||
{
|
||||
@@ -420,7 +426,13 @@ tryAgain:
|
||||
* arrived.
|
||||
*/
|
||||
tryAgain2:
|
||||
nread = recv(conn->sock, conn->inBuffer + conn->inEnd,
|
||||
#ifdef USE_SSL
|
||||
if (conn->ssl)
|
||||
nread = SSL_read(conn->ssl, conn->inBuffer + conn->inEnd,
|
||||
conn->inBufSize - conn->inEnd);
|
||||
else
|
||||
#endif
|
||||
nread = recv(conn->sock, conn->inBuffer + conn->inEnd,
|
||||
conn->inBufSize - conn->inEnd, 0);
|
||||
if (nread < 0)
|
||||
{
|
||||
@@ -494,7 +506,13 @@ pqFlush(PGconn *conn)
|
||||
pqsigfunc oldsighandler = pqsignal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
|
||||
int sent = send(conn->sock, ptr, len, 0);
|
||||
int sent;
|
||||
#ifdef USE_SSL
|
||||
if (conn->ssl)
|
||||
sent = SSL_write(conn->ssl, ptr, len);
|
||||
else
|
||||
#endif
|
||||
sent = send(conn->sock, ptr, len, 0);
|
||||
|
||||
#ifndef WIN32
|
||||
pqsignal(SIGPIPE, oldsighandler);
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: libpq-int.h,v 1.11 1999/08/31 01:37:37 tgl Exp $
|
||||
* $Id: libpq-int.h,v 1.12 1999/09/27 03:13:16 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -28,6 +28,11 @@
|
||||
#include "pqexpbuffer.h"
|
||||
|
||||
|
||||
#ifdef USE_SSL
|
||||
#include "openssl/ssl.h"
|
||||
#include "openssl/err.h"
|
||||
#endif
|
||||
|
||||
/* libpq supports this version of the frontend/backend protocol.
|
||||
*
|
||||
* NB: we used to use PG_PROTOCOL_LATEST from the backend pqcomm.h file,
|
||||
@@ -215,6 +220,10 @@ struct pg_conn
|
||||
PGresult *result; /* result being constructed */
|
||||
PGresAttValue *curTuple; /* tuple currently being read */
|
||||
|
||||
#ifdef USE_SSL
|
||||
SSL *ssl;
|
||||
#endif
|
||||
|
||||
/* Buffer for current error message */
|
||||
PQExpBufferData errorMessage; /* expansible string */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user