1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-30 11:03:19 +03:00

Here is a patch to fix win32 ssl builds. Summary of changes:

* Links with -leay32 and -lssleay32 instead of crypto and ssl. On win32,
"crypto and ssl" is only used for static linking.

* Initializes SSL in the backend and not just in the postmaster. We
cannot pass the SSL context from the postmaster through the parameter
file, because it contains function pointers.

* Split one error check in be-secure.c. Previously we could not tell
which of three calls actually failed. The previous code also returned
incorrect error messages if SSL_accept() failed - that function needs to
use SSL_get_error() on the return value, can't just use the error queue.

* Since the win32 implementation uses non-blocking sockets "behind the
scenes" in order to deliver signals correctly, implements a version of
SSL_accept() that can handle this. Also, add a wait function in case
SSL_read or SSL_write() needs more data.

Magnus Hagander
This commit is contained in:
Bruce Momjian
2004-10-06 09:35:23 +00:00
parent 5431393274
commit 902ca3e225
7 changed files with 234 additions and 11 deletions

View File

@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.51 2004/09/26 22:51:49 tgl Exp $
* $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.52 2004/10/06 09:35:20 momjian Exp $
*
* Since the server static private key ($DataDir/server.key)
* will normally be stored unencrypted so that the database
@ -268,6 +268,11 @@ rloop:
break;
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
#ifdef WIN32
pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
(err==SSL_ERROR_WANT_READ) ?
FD_READ|FD_CLOSE : FD_WRITE|FD_CLOSE);
#endif
goto rloop;
case SSL_ERROR_SYSCALL:
if (n == -1)
@ -356,6 +361,11 @@ wloop:
break;
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
#ifdef WIN32
pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
(err==SSL_ERROR_WANT_READ) ?
FD_READ|FD_CLOSE : FD_WRITE|FD_CLOSE);
#endif
goto wloop;
case SSL_ERROR_SYSCALL:
if (n == -1)
@ -717,6 +727,38 @@ initialize_SSL(void)
return 0;
}
#ifdef WIN32
/*
* Win32 socket code uses nonblocking sockets. We ned to deal with that
* by waiting on the socket if the SSL accept operation didn't complete
* right away.
*/
static int pgwin32_SSL_accept(SSL *ssl)
{
int r;
while (1)
{
int rc;
int waitfor;
printf("uhh\n");fflush(stdout);
r = SSL_accept(ssl);
if (r == 1)
return 1;
rc = SSL_get_error(ssl, r);
if (rc != SSL_ERROR_WANT_READ && rc != SSL_ERROR_WANT_WRITE)
return r;
waitfor = (rc == SSL_ERROR_WANT_READ)?FD_READ|FD_CLOSE|FD_ACCEPT:FD_WRITE|FD_CLOSE;
if (pgwin32_waitforsinglesocket(SSL_get_fd(ssl), waitfor) == 0)
return -1;
}
}
#define SSL_accept(ssl) pgwin32_SSL_accept(ssl)
#endif
/*
* Destroy global SSL context.
*/
@ -736,12 +778,11 @@ destroy_SSL(void)
static int
open_server_SSL(Port *port)
{
int r;
Assert(!port->ssl);
Assert(!port->peer);
if (!(port->ssl = SSL_new(SSL_context)) ||
!SSL_set_fd(port->ssl, port->sock) ||
SSL_accept(port->ssl) <= 0)
if (!(port->ssl = SSL_new(SSL_context)))
{
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
@ -750,6 +791,25 @@ open_server_SSL(Port *port)
close_SSL(port);
return -1;
}
if (!SSL_set_fd(port->ssl, port->sock))
{
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("could not set SSL socket: %s",
SSLerrmessage())));
close_SSL(port);
return -1;
}
if ((r=SSL_accept(port->ssl)) <= 0)
{
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("could not accept SSL connection: %i",
SSL_get_error(port->ssl,r))));
close_SSL(port);
return -1;
}
port->count = 0;
/* get client certificate, if available. */

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/port/win32/socket.c,v 1.6 2004/09/07 14:31:42 tgl Exp $
* $PostgreSQL: pgsql/src/backend/port/win32/socket.c,v 1.7 2004/10/06 09:35:20 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -102,7 +102,7 @@ pgwin32_poll_signals(void)
return 0;
}
static int
int
pgwin32_waitforsinglesocket(SOCKET s, int what)
{
static HANDLE waitevent = INVALID_HANDLE_VALUE;

View File

@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.425 2004/09/09 00:59:33 momjian Exp $
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.426 2004/10/06 09:35:21 momjian Exp $
*
* NOTES
*
@ -2981,6 +2981,16 @@ SubPostmasterMain(int argc, char *argv[])
/* Attach process to shared segments */
CreateSharedMemoryAndSemaphores(false, MaxBackends, 0);
#ifdef USE_SSL
/*
* Need to reinitialize the SSL library in the backend,
* since the context structures contain function pointers
* and cannot be passed through the parameter file.
*/
if (EnableSSL)
secure_initialize();
#endif
Assert(argc == 3); /* shouldn't be any more args */
proc_exit(BackendRun(&port));
}

View File

@ -227,6 +227,9 @@
/* Define to 1 if you have the `dld' library (-ldld). */
#undef HAVE_LIBDLD
/* Define to 1 if you have the `eay32' library (-leay32). */
#undef HAVE_LIBEAY32
/* Define to 1 if you have the `gen' library (-lgen). */
#undef HAVE_LIBGEN
@ -266,6 +269,9 @@
/* Define to 1 if you have the `ssl' library (-lssl). */
#undef HAVE_LIBSSL
/* Define to 1 if you have the `ssleay32' library (-lssleay32). */
#undef HAVE_LIBSSLEAY32
/* Define to 1 if you have the `unix' library (-lunix). */
#undef HAVE_LIBUNIX

View File

@ -1,4 +1,4 @@
/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.36 2004/10/05 14:27:07 momjian Exp $ */
/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.37 2004/10/06 09:35:23 momjian Exp $ */
/* undefine and redefine after #include */
#undef mkdir
@ -141,6 +141,7 @@ int pgwin32_recv(SOCKET s, char *buf, int len, int flags);
int pgwin32_send(SOCKET s, char *buf, int len, int flags);
const char *pgwin32_socket_strerror(int err);
int pgwin32_waitforsinglesocket(SOCKET s, int what);
/* in backend/port/win32/security.c */
extern int pgwin32_is_admin(void);