Skip to content

Commit 7bc654b

Browse files
committed
SSL patch from Magnus
1 parent 3498ea8 commit 7bc654b

File tree

5 files changed

+146
-88
lines changed

5 files changed

+146
-88
lines changed

src/backend/postmaster/postmaster.c

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.163 2000/08/29 16:40:19 tgl Exp $
14+
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.164 2000/08/30 14:54:22 momjian Exp $
1515
*
1616
* NOTES
1717
*
@@ -195,10 +195,7 @@ static int SendStop = false;
195195
bool NetServer = false; /* listen on TCP/IP */
196196

197197
#ifdef USE_SSL
198-
static bool SecureNetServer = false; /* if not zero, postmaster listens
199-
* for only SSL non-local
200-
* connections */
201-
198+
static bool DisableSSL = false; /* Completely disable SSL, even if compiled in */
202199
#endif
203200

204201
static pid_t StartupPID = 0,
@@ -455,7 +452,7 @@ PostmasterMain(int argc, char *argv[])
455452
break;
456453
#ifdef USE_SSL
457454
case 'l':
458-
SecureNetServer = true;
455+
DisableSSL = true;
459456
break;
460457
#endif
461458
case 'm':
@@ -566,13 +563,14 @@ PostmasterMain(int argc, char *argv[])
566563
}
567564

568565
#ifdef USE_SSL
569-
if (!NetServer && SecureNetServer)
566+
if (!NetServer && !DisableSSL)
570567
{
571-
fprintf(stderr, "%s: For SSL, you must enable TCP/IP connections.\n",
568+
fprintf(stderr, "%s: For SSL, you must enable TCP/IP connections. Use -l to disable SSL\n",
572569
progname);
573570
exit(1);
574571
}
575-
InitSSL();
572+
if (!DisableSSL)
573+
InitSSL();
576574
#endif
577575

578576
if (NetServer)
@@ -754,7 +752,7 @@ usage(const char *progname)
754752
printf(" -F turn fsync off\n");
755753
printf(" -i listen on TCP/IP sockets\n");
756754
#ifdef USE_SSL
757-
printf(" -l listen only on SSL connections (EXPERIMENTAL)\n");
755+
printf(" -l disable SSL\n");
758756
#endif
759757
printf(" -N <number> maximum number of allowed connections (1..%d, default %d)\n",
760758
MAXBACKENDS, DEF_MAXBACKENDS);
@@ -1062,7 +1060,11 @@ readStartupPacket(void *arg, PacketLen len, void *pkt)
10621060
char SSLok;
10631061

10641062
#ifdef USE_SSL
1065-
SSLok = 'S'; /* Support for SSL */
1063+
if (DisableSSL || port->laddr.sa.sa_family != AF_INET)
1064+
/* No SSL when disabled or on Unix sockets */
1065+
SSLok = 'N';
1066+
else
1067+
SSLok = 'S'; /* Support for SSL */
10661068
#else
10671069
SSLok = 'N'; /* No support for SSL */
10681070
#endif
@@ -1073,13 +1075,15 @@ readStartupPacket(void *arg, PacketLen len, void *pkt)
10731075
}
10741076

10751077
#ifdef USE_SSL
1076-
if (!(port->ssl = SSL_new(SSL_context)) ||
1077-
!SSL_set_fd(port->ssl, port->sock) ||
1078-
SSL_accept(port->ssl) <= 0)
1079-
{
1080-
fprintf(stderr, "Failed to initialize SSL connection: %s, errno: %d (%s)\n",
1081-
ERR_reason_error_string(ERR_get_error()), errno, strerror(errno));
1082-
return STATUS_ERROR;
1078+
if (SSLok == 'S') {
1079+
if (!(port->ssl = SSL_new(SSL_context)) ||
1080+
!SSL_set_fd(port->ssl, port->sock) ||
1081+
SSL_accept(port->ssl) <= 0)
1082+
{
1083+
fprintf(stderr, "Failed to initialize SSL connection: %s, errno: %d (%s)\n",
1084+
ERR_reason_error_string(ERR_get_error()), errno, strerror(errno));
1085+
return STATUS_ERROR;
1086+
}
10831087
}
10841088
#endif
10851089
/* ready for the normal startup packet */
@@ -1091,18 +1095,6 @@ readStartupPacket(void *arg, PacketLen len, void *pkt)
10911095

10921096
/* Could add additional special packet types here */
10931097

1094-
#ifdef USE_SSL
1095-
1096-
/*
1097-
* Any SSL negotiation must have taken place here, so drop the
1098-
* connection ASAP if we require SSL
1099-
*/
1100-
if (SecureNetServer && !port->ssl)
1101-
{
1102-
PacketSendError(&port->pktInfo, "Backend requires secure connection.");
1103-
return STATUS_OK;
1104-
}
1105-
#endif
11061098

11071099
/* Check we can handle the protocol the frontend is using. */
11081100

src/bin/psql/startup.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* Copyright 2000 by PostgreSQL Global Development Group
55
*
6-
* $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.34 2000/07/02 15:21:17 petere Exp $
6+
* $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.35 2000/08/30 14:54:23 momjian Exp $
77
*/
88
#include "postgres.h"
99

@@ -81,6 +81,10 @@ static void
8181
static void
8282
showVersion(void);
8383

84+
#ifdef USE_SSL
85+
static void
86+
printSSLInfo(void);
87+
#endif
8488

8589

8690
/*
@@ -263,7 +267,9 @@ main(int argc, char *argv[])
263267
" \\g or terminate with semicolon to execute query\n"
264268
" \\q to quit\n\n", pset.progname);
265269
}
266-
270+
#ifdef USE_SSL
271+
printSSLInfo();
272+
#endif
267273
SetVariable(pset.vars, "PROMPT1", DEFAULT_PROMPT1);
268274
SetVariable(pset.vars, "PROMPT2", DEFAULT_PROMPT2);
269275
SetVariable(pset.vars, "PROMPT3", DEFAULT_PROMPT3);
@@ -639,3 +645,27 @@ showVersion(void)
639645
puts("Read the file COPYRIGHT or use the command \\copyright to see the");
640646
puts("usage and distribution terms.");
641647
}
648+
649+
650+
651+
/*
652+
* printSSLInfo
653+
*
654+
* Prints information about the current SSL connection, if SSL is in use
655+
*/
656+
#ifdef USE_SSL
657+
static void
658+
printSSLInfo(void)
659+
{
660+
int sslbits = -1;
661+
SSL *ssl;
662+
663+
ssl = PQgetssl(pset.db);
664+
if (!ssl)
665+
return; /* no SSL */
666+
667+
SSL_get_cipher_bits(ssl, &sslbits);
668+
printf("SSL enabled connection. Chiper: %s, bits: %i\n\n",
669+
SSL_get_cipher(ssl),sslbits);
670+
}
671+
#endif

src/interfaces/libpq/fe-connect.c

Lines changed: 81 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.132 2000/08/20 10:55:35 petere Exp $
11+
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.133 2000/08/30 14:54:23 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -63,7 +63,6 @@ inet_aton(const char *cp, struct in_addr * inp)
6363

6464
#ifdef USE_SSL
6565
static SSL_CTX *SSL_context = NULL;
66-
6766
#endif
6867

6968
#define NOTIFYLIST_INITIAL_SIZE 10
@@ -131,6 +130,11 @@ static const PQconninfoOption PQconninfoOptions[] = {
131130
{"options", "PGOPTIONS", DefaultOption, NULL,
132131
"Backend-Debug-Options", "D", 40},
133132

133+
#ifdef USE_SSL
134+
{"requiressl", "PGREQUIRESSL", "0", NULL,
135+
"Require-SSL", "", 1 },
136+
#endif
137+
134138
/* Terminating entry --- MUST BE LAST */
135139
{NULL, NULL, NULL, NULL,
136140
NULL, NULL, 0}
@@ -303,6 +307,10 @@ PQconnectStart(const char *conninfo)
303307
conn->pguser = tmp ? strdup(tmp) : NULL;
304308
tmp = conninfo_getval(connOptions, "password");
305309
conn->pgpass = tmp ? strdup(tmp) : NULL;
310+
#ifdef USE_SSL
311+
tmp = conninfo_getval(connOptions, "requiressl");
312+
conn->require_ssl = tmp ? (tmp[0]=='1'?true:false) : false;
313+
#endif
306314

307315
/* ----------
308316
* Free the option info - all is in conn now
@@ -475,6 +483,14 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
475483
else
476484
conn->dbName = strdup(dbName);
477485

486+
487+
#ifdef USE_SSL
488+
if ((tmp = getenv("PGREQUIRESSL")) != NULL)
489+
conn->require_ssl = (tmp[0]=='1')?true:false;
490+
else
491+
conn->require_ssl = 0;
492+
#endif
493+
478494
if (error)
479495
conn->status = CONNECTION_BAD;
480496
else
@@ -781,13 +797,55 @@ connectDBStart(PGconn *conn)
781797
goto connect_errReturn;
782798
#endif
783799

784-
#ifdef USE_SSL
785-
786-
/*
787-
* This needs to be done before we set into nonblocking, since SSL
788-
* negotiation does not like that mode
800+
/* ----------
801+
* Start / make connection. We are hopefully in non-blocking mode
802+
* now, but it is possible that:
803+
* 1. Older systems will still block on connect, despite the
804+
* non-blocking flag. (Anyone know if this is true?)
805+
* 2. We are running under Windows, and aren't even trying
806+
* to be non-blocking (see above).
807+
* 3. We are using SSL.
808+
* Thus, we have make arrangements for all eventualities.
809+
* ----------
789810
*/
811+
if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
812+
{
813+
#ifndef WIN32
814+
if (errno == EINPROGRESS || errno == 0)
815+
#else
816+
if (WSAGetLastError() == WSAEINPROGRESS)
817+
#endif
818+
{
790819

820+
/*
821+
* This is fine - we're in non-blocking mode, and the
822+
* connection is in progress.
823+
*/
824+
conn->status = CONNECTION_STARTED;
825+
}
826+
else
827+
{
828+
/* Something's gone wrong */
829+
printfPQExpBuffer(&conn->errorMessage,
830+
"connectDBStart() -- connect() failed: %s\n"
831+
"\tIs the postmaster running%s at '%s'\n"
832+
"\tand accepting connections on %s '%s'?\n",
833+
strerror(errno),
834+
(family == AF_INET) ? " (with -i)" : "",
835+
conn->pghost ? conn->pghost : "localhost",
836+
(family == AF_INET) ?
837+
"TCP/IP port" : "Unix socket",
838+
conn->pgport);
839+
goto connect_errReturn;
840+
}
841+
}
842+
else
843+
{
844+
/* We're connected already */
845+
conn->status = CONNECTION_MADE;
846+
}
847+
848+
#ifdef USE_SSL
791849
/* Attempt to negotiate SSL usage */
792850
if (conn->allow_ssl_try)
793851
{
@@ -837,7 +895,7 @@ connectDBStart(PGconn *conn)
837895
{
838896
/* Received error - probably protocol mismatch */
839897
if (conn->Pfdebug)
840-
fprintf(conn->Pfdebug, "Postmaster reports error, attempting fallback to pre-6.6.\n");
898+
fprintf(conn->Pfdebug, "Postmaster reports error, attempting fallback to pre-7.0.\n");
841899
close(conn->sock);
842900
conn->allow_ssl_try = FALSE;
843901
return connectDBStart(conn);
@@ -849,55 +907,15 @@ connectDBStart(PGconn *conn)
849907
goto connect_errReturn;
850908
}
851909
}
852-
#endif
853-
854-
/* ----------
855-
* Start / make connection. We are hopefully in non-blocking mode
856-
* now, but it is possible that:
857-
* 1. Older systems will still block on connect, despite the
858-
* non-blocking flag. (Anyone know if this is true?)
859-
* 2. We are running under Windows, and aren't even trying
860-
* to be non-blocking (see above).
861-
* 3. We are using SSL.
862-
* Thus, we have make arrangements for all eventualities.
863-
* ----------
864-
*/
865-
if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
910+
if (conn->require_ssl && !conn->ssl)
866911
{
867-
#ifndef WIN32
868-
if (errno == EINPROGRESS || errno == 0)
869-
#else
870-
if (WSAGetLastError() == WSAEINPROGRESS)
912+
/* Require SSL, but server does not support/want it */
913+
printfPQExpBuffer(&conn->errorMessage,
914+
"Server does not support SSL when SSL was required.\n");
915+
goto connect_errReturn;
916+
}
871917
#endif
872-
{
873918

874-
/*
875-
* This is fine - we're in non-blocking mode, and the
876-
* connection is in progress.
877-
*/
878-
conn->status = CONNECTION_STARTED;
879-
}
880-
else
881-
{
882-
/* Something's gone wrong */
883-
printfPQExpBuffer(&conn->errorMessage,
884-
"connectDBStart() -- connect() failed: %s\n"
885-
"\tIs the postmaster running%s at '%s'\n"
886-
"\tand accepting connections on %s '%s'?\n",
887-
strerror(errno),
888-
(family == AF_INET) ? " (with -i)" : "",
889-
conn->pghost ? conn->pghost : "localhost",
890-
(family == AF_INET) ?
891-
"TCP/IP port" : "Unix socket",
892-
conn->pgport);
893-
goto connect_errReturn;
894-
}
895-
}
896-
else
897-
{
898-
/* We're connected already */
899-
conn->status = CONNECTION_MADE;
900-
}
901919

902920
/*
903921
* This makes the connection non-blocking, for all those cases which
@@ -2485,6 +2503,15 @@ PQsetClientEncoding(PGconn *conn, const char *encoding)
24852503

24862504
#endif
24872505

2506+
#ifdef USE_SSL
2507+
SSL *PQgetssl(PGconn *conn)
2508+
{
2509+
if (!conn)
2510+
return NULL;
2511+
return conn->ssl;
2512+
}
2513+
#endif
2514+
24882515
void
24892516
PQtrace(PGconn *conn, FILE *debug_port)
24902517
{

0 commit comments

Comments
 (0)