Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita9bd176

Browse files
committed
Attached are a revised set of SSL patches. Many of these patches
are motivated by security concerns, it's not just bug fixes. The keydifferences (from stock 7.2.1) are:*) almost all code that directly uses the OpenSSL library is in two new files, src/interfaces/libpq/fe-ssl.c src/backend/postmaster/be-ssl.c in the long run, it would be nice to merge these two files.*) the legacy code to read and write network data have been encapsulated into read_SSL() and write_SSL(). These functions should probably be renamed - they handle both SSL and non-SSL cases. the remaining code should eliminate the problems identified earlier, albeit not very cleanly.*) both front- and back-ends will send a SSL shutdown via the new close_SSL() function. This is necessary for sessions to work properly. (Sessions are not yet fully supported, but by cleanly closing the SSL connection instead of just sending a TCP FIN packet other SSL tools will be much happier.)*) The client certificate and key are now expected in a subdirectory of the user's home directory. Specifically,- the directory .postgresql must be owned by the user, and allow no access by 'group' or 'other.'- the file .postgresql/postgresql.crt must be a regular file owned by the user.- the file .postgresql/postgresql.key must be a regular file owned by the user, and allow no access by 'group' or 'other'. At the current time encrypted private keys are not supported. There should also be a way to support multiple client certs/keys.*) the front-end performs minimal validation of the back-end cert. Self-signed certs are permitted, but the common name *must* match the hostname used by the front-end. (The cert itself should always use a fully qualified domain name (FDQN) in its common name field.) This means that psql -h eris db will fail, but psql -h eris.example.com db will succeed. At the current time this must be an exact match; future patches may support any FQDN that resolves to the address returned by getpeername(2). Another common "problem" is expiring certs. For now, it may be a good idea to use a very-long-lived self-signed cert. As a compile-time option, the front-end can specify a file containing valid root certificates, but it is not yet required.*) the back-end performs minimal validation of the client cert. It allows self-signed certs. It checks for expiration. It supports a compile-time option specifying a file containing valid root certificates.*) both front- and back-ends default to TLSv1, not SSLv3/SSLv2.*) both front- and back-ends support DSA keys. DSA keys are moderately more expensive on startup, but many people consider them preferable than RSA keys. (E.g., SSH2 prefers DSA keys.)*) if /dev/urandom exists, both client and server will read 16k of randomization data from it.*) the server can read empheral DH parameters from the files $DataDir/dh512.pem $DataDir/dh1024.pem $DataDir/dh2048.pem $DataDir/dh4096.pem if none are provided, the server will default to hardcoded parameter files provided by the OpenSSL project.Remaining tasks:*) the select() clauses need to be revisited - the SSL abstraction layer may need to absorb more of the current code to avoid rare deadlock conditions. This also touches on a true solution to the pg_eof() problem.*) the SIGPIPE signal handler may need to be revisited.*) support encrypted private keys.*) sessions are not yet fully supported. (SSL sessions can span multiple "connections," and allow the client and server to avoid costly renegotiations.)*) makecert - a script that creates back-end certs.*) pgkeygen - a tool that creates front-end certs.*) the whole protocol issue, SASL, etc. *) certs are fully validated - valid root certs must be available. This is a hassle, but it means that you *can* trust the identity of the server. *) the client library can handle hardcoded root certificates, to avoid the need to copy these files. *) host name of server cert must resolve to IP address, or be a recognized alias. This is more liberal than the previous iteration. *) the number of bytes transferred is tracked, and the session key is periodically renegotiated. *) basic cert generation scripts (mkcert.sh, pgkeygen.sh). The configuration files have reasonable defaults for each type of use.Bear Giles
1 parent15378a5 commita9bd176

File tree

15 files changed

+1562
-208
lines changed

15 files changed

+1562
-208
lines changed

‎src/backend/libpq/Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# Makefile for libpq subsystem (backend half of libpq interface)
55
#
66
# IDENTIFICATION
7-
# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.30 2002/04/04 04:25:46 momjian Exp $
7+
# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.31 2002/06/14 03:56:46 momjian Exp $
88
#
99
#-------------------------------------------------------------------------
1010

@@ -14,7 +14,8 @@ include $(top_builddir)/src/Makefile.global
1414

1515
# be-fsstubs is here for historical reasons, probably belongs elsewhere
1616

17-
OBJS = be-fsstubs.o auth.o crypt.o hba.o md5.o pqcomm.o pqformat.o pqsignal.o
17+
OBJS = be-fsstubs.o be-ssl.o auth.o crypt.o hba.o md5.o pqcomm.o\
18+
pqformat.o pqsignal.o
1819

1920

2021
all: SUBSYS.o

‎src/backend/libpq/pqcomm.c

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
3030
* Portions Copyright (c) 1994, Regents of the University of California
3131
*
32-
*$Id: pqcomm.c,v 1.133 2002/05/05 00:03:28 tgl Exp $
32+
*$Id: pqcomm.c,v 1.134 2002/06/1403:56:46 momjian Exp $
3333
*
3434
*-------------------------------------------------------------------------
3535
*/
@@ -81,6 +81,14 @@
8181
#include"miscadmin.h"
8282
#include"storage/ipc.h"
8383

84+
/* these functions are misnamed - they handle both SSL and non-SSL case */
85+
externssize_tread_SSL(Port*,void*ptr,size_tlen);
86+
externssize_twrite_SSL(Port*,constvoid*ptr,size_tlen);
87+
88+
#ifdefUSE_SSL
89+
externvoidclose_SSL(Port*);
90+
#endif/* USE_SSL */
91+
8492

8593
staticvoidpq_close(void);
8694

@@ -138,6 +146,9 @@ pq_close(void)
138146
{
139147
if (MyProcPort!=NULL)
140148
{
149+
#ifdefUSE_SSL
150+
close_SSL(MyProcPort);
151+
#endif/* USE_SSL */
141152
close(MyProcPort->sock);
142153
/* make sure any subsequent attempts to do I/O fail cleanly */
143154
MyProcPort->sock=-1;
@@ -416,6 +427,7 @@ StreamConnection(int server_fd, Port *port)
416427
void
417428
StreamClose(intsock)
418429
{
430+
/* FIXME - what about closing SSL connections? */
419431
close(sock);
420432
}
421433

@@ -457,14 +469,8 @@ pq_recvbuf(void)
457469
{
458470
intr;
459471

460-
#ifdefUSE_SSL
461-
if (MyProcPort->ssl)
462-
r=SSL_read(MyProcPort->ssl,PqRecvBuffer+PqRecvLength,
463-
PQ_BUFFER_SIZE-PqRecvLength);
464-
else
465-
#endif
466-
r=recv(MyProcPort->sock,PqRecvBuffer+PqRecvLength,
467-
PQ_BUFFER_SIZE-PqRecvLength,0);
472+
r=read_SSL(MyProcPort,PqRecvBuffer+PqRecvLength,
473+
PQ_BUFFER_SIZE-PqRecvLength);
468474

469475
if (r<0)
470476
{
@@ -480,7 +486,11 @@ pq_recvbuf(void)
480486
elog(COMMERROR,"pq_recvbuf: recv() failed: %m");
481487
returnEOF;
482488
}
489+
#ifdefUSE_SSL
490+
if (r==0&& !MyProcPort->ssl)
491+
#else/* USE_SSL */
483492
if (r==0)
493+
#endif/* USE_SSL */
484494
{
485495
/* as above, only write to postmaster log */
486496
elog(COMMERROR,"pq_recvbuf: unexpected EOF on client connection");
@@ -651,14 +661,13 @@ pq_flush(void)
651661
{
652662
intr;
653663

654-
#ifdefUSE_SSL
655-
if (MyProcPort->ssl)
656-
r=SSL_write(MyProcPort->ssl,bufptr,bufend-bufptr);
657-
else
658-
#endif
659-
r=send(MyProcPort->sock,bufptr,bufend-bufptr,0);
664+
r=write_SSL(MyProcPort,bufptr,bufend-bufptr);
660665

666+
#ifdefUSE_SSL
667+
if (r<0|| (r==0&& !MyProcPort->ssl))
668+
#else/* USE_SSL */
661669
if (r <=0)
670+
#endif/* USE_SSL */
662671
{
663672
if (errno==EINTR)
664673
continue;/* Ok if we were interrupted */
@@ -703,8 +712,9 @@ int
703712
pq_eof(void)
704713
{
705714
charx;
706-
intres;
715+
intres=1;
707716

717+
#ifndefUSE_SSL/* not a good solution, but better than nothing */
708718
res=recv(MyProcPort->sock,&x,1,MSG_PEEK);
709719

710720
if (res<0)
@@ -713,6 +723,8 @@ pq_eof(void)
713723
elog(COMMERROR,"pq_eof: recv() failed: %m");
714724
returnEOF;
715725
}
726+
#endif/* USE_SSL */
727+
716728
if (res==0)
717729
returnEOF;
718730
else

‎src/backend/postmaster/postmaster.c

Lines changed: 14 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
*
3838
*
3939
* IDENTIFICATION
40-
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.276 2002/06/11 13:40:51 wieck Exp $
40+
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.277 2002/06/14 03:56:47 momjian Exp $
4141
*
4242
* NOTES
4343
*
@@ -165,10 +165,6 @@ static intServerSock_INET = INVALID_SOCK;/* stream socket server */
165165
staticintServerSock_UNIX=INVALID_SOCK;/* stream socket server */
166166
#endif
167167

168-
#ifdefUSE_SSL
169-
staticSSL_CTX*SSL_context=NULL;/* Global SSL context */
170-
#endif
171-
172168
/*
173169
* Set by the -o option
174170
*/
@@ -274,8 +270,10 @@ __attribute__((format(printf, 1, 2)));
274270
#defineShutdownDataBase()SSDataBase(BS_XLOG_SHUTDOWN)
275271

276272
#ifdefUSE_SSL
277-
staticvoidInitSSL(void);
278-
staticconstchar*SSLerrmessage(void);
273+
externintinitialize_ctx(constchar*,void (*err)(constchar*fmt,...));
274+
externvoiddestroy_ctx(void);
275+
externintopen_SSL_server(Port*);
276+
externvoidclose_SSL(Port*);
279277
#endif
280278

281279

@@ -609,7 +607,10 @@ PostmasterMain(int argc, char *argv[])
609607
ExitPostmaster(1);
610608
}
611609
if (EnableSSL)
612-
InitSSL();
610+
{
611+
if (initialize_ctx(NULL,postmaster_error)==-1)
612+
ExitPostmaster(1);
613+
}
613614
#endif
614615

615616
/*
@@ -1114,13 +1115,9 @@ ProcessStartupPacket(Port *port, bool SSLdone)
11141115

11151116
#ifdefUSE_SSL
11161117
if (SSLok=='S')
1117-
{
1118-
if (!(port->ssl=SSL_new(SSL_context))||
1119-
!SSL_set_fd(port->ssl,port->sock)||
1120-
SSL_accept(port->ssl) <=0)
1118+
{
1119+
if (open_SSL_server(port)!=STATUS_OK)
11211120
{
1122-
elog(LOG,"failed to initialize SSL connection: %s (%m)",
1123-
SSLerrmessage());
11241121
returnSTATUS_ERROR;
11251122
}
11261123
}
@@ -1322,9 +1319,10 @@ static void
13221319
ConnFree(Port*conn)
13231320
{
13241321
#ifdefUSE_SSL
1325-
if (conn->ssl)
1326-
SSL_free(conn->ssl);
1322+
close_SSL(conn);
13271323
#endif
1324+
if (conn->sock!=-1)
1325+
close(conn->sock);
13281326
free(conn);
13291327
}
13301328

@@ -2424,72 +2422,6 @@ CountChildren(void)
24242422
returncnt;
24252423
}
24262424

2427-
#ifdefUSE_SSL
2428-
2429-
/*
2430-
* Initialize SSL library and structures
2431-
*/
2432-
staticvoid
2433-
InitSSL(void)
2434-
{
2435-
charfnbuf[2048];
2436-
2437-
SSL_load_error_strings();
2438-
SSL_library_init();
2439-
SSL_context=SSL_CTX_new(SSLv23_method());
2440-
if (!SSL_context)
2441-
{
2442-
postmaster_error("failed to create SSL context: %s",
2443-
SSLerrmessage());
2444-
ExitPostmaster(1);
2445-
}
2446-
snprintf(fnbuf,sizeof(fnbuf),"%s/server.crt",DataDir);
2447-
if (!SSL_CTX_use_certificate_file(SSL_context,fnbuf,SSL_FILETYPE_PEM))
2448-
{
2449-
postmaster_error("failed to load server certificate (%s): %s",
2450-
fnbuf,SSLerrmessage());
2451-
ExitPostmaster(1);
2452-
}
2453-
snprintf(fnbuf,sizeof(fnbuf),"%s/server.key",DataDir);
2454-
if (!SSL_CTX_use_PrivateKey_file(SSL_context,fnbuf,SSL_FILETYPE_PEM))
2455-
{
2456-
postmaster_error("failed to load private key file (%s): %s",
2457-
fnbuf,SSLerrmessage());
2458-
ExitPostmaster(1);
2459-
}
2460-
if (!SSL_CTX_check_private_key(SSL_context))
2461-
{
2462-
postmaster_error("check of private key failed: %s",
2463-
SSLerrmessage());
2464-
ExitPostmaster(1);
2465-
}
2466-
}
2467-
2468-
/*
2469-
* Obtain reason string for last SSL error
2470-
*
2471-
* Some caution is needed here since ERR_reason_error_string will
2472-
* return NULL if it doesn't recognize the error code. We don't
2473-
* want to return NULL ever.
2474-
*/
2475-
staticconstchar*
2476-
SSLerrmessage(void)
2477-
{
2478-
unsigned longerrcode;
2479-
constchar*errreason;
2480-
staticcharerrbuf[32];
2481-
2482-
errcode=ERR_get_error();
2483-
if (errcode==0)
2484-
return"No SSL error reported";
2485-
errreason=ERR_reason_error_string(errcode);
2486-
if (errreason!=NULL)
2487-
returnerrreason;
2488-
snprintf(errbuf,sizeof(errbuf),"SSL error code %lu",errcode);
2489-
returnerrbuf;
2490-
}
2491-
2492-
#endif/* USE_SSL */
24932425

24942426
/*
24952427
* Fire off a subprocess for startup/shutdown/checkpoint.

‎src/bin/psql/startup.c

Lines changed: 21 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.57 2002/05/1404:20:15 ishii Exp $
6+
* $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.58 2002/06/1403:56:47 momjian Exp $
77
*/
88
#include"postgres_fe.h"
99

@@ -678,14 +678,33 @@ printSSLInfo(void)
678678
{
679679
intsslbits=-1;
680680
SSL*ssl;
681+
X509*peer;
682+
charsn[256];
683+
longl;
681684

682685
ssl=PQgetssl(pset.db);
683686
if (!ssl)
684687
return;/* no SSL */
685688

689+
/*peer = pset.db.peer; */
690+
if ((peer=SSL_get_peer_certificate(ssl))!=NULL)
691+
{
692+
X509_NAME_oneline(X509_get_subject_name(peer),sn,sizeofsn);
693+
}
694+
else
695+
{
696+
strncpy(sn,"(anonymous)",sizeofsn);
697+
}
698+
printf(gettext("SSL connection\n"));
699+
printf(gettext("(host: %s)\n"),sn);
700+
686701
SSL_get_cipher_bits(ssl,&sslbits);
687-
printf(gettext("SSL connection (cipher: %s, bits: %i)\n\n"),
702+
printf(gettext("(protocol: %s)\n"),SSL_get_version(ssl)),
703+
printf(gettext("(cipher: %s, bits: %i)\n"),
688704
SSL_get_cipher(ssl),sslbits);
705+
l=SSL_get_default_timeout(ssl);
706+
printf(gettext("(timeout: %ld:%02ld:%02ld)\n\n"),
707+
l /3600L, (l /60L) %60L,l %60L);
689708
}
690709

691710
#endif

‎src/include/libpq/libpq-be.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
1212
* Portions Copyright (c) 1994, Regents of the University of California
1313
*
14-
* $Id: libpq-be.h,v 1.27 2001/11/12 05:43:25 tgl Exp $
14+
* $Id: libpq-be.h,v 1.28 2002/06/14 03:56:47 momjian Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -70,6 +70,7 @@ typedef struct Port
7070
*/
7171
#ifdefUSE_SSL
7272
SSL*ssl;
73+
X509*peer;
7374
#endif
7475
}Port;
7576

‎src/interfaces/libpq/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#
55
# Copyright (c) 1994, Regents of the University of California
66
#
7-
# $Header: /cvsroot/pgsql/src/interfaces/libpq/Makefile,v 1.59 2001/09/22 22:54:32 petere Exp $
7+
# $Header: /cvsroot/pgsql/src/interfaces/libpq/Makefile,v 1.60 2002/06/14 03:56:47 momjian Exp $
88
#
99
#-------------------------------------------------------------------------
1010

@@ -20,7 +20,7 @@ SO_MINOR_VERSION= 2
2020
overrideCPPFLAGS := -I$(srcdir)$(CPPFLAGS) -DFRONTEND -DSYSCONFDIR='"$(sysconfdir)"'
2121

2222
OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o\
23-
pqexpbuffer.o dllist.o md5.o pqsignal.o\
23+
pqexpbuffer.o dllist.o md5.o pqsignal.ofe-ssl.o\
2424
$(INET_ATON)$(SNPRINTF)$(STRERROR)
2525

2626
ifdefMULTIBYTE

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp