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

Commit7506677

Browse files
committed
Improve error reporting for SSL connection failures. Remove redundant
free operations in client_cert_cb --- openssl will also attempt to freethese structures, resulting in core dumps.
1 parent88969ea commit7506677

File tree

2 files changed

+69
-50
lines changed

2 files changed

+69
-50
lines changed

‎src/backend/libpq/be-secure.c

Lines changed: 47 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.53 2004/11/17 04:05:42 neilc Exp $
14+
* $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.54 2004/11/20 00:18:13 tgl Exp $
1515
*
1616
* Since the server static private key ($DataDir/server.key)
1717
* will normally be stored unencrypted so that the database
@@ -727,37 +727,6 @@ initialize_SSL(void)
727727
return0;
728728
}
729729

730-
#ifdefWIN32
731-
/*
732-
*Win32 socket code uses nonblocking sockets. We ned to deal with that
733-
*by waiting on the socket if the SSL accept operation didn't complete
734-
*right away.
735-
*/
736-
staticintpgwin32_SSL_accept(SSL*ssl)
737-
{
738-
intr;
739-
740-
while (1)
741-
{
742-
intrc;
743-
intwaitfor;
744-
745-
r=SSL_accept(ssl);
746-
if (r==1)
747-
return1;
748-
749-
rc=SSL_get_error(ssl,r);
750-
if (rc!=SSL_ERROR_WANT_READ&&rc!=SSL_ERROR_WANT_WRITE)
751-
returnr;
752-
753-
waitfor= (rc==SSL_ERROR_WANT_READ)?FD_READ|FD_CLOSE|FD_ACCEPT:FD_WRITE|FD_CLOSE;
754-
if (pgwin32_waitforsinglesocket(SSL_get_fd(ssl),waitfor)==0)
755-
return-1;
756-
}
757-
}
758-
#defineSSL_accept(ssl) pgwin32_SSL_accept(ssl)
759-
#endif
760-
761730
/*
762731
*Destroy global SSL context.
763732
*/
@@ -777,7 +746,9 @@ destroy_SSL(void)
777746
staticint
778747
open_server_SSL(Port*port)
779748
{
780-
intr;
749+
intr;
750+
interr;
751+
781752
Assert(!port->ssl);
782753
Assert(!port->peer);
783754

@@ -799,12 +770,50 @@ open_server_SSL(Port *port)
799770
close_SSL(port);
800771
return-1;
801772
}
802-
if ((r=SSL_accept(port->ssl)) <=0)
773+
774+
aloop:
775+
r=SSL_accept(port->ssl);
776+
if (r <=0)
803777
{
804-
ereport(COMMERROR,
805-
(errcode(ERRCODE_PROTOCOL_VIOLATION),
806-
errmsg("could not accept SSL connection: %i",
807-
SSL_get_error(port->ssl,r))));
778+
err=SSL_get_error(port->ssl,r);
779+
switch (err)
780+
{
781+
caseSSL_ERROR_WANT_READ:
782+
caseSSL_ERROR_WANT_WRITE:
783+
#ifdefWIN32
784+
pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
785+
(err==SSL_ERROR_WANT_READ) ?
786+
FD_READ|FD_CLOSE|FD_ACCEPT :FD_WRITE|FD_CLOSE);
787+
#endif
788+
gotoaloop;
789+
caseSSL_ERROR_SYSCALL:
790+
if (r<0)
791+
ereport(COMMERROR,
792+
(errcode_for_socket_access(),
793+
errmsg("could not accept SSL connection: %m")));
794+
else
795+
ereport(COMMERROR,
796+
(errcode(ERRCODE_PROTOCOL_VIOLATION),
797+
errmsg("could not accept SSL connection: EOF detected")));
798+
break;
799+
caseSSL_ERROR_SSL:
800+
ereport(COMMERROR,
801+
(errcode(ERRCODE_PROTOCOL_VIOLATION),
802+
errmsg("could not accept SSL connection: %s",
803+
SSLerrmessage())));
804+
break;
805+
caseSSL_ERROR_ZERO_RETURN:
806+
ereport(COMMERROR,
807+
(errcode(ERRCODE_PROTOCOL_VIOLATION),
808+
errmsg("could not accept SSL connection: EOF detected")));
809+
break;
810+
default:
811+
ereport(COMMERROR,
812+
(errcode(ERRCODE_PROTOCOL_VIOLATION),
813+
errmsg("unrecognized SSL error code: %d",
814+
err)));
815+
break;
816+
}
808817
close_SSL(port);
809818
return-1;
810819
}

‎src/interfaces/libpq/fe-secure.c

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.55 2004/10/16 03:26:43 momjian Exp $
14+
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.56 2004/11/20 00:18:18 tgl Exp $
1515
*
1616
* NOTES
1717
* [ Most of these notes are wrong/obsolete, but perhaps not all ]
@@ -267,6 +267,11 @@ pqsecure_open_client(PGconn *conn)
267267
close_SSL(conn);
268268
returnPGRES_POLLING_FAILED;
269269
}
270+
/*
271+
* Initialize errorMessage to empty. This allows open_client_SSL()
272+
* to detect whether client_cert_cb() has stored a message.
273+
*/
274+
resetPQExpBuffer(&conn->errorMessage);
270275
}
271276
/* Begin or continue the actual handshake */
272277
returnopen_client_SSL(conn);
@@ -797,7 +802,6 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
797802
printfPQExpBuffer(&conn->errorMessage,
798803
libpq_gettext("certificate present, but not private key file \"%s\"\n"),
799804
fnbuf);
800-
X509_free(*x509);
801805
return0;
802806
}
803807
if (!S_ISREG(buf.st_mode)|| (buf.st_mode&0077)||
@@ -806,23 +810,20 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
806810
printfPQExpBuffer(&conn->errorMessage,
807811
libpq_gettext("private key file \"%s\" has wrong permissions\n"),
808812
fnbuf);
809-
X509_free(*x509);
810813
return0;
811814
}
812815
if ((fp=fopen(fnbuf,"r"))==NULL)
813816
{
814817
printfPQExpBuffer(&conn->errorMessage,
815818
libpq_gettext("could not open private key file \"%s\": %s\n"),
816819
fnbuf,pqStrerror(errno,sebuf,sizeof(sebuf)));
817-
X509_free(*x509);
818820
return0;
819821
}
820822
if (fstat(fileno(fp),&buf2)==-1||
821823
buf.st_dev!=buf2.st_dev||buf.st_ino!=buf2.st_ino)
822824
{
823825
printfPQExpBuffer(&conn->errorMessage,
824826
libpq_gettext("private key file \"%s\" changed during execution\n"),fnbuf);
825-
X509_free(*x509);
826827
return0;
827828
}
828829
if (PEM_read_PrivateKey(fp,pkey,cb,NULL)==NULL)
@@ -833,7 +834,6 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
833834
libpq_gettext("could not read private key file \"%s\": %s\n"),
834835
fnbuf,err);
835836
SSLerrfree(err);
836-
X509_free(*x509);
837837
fclose(fp);
838838
return0;
839839
}
@@ -848,8 +848,6 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
848848
libpq_gettext("certificate does not match private key file \"%s\": %s\n"),
849849
fnbuf,err);
850850
SSLerrfree(err);
851-
X509_free(*x509);
852-
EVP_PKEY_free(*pkey);
853851
return0;
854852
}
855853

@@ -1045,11 +1043,23 @@ open_client_SSL(PGconn *conn)
10451043
}
10461044
caseSSL_ERROR_SSL:
10471045
{
1048-
char*err=SSLerrmessage();
1046+
/*
1047+
* If there are problems with the local certificate files,
1048+
* these will be detected by client_cert_cb() which is
1049+
* called from SSL_connect(). We want to return that
1050+
* error message and not the rather unhelpful error that
1051+
* OpenSSL itself returns. So check to see if an error
1052+
* message was already stored.
1053+
*/
1054+
if (conn->errorMessage.len==0)
1055+
{
1056+
char*err=SSLerrmessage();
10491057

1050-
printfPQExpBuffer(&conn->errorMessage,
1051-
libpq_gettext("SSL error: %s\n"),err);
1052-
SSLerrfree(err);
1058+
printfPQExpBuffer(&conn->errorMessage,
1059+
libpq_gettext("SSL error: %s\n"),
1060+
err);
1061+
SSLerrfree(err);
1062+
}
10531063
close_SSL(conn);
10541064
returnPGRES_POLLING_FAILED;
10551065
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp