summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Momjian2000-08-30 14:54:24 +0000
committerBruce Momjian2000-08-30 14:54:24 +0000
commit7bc654bb16dc08153060c8ddc1e0f3786026a483 (patch)
tree5b9ae9cc8cb21a2ceb3e0db714a404ee96cfc4b1
parent3498ea830828feb8c5f6cf155a40df012cbc6d64 (diff)
SSL patch from Magnus
-rw-r--r--src/backend/postmaster/postmaster.c52
-rw-r--r--src/bin/psql/startup.c34
-rw-r--r--src/interfaces/libpq/fe-connect.c135
-rw-r--r--src/interfaces/libpq/libpq-fe.h10
-rw-r--r--src/interfaces/libpq/libpq-int.h3
5 files changed, 146 insertions, 88 deletions
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 986e0e038cb..223b5bbe24c 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.163 2000/08/29 16:40:19 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.164 2000/08/30 14:54:22 momjian Exp $
*
* NOTES
*
@@ -195,10 +195,7 @@ static int SendStop = false;
bool NetServer = false; /* listen on TCP/IP */
#ifdef USE_SSL
-static bool SecureNetServer = false; /* if not zero, postmaster listens
- * for only SSL non-local
- * connections */
-
+static bool DisableSSL = false; /* Completely disable SSL, even if compiled in */
#endif
static pid_t StartupPID = 0,
@@ -455,7 +452,7 @@ PostmasterMain(int argc, char *argv[])
break;
#ifdef USE_SSL
case 'l':
- SecureNetServer = true;
+ DisableSSL = true;
break;
#endif
case 'm':
@@ -566,13 +563,14 @@ PostmasterMain(int argc, char *argv[])
}
#ifdef USE_SSL
- if (!NetServer && SecureNetServer)
+ if (!NetServer && !DisableSSL)
{
- fprintf(stderr, "%s: For SSL, you must enable TCP/IP connections.\n",
+ fprintf(stderr, "%s: For SSL, you must enable TCP/IP connections. Use -l to disable SSL\n",
progname);
exit(1);
}
- InitSSL();
+ if (!DisableSSL)
+ InitSSL();
#endif
if (NetServer)
@@ -754,7 +752,7 @@ usage(const char *progname)
printf(" -F turn fsync off\n");
printf(" -i listen on TCP/IP sockets\n");
#ifdef USE_SSL
- printf(" -l listen only on SSL connections (EXPERIMENTAL)\n");
+ printf(" -l disable SSL\n");
#endif
printf(" -N <number> maximum number of allowed connections (1..%d, default %d)\n",
MAXBACKENDS, DEF_MAXBACKENDS);
@@ -1062,7 +1060,11 @@ readStartupPacket(void *arg, PacketLen len, void *pkt)
char SSLok;
#ifdef USE_SSL
- SSLok = 'S'; /* Support for SSL */
+ if (DisableSSL || port->laddr.sa.sa_family != AF_INET)
+ /* No SSL when disabled or on Unix sockets */
+ SSLok = 'N';
+ else
+ SSLok = 'S'; /* Support for SSL */
#else
SSLok = 'N'; /* No support for SSL */
#endif
@@ -1073,13 +1075,15 @@ readStartupPacket(void *arg, PacketLen len, void *pkt)
}
#ifdef USE_SSL
- if (!(port->ssl = SSL_new(SSL_context)) ||
- !SSL_set_fd(port->ssl, port->sock) ||
- SSL_accept(port->ssl) <= 0)
- {
- fprintf(stderr, "Failed to initialize SSL connection: %s, errno: %d (%s)\n",
- ERR_reason_error_string(ERR_get_error()), errno, strerror(errno));
- return STATUS_ERROR;
+ if (SSLok == 'S') {
+ if (!(port->ssl = SSL_new(SSL_context)) ||
+ !SSL_set_fd(port->ssl, port->sock) ||
+ SSL_accept(port->ssl) <= 0)
+ {
+ fprintf(stderr, "Failed to initialize SSL connection: %s, errno: %d (%s)\n",
+ ERR_reason_error_string(ERR_get_error()), errno, strerror(errno));
+ return STATUS_ERROR;
+ }
}
#endif
/* ready for the normal startup packet */
@@ -1091,18 +1095,6 @@ readStartupPacket(void *arg, PacketLen len, void *pkt)
/* Could add additional special packet types here */
-#ifdef USE_SSL
-
- /*
- * Any SSL negotiation must have taken place here, so drop the
- * connection ASAP if we require SSL
- */
- if (SecureNetServer && !port->ssl)
- {
- PacketSendError(&port->pktInfo, "Backend requires secure connection.");
- return STATUS_OK;
- }
-#endif
/* Check we can handle the protocol the frontend is using. */
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 88ef5865afd..0f36e30ef8c 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
- * $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.34 2000/07/02 15:21:17 petere Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.35 2000/08/30 14:54:23 momjian Exp $
*/
#include "postgres.h"
@@ -81,6 +81,10 @@ static void
static void
showVersion(void);
+#ifdef USE_SSL
+static void
+ printSSLInfo(void);
+#endif
/*
@@ -263,7 +267,9 @@ main(int argc, char *argv[])
" \\g or terminate with semicolon to execute query\n"
" \\q to quit\n\n", pset.progname);
}
-
+#ifdef USE_SSL
+ printSSLInfo();
+#endif
SetVariable(pset.vars, "PROMPT1", DEFAULT_PROMPT1);
SetVariable(pset.vars, "PROMPT2", DEFAULT_PROMPT2);
SetVariable(pset.vars, "PROMPT3", DEFAULT_PROMPT3);
@@ -639,3 +645,27 @@ showVersion(void)
puts("Read the file COPYRIGHT or use the command \\copyright to see the");
puts("usage and distribution terms.");
}
+
+
+
+/*
+ * printSSLInfo
+ *
+ * Prints information about the current SSL connection, if SSL is in use
+ */
+#ifdef USE_SSL
+static void
+printSSLInfo(void)
+{
+ int sslbits = -1;
+ SSL *ssl;
+
+ ssl = PQgetssl(pset.db);
+ if (!ssl)
+ return; /* no SSL */
+
+ SSL_get_cipher_bits(ssl, &sslbits);
+ printf("SSL enabled connection. Chiper: %s, bits: %i\n\n",
+ SSL_get_cipher(ssl),sslbits);
+}
+#endif
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 1db218e12be..7349be66459 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.132 2000/08/20 10:55:35 petere Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.133 2000/08/30 14:54:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -63,7 +63,6 @@ inet_aton(const char *cp, struct in_addr * inp)
#ifdef USE_SSL
static SSL_CTX *SSL_context = NULL;
-
#endif
#define NOTIFYLIST_INITIAL_SIZE 10
@@ -131,6 +130,11 @@ static const PQconninfoOption PQconninfoOptions[] = {
{"options", "PGOPTIONS", DefaultOption, NULL,
"Backend-Debug-Options", "D", 40},
+#ifdef USE_SSL
+ {"requiressl", "PGREQUIRESSL", "0", NULL,
+ "Require-SSL", "", 1 },
+#endif
+
/* Terminating entry --- MUST BE LAST */
{NULL, NULL, NULL, NULL,
NULL, NULL, 0}
@@ -303,6 +307,10 @@ PQconnectStart(const char *conninfo)
conn->pguser = tmp ? strdup(tmp) : NULL;
tmp = conninfo_getval(connOptions, "password");
conn->pgpass = tmp ? strdup(tmp) : NULL;
+#ifdef USE_SSL
+ tmp = conninfo_getval(connOptions, "requiressl");
+ conn->require_ssl = tmp ? (tmp[0]=='1'?true:false) : false;
+#endif
/* ----------
* Free the option info - all is in conn now
@@ -475,6 +483,14 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
else
conn->dbName = strdup(dbName);
+
+#ifdef USE_SSL
+ if ((tmp = getenv("PGREQUIRESSL")) != NULL)
+ conn->require_ssl = (tmp[0]=='1')?true:false;
+ else
+ conn->require_ssl = 0;
+#endif
+
if (error)
conn->status = CONNECTION_BAD;
else
@@ -781,13 +797,55 @@ connectDBStart(PGconn *conn)
goto connect_errReturn;
#endif
-#ifdef USE_SSL
-
- /*
- * This needs to be done before we set into nonblocking, since SSL
- * negotiation does not like that mode
+ /* ----------
+ * Start / make connection. We are hopefully in non-blocking mode
+ * now, but it is possible that:
+ * 1. Older systems will still block on connect, despite the
+ * non-blocking flag. (Anyone know if this is true?)
+ * 2. We are running under Windows, and aren't even trying
+ * to be non-blocking (see above).
+ * 3. We are using SSL.
+ * Thus, we have make arrangements for all eventualities.
+ * ----------
*/
+ if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
+ {
+#ifndef WIN32
+ if (errno == EINPROGRESS || errno == 0)
+#else
+ if (WSAGetLastError() == WSAEINPROGRESS)
+#endif
+ {
+ /*
+ * This is fine - we're in non-blocking mode, and the
+ * connection is in progress.
+ */
+ conn->status = CONNECTION_STARTED;
+ }
+ else
+ {
+ /* Something's gone wrong */
+ printfPQExpBuffer(&conn->errorMessage,
+ "connectDBStart() -- connect() failed: %s\n"
+ "\tIs the postmaster running%s at '%s'\n"
+ "\tand accepting connections on %s '%s'?\n",
+ strerror(errno),
+ (family == AF_INET) ? " (with -i)" : "",
+ conn->pghost ? conn->pghost : "localhost",
+ (family == AF_INET) ?
+ "TCP/IP port" : "Unix socket",
+ conn->pgport);
+ goto connect_errReturn;
+ }
+ }
+ else
+ {
+ /* We're connected already */
+ conn->status = CONNECTION_MADE;
+ }
+
+#ifdef USE_SSL
/* Attempt to negotiate SSL usage */
if (conn->allow_ssl_try)
{
@@ -837,7 +895,7 @@ connectDBStart(PGconn *conn)
{
/* Received error - probably protocol mismatch */
if (conn->Pfdebug)
- fprintf(conn->Pfdebug, "Postmaster reports error, attempting fallback to pre-6.6.\n");
+ fprintf(conn->Pfdebug, "Postmaster reports error, attempting fallback to pre-7.0.\n");
close(conn->sock);
conn->allow_ssl_try = FALSE;
return connectDBStart(conn);
@@ -849,55 +907,15 @@ connectDBStart(PGconn *conn)
goto connect_errReturn;
}
}
-#endif
-
- /* ----------
- * Start / make connection. We are hopefully in non-blocking mode
- * now, but it is possible that:
- * 1. Older systems will still block on connect, despite the
- * non-blocking flag. (Anyone know if this is true?)
- * 2. We are running under Windows, and aren't even trying
- * to be non-blocking (see above).
- * 3. We are using SSL.
- * Thus, we have make arrangements for all eventualities.
- * ----------
- */
- if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
+ if (conn->require_ssl && !conn->ssl)
{
-#ifndef WIN32
- if (errno == EINPROGRESS || errno == 0)
-#else
- if (WSAGetLastError() == WSAEINPROGRESS)
+ /* Require SSL, but server does not support/want it */
+ printfPQExpBuffer(&conn->errorMessage,
+ "Server does not support SSL when SSL was required.\n");
+ goto connect_errReturn;
+ }
#endif
- {
- /*
- * This is fine - we're in non-blocking mode, and the
- * connection is in progress.
- */
- conn->status = CONNECTION_STARTED;
- }
- else
- {
- /* Something's gone wrong */
- printfPQExpBuffer(&conn->errorMessage,
- "connectDBStart() -- connect() failed: %s\n"
- "\tIs the postmaster running%s at '%s'\n"
- "\tand accepting connections on %s '%s'?\n",
- strerror(errno),
- (family == AF_INET) ? " (with -i)" : "",
- conn->pghost ? conn->pghost : "localhost",
- (family == AF_INET) ?
- "TCP/IP port" : "Unix socket",
- conn->pgport);
- goto connect_errReturn;
- }
- }
- else
- {
- /* We're connected already */
- conn->status = CONNECTION_MADE;
- }
/*
* This makes the connection non-blocking, for all those cases which
@@ -2485,6 +2503,15 @@ PQsetClientEncoding(PGconn *conn, const char *encoding)
#endif
+#ifdef USE_SSL
+SSL *PQgetssl(PGconn *conn)
+{
+ if (!conn)
+ return NULL;
+ return conn->ssl;
+}
+#endif
+
void
PQtrace(PGconn *conn, FILE *debug_port)
{
diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h
index 3c9a311eafa..cfca1984604 100644
--- a/src/interfaces/libpq/libpq-fe.h
+++ b/src/interfaces/libpq/libpq-fe.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: libpq-fe.h,v 1.66 2000/04/14 00:24:52 tgl Exp $
+ * $Id: libpq-fe.h,v 1.67 2000/08/30 14:54:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -25,6 +25,9 @@ extern "C"
* such as Oid.
*/
#include "postgres_ext.h"
+#ifdef USE_SSL
+#include <openssl/ssl.h>
+#endif
/* Application-visible enum types */
@@ -222,6 +225,11 @@ extern "C"
extern int PQbackendPID(const PGconn *conn);
extern int PQclientEncoding(const PGconn *conn);
extern int PQsetClientEncoding(PGconn *conn, const char *encoding);
+#ifdef USE_SSL
+ /* Get the SSL structure associated with a connection */
+ extern SSL *PQgetssl(PGconn *conn);
+#endif
+
/* Enable/disable tracing */
extern void PQtrace(PGconn *conn, FILE *debug_port);
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index b7d16d6d390..c640b6df9f2 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: libpq-int.h,v 1.26 2000/05/27 04:13:05 momjian Exp $
+ * $Id: libpq-int.h,v 1.27 2000/08/30 14:54:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -263,6 +263,7 @@ struct pg_conn
#ifdef USE_SSL
bool allow_ssl_try; /* Allowed to try SSL negotiation */
+ bool require_ssl; /* Require SSL to make connection */
SSL *ssl; /* SSL status, if have SSL connection */
#endif