mirror of https://github.com/postgres/postgres
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:
parent
5431393274
commit
902ca3e225
|
@ -6558,6 +6558,7 @@ fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$with_openssl" = yes ; then
|
if test "$with_openssl" = yes ; then
|
||||||
|
if test "$PORTNAME" != "win32"; then
|
||||||
|
|
||||||
echo "$as_me:$LINENO: checking for CRYPTO_new_ex_data in -lcrypto" >&5
|
echo "$as_me:$LINENO: checking for CRYPTO_new_ex_data in -lcrypto" >&5
|
||||||
echo $ECHO_N "checking for CRYPTO_new_ex_data in -lcrypto... $ECHO_C" >&6
|
echo $ECHO_N "checking for CRYPTO_new_ex_data in -lcrypto... $ECHO_C" >&6
|
||||||
|
@ -6696,6 +6697,146 @@ echo "$as_me: error: library 'ssl' is required for OpenSSL" >&2;}
|
||||||
{ (exit 1); exit 1; }; }
|
{ (exit 1); exit 1; }; }
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
echo "$as_me:$LINENO: checking for CRYPTO_new_ex_data in -leay32" >&5
|
||||||
|
echo $ECHO_N "checking for CRYPTO_new_ex_data in -leay32... $ECHO_C" >&6
|
||||||
|
if test "${ac_cv_lib_eay32_CRYPTO_new_ex_data+set}" = set; then
|
||||||
|
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||||
|
else
|
||||||
|
ac_check_lib_save_LIBS=$LIBS
|
||||||
|
LIBS="-leay32 $LIBS"
|
||||||
|
cat >conftest.$ac_ext <<_ACEOF
|
||||||
|
#line $LINENO "configure"
|
||||||
|
#include "confdefs.h"
|
||||||
|
|
||||||
|
/* Override any gcc2 internal prototype to avoid an error. */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
#endif
|
||||||
|
/* We use char because int might match the return type of a gcc2
|
||||||
|
builtin and then its argument prototype would still apply. */
|
||||||
|
char CRYPTO_new_ex_data ();
|
||||||
|
#ifdef F77_DUMMY_MAIN
|
||||||
|
# ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
# endif
|
||||||
|
int F77_DUMMY_MAIN() { return 1; }
|
||||||
|
#endif
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
CRYPTO_new_ex_data ();
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||||
|
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||||
|
(eval $ac_link) 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); } &&
|
||||||
|
{ ac_try='test -s conftest$ac_exeext'
|
||||||
|
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||||
|
(eval $ac_try) 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); }; }; then
|
||||||
|
ac_cv_lib_eay32_CRYPTO_new_ex_data=yes
|
||||||
|
else
|
||||||
|
echo "$as_me: failed program was:" >&5
|
||||||
|
cat conftest.$ac_ext >&5
|
||||||
|
ac_cv_lib_eay32_CRYPTO_new_ex_data=no
|
||||||
|
fi
|
||||||
|
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
|
||||||
|
LIBS=$ac_check_lib_save_LIBS
|
||||||
|
fi
|
||||||
|
echo "$as_me:$LINENO: result: $ac_cv_lib_eay32_CRYPTO_new_ex_data" >&5
|
||||||
|
echo "${ECHO_T}$ac_cv_lib_eay32_CRYPTO_new_ex_data" >&6
|
||||||
|
if test $ac_cv_lib_eay32_CRYPTO_new_ex_data = yes; then
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define HAVE_LIBEAY32 1
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
LIBS="-leay32 $LIBS"
|
||||||
|
|
||||||
|
else
|
||||||
|
{ { echo "$as_me:$LINENO: error: library 'eay32' is required for OpenSSL" >&5
|
||||||
|
echo "$as_me: error: library 'eay32' is required for OpenSSL" >&2;}
|
||||||
|
{ (exit 1); exit 1; }; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
echo "$as_me:$LINENO: checking for SSL_library_init in -lssleay32" >&5
|
||||||
|
echo $ECHO_N "checking for SSL_library_init in -lssleay32... $ECHO_C" >&6
|
||||||
|
if test "${ac_cv_lib_ssleay32_SSL_library_init+set}" = set; then
|
||||||
|
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||||
|
else
|
||||||
|
ac_check_lib_save_LIBS=$LIBS
|
||||||
|
LIBS="-lssleay32 $LIBS"
|
||||||
|
cat >conftest.$ac_ext <<_ACEOF
|
||||||
|
#line $LINENO "configure"
|
||||||
|
#include "confdefs.h"
|
||||||
|
|
||||||
|
/* Override any gcc2 internal prototype to avoid an error. */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
#endif
|
||||||
|
/* We use char because int might match the return type of a gcc2
|
||||||
|
builtin and then its argument prototype would still apply. */
|
||||||
|
char SSL_library_init ();
|
||||||
|
#ifdef F77_DUMMY_MAIN
|
||||||
|
# ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
# endif
|
||||||
|
int F77_DUMMY_MAIN() { return 1; }
|
||||||
|
#endif
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
SSL_library_init ();
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||||
|
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||||
|
(eval $ac_link) 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); } &&
|
||||||
|
{ ac_try='test -s conftest$ac_exeext'
|
||||||
|
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||||
|
(eval $ac_try) 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); }; }; then
|
||||||
|
ac_cv_lib_ssleay32_SSL_library_init=yes
|
||||||
|
else
|
||||||
|
echo "$as_me: failed program was:" >&5
|
||||||
|
cat conftest.$ac_ext >&5
|
||||||
|
ac_cv_lib_ssleay32_SSL_library_init=no
|
||||||
|
fi
|
||||||
|
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
|
||||||
|
LIBS=$ac_check_lib_save_LIBS
|
||||||
|
fi
|
||||||
|
echo "$as_me:$LINENO: result: $ac_cv_lib_ssleay32_SSL_library_init" >&5
|
||||||
|
echo "${ECHO_T}$ac_cv_lib_ssleay32_SSL_library_init" >&6
|
||||||
|
if test $ac_cv_lib_ssleay32_SSL_library_init = yes; then
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define HAVE_LIBSSLEAY32 1
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
LIBS="-lssleay32 $LIBS"
|
||||||
|
|
||||||
|
else
|
||||||
|
{ { echo "$as_me:$LINENO: error: library 'ssleay32' is required for OpenSSL" >&5
|
||||||
|
echo "$as_me: error: library 'ssleay32' is required for OpenSSL" >&2;}
|
||||||
|
{ (exit 1); exit 1; }; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$with_pam" = yes ; then
|
if test "$with_pam" = yes ; then
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
dnl Process this file with autoconf to produce a configure script.
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
dnl $PostgreSQL: pgsql/configure.in,v 1.379 2004/10/01 02:00:41 neilc Exp $
|
dnl $PostgreSQL: pgsql/configure.in,v 1.380 2004/10/06 09:35:19 momjian Exp $
|
||||||
dnl
|
dnl
|
||||||
dnl Developers, please strive to achieve this order:
|
dnl Developers, please strive to achieve this order:
|
||||||
dnl
|
dnl
|
||||||
|
@ -672,8 +672,13 @@ fi
|
||||||
|
|
||||||
if test "$with_openssl" = yes ; then
|
if test "$with_openssl" = yes ; then
|
||||||
dnl Order matters!
|
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(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])])
|
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
|
fi
|
||||||
|
|
||||||
if test "$with_pam" = yes ; then
|
if test "$with_pam" = yes ; then
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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)
|
* Since the server static private key ($DataDir/server.key)
|
||||||
* will normally be stored unencrypted so that the database
|
* will normally be stored unencrypted so that the database
|
||||||
|
@ -268,6 +268,11 @@ rloop:
|
||||||
break;
|
break;
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
case SSL_ERROR_WANT_WRITE:
|
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;
|
goto rloop;
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
if (n == -1)
|
if (n == -1)
|
||||||
|
@ -356,6 +361,11 @@ wloop:
|
||||||
break;
|
break;
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
case SSL_ERROR_WANT_WRITE:
|
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;
|
goto wloop;
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
if (n == -1)
|
if (n == -1)
|
||||||
|
@ -717,6 +727,38 @@ initialize_SSL(void)
|
||||||
return 0;
|
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.
|
* Destroy global SSL context.
|
||||||
*/
|
*/
|
||||||
|
@ -736,12 +778,11 @@ destroy_SSL(void)
|
||||||
static int
|
static int
|
||||||
open_server_SSL(Port *port)
|
open_server_SSL(Port *port)
|
||||||
{
|
{
|
||||||
|
int r;
|
||||||
Assert(!port->ssl);
|
Assert(!port->ssl);
|
||||||
Assert(!port->peer);
|
Assert(!port->peer);
|
||||||
|
|
||||||
if (!(port->ssl = SSL_new(SSL_context)) ||
|
if (!(port->ssl = SSL_new(SSL_context)))
|
||||||
!SSL_set_fd(port->ssl, port->sock) ||
|
|
||||||
SSL_accept(port->ssl) <= 0)
|
|
||||||
{
|
{
|
||||||
ereport(COMMERROR,
|
ereport(COMMERROR,
|
||||||
(errcode(ERRCODE_PROTOCOL_VIOLATION),
|
(errcode(ERRCODE_PROTOCOL_VIOLATION),
|
||||||
|
@ -750,6 +791,25 @@ open_server_SSL(Port *port)
|
||||||
close_SSL(port);
|
close_SSL(port);
|
||||||
return -1;
|
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;
|
port->count = 0;
|
||||||
|
|
||||||
/* get client certificate, if available. */
|
/* get client certificate, if available. */
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
pgwin32_waitforsinglesocket(SOCKET s, int what)
|
pgwin32_waitforsinglesocket(SOCKET s, int what)
|
||||||
{
|
{
|
||||||
static HANDLE waitevent = INVALID_HANDLE_VALUE;
|
static HANDLE waitevent = INVALID_HANDLE_VALUE;
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
*
|
*
|
||||||
|
@ -2981,6 +2981,16 @@ SubPostmasterMain(int argc, char *argv[])
|
||||||
/* Attach process to shared segments */
|
/* Attach process to shared segments */
|
||||||
CreateSharedMemoryAndSemaphores(false, MaxBackends, 0);
|
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 */
|
Assert(argc == 3); /* shouldn't be any more args */
|
||||||
proc_exit(BackendRun(&port));
|
proc_exit(BackendRun(&port));
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,6 +227,9 @@
|
||||||
/* Define to 1 if you have the `dld' library (-ldld). */
|
/* Define to 1 if you have the `dld' library (-ldld). */
|
||||||
#undef HAVE_LIBDLD
|
#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). */
|
/* Define to 1 if you have the `gen' library (-lgen). */
|
||||||
#undef HAVE_LIBGEN
|
#undef HAVE_LIBGEN
|
||||||
|
|
||||||
|
@ -266,6 +269,9 @@
|
||||||
/* Define to 1 if you have the `ssl' library (-lssl). */
|
/* Define to 1 if you have the `ssl' library (-lssl). */
|
||||||
#undef HAVE_LIBSSL
|
#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). */
|
/* Define to 1 if you have the `unix' library (-lunix). */
|
||||||
#undef HAVE_LIBUNIX
|
#undef HAVE_LIBUNIX
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
/* undefine and redefine after #include */
|
||||||
#undef mkdir
|
#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);
|
int pgwin32_send(SOCKET s, char *buf, int len, int flags);
|
||||||
|
|
||||||
const char *pgwin32_socket_strerror(int err);
|
const char *pgwin32_socket_strerror(int err);
|
||||||
|
int pgwin32_waitforsinglesocket(SOCKET s, int what);
|
||||||
|
|
||||||
/* in backend/port/win32/security.c */
|
/* in backend/port/win32/security.c */
|
||||||
extern int pgwin32_is_admin(void);
|
extern int pgwin32_is_admin(void);
|
||||||
|
|
Loading…
Reference in New Issue