Index: configure.in =================================================================== RCS file: /projects/cvsroot/pgsql-server/configure.in,v retrieving revision 1.378 diff -c -r1.378 configure.in *** configure.in 27 Sep 2004 02:17:14 -0000 1.378 --- configure.in 30 Sep 2004 20:33:17 -0000 *************** *** 672,679 **** if test "$with_openssl" = yes ; then dnl Order matters! ! AC_CHECK_LIB(crypto, CRYPTO_new_ex_data, [], [AC_MSG_ERROR([library 'crypto' is required for OpenSSL])]) ! AC_CHECK_LIB(ssl, SSL_library_init, [], [AC_MSG_ERROR([library 'ssl' is required for OpenSSL])]) fi if test "$with_pam" = yes ; then --- 672,684 ---- if test "$with_openssl" = yes ; then dnl Order matters! ! if test ""$PORTNAME" "!= "win32"; then ! AC_CHECK_LIB(crypto, CRYPTO_new_ex_data, [], [AC_MSG_ERROR([library 'crypto' is required for OpenSSL])]) ! AC_CHECK_LIB(ssl, SSL_library_init, [], [AC_MSG_ERROR([library 'ssl' is required for OpenSSL])]) ! else ! AC_CHECK_LIB(eay32, CRYPTO_new_ex_data, [], [AC_MSG_ERROR([library 'eay32' is required for OpenSSL])]) ! AC_CHECK_LIB(ssleay32, SSL_library_init, [], [AC_MSG_ERROR([library 'ssleay32' is required for OpenSSL])]) ! fi fi if test "$with_pam" = yes ; then Index: src/backend/libpq/be-secure.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/libpq/be-secure.c,v retrieving revision 1.51 diff -c -r1.51 be-secure.c *** src/backend/libpq/be-secure.c 26 Sep 2004 22:51:49 -0000 1.51 --- src/backend/libpq/be-secure.c 30 Sep 2004 21:49:33 -0000 *************** *** 268,273 **** --- 268,276 ---- 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,361 **** --- 359,367 ---- 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,722 **** --- 723,758 ---- 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,747 **** static int open_server_SSL(Port *port) { 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) { ereport(COMMERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), --- 772,782 ---- static int open_server_SSL(Port *port) { + int r; Assert(!port->ssl); Assert(!port->peer); ! if (!(port->ssl = SSL_new(SSL_context))) { ereport(COMMERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), *************** *** 750,755 **** --- 785,809 ---- 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. */ Index: src/backend/port/win32/socket.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/port/win32/socket.c,v retrieving revision 1.6 diff -c -r1.6 socket.c *** src/backend/port/win32/socket.c 7 Sep 2004 14:31:42 -0000 1.6 --- src/backend/port/win32/socket.c 30 Sep 2004 21:52:59 -0000 *************** *** 102,108 **** return 0; } ! static int pgwin32_waitforsinglesocket(SOCKET s, int what) { static HANDLE waitevent = INVALID_HANDLE_VALUE; --- 101,107 ---- return 0; } ! int pgwin32_waitforsinglesocket(SOCKET s, int what) { static HANDLE waitevent = INVALID_HANDLE_VALUE; Index: src/backend/postmaster/postmaster.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/postmaster/postmaster.c,v retrieving revision 1.425 diff -c -r1.425 postmaster.c *** src/backend/postmaster/postmaster.c 9 Sep 2004 00:59:33 -0000 1.425 --- src/backend/postmaster/postmaster.c 30 Sep 2004 17:47:28 -0000 *************** *** 2981,2986 **** --- 2981,2995 ---- /* 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)); } Index: src/include/port/win32.h =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/include/port/win32.h,v retrieving revision 1.34 diff -c -r1.34 win32.h *** src/include/port/win32.h 27 Sep 2004 23:24:40 -0000 1.34 --- src/include/port/win32.h 30 Sep 2004 20:06:18 -0000 *************** *** 141,146 **** --- 141,147 ---- 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);