Index: configure
Index: configure.in
===================================================================
RCS file: /projects/cvsroot/pgsql/configure.in,v
retrieving revision 1.464
diff -c -r1.464 configure.in
*** configure.in	29 Apr 2006 20:47:29 -0000	1.464
--- configure.in	4 May 2006 13:35:49 -0000
***************
*** 489,498 ****
  #
  AC_MSG_CHECKING([whether to build with OpenSSL support])
  PGAC_ARG_BOOL(with, openssl, no, [  --with-openssl          build with OpenSSL support],
!               [AC_DEFINE([USE_SSL], 1, [Define to build with (Open)SSL support. (--with-openssl)])])
  AC_MSG_RESULT([$with_openssl])
  AC_SUBST(with_openssl)
  
  
  #
  # Prefer libedit
--- 489,515 ----
  #
  AC_MSG_CHECKING([whether to build with OpenSSL support])
  PGAC_ARG_BOOL(with, openssl, no, [  --with-openssl          build with OpenSSL support],
!               [AC_DEFINE([USE_SSL_OPENSSL], 1, [Define to build with (Open)SSL support. (--with-openssl)])])
  AC_MSG_RESULT([$with_openssl])
  AC_SUBST(with_openssl)
  
+ #
+ # GnuTLS
+ #
+ AC_MSG_CHECKING([whether to build with GnuTLS support])
+ PGAC_ARG_BOOL(with, gnutls, no, [  --with-gnutls           build with GnuTLS support],
+               [AC_DEFINE([USE_SSL_GNUTLS], 1, [Define to build with GnuTLS (SSL) support. (--with-gnutls)])])
+ AC_MSG_RESULT([$with_gnutls])
+ AC_SUBST(with_gnutls)
+ 
+ if test "$with_openssl" = yes -o "$with_gnutls" = yes ; then
+ 	AC_DEFINE([USE_SSL], 1, [Define to build with SSL support (select either OpenSSL or GnuTLS)])
+ fi
+ 
+ if test "$with_openssl" = yes -a "$with_gnutls" = yes ; then
+   AC_MSG_ERROR([
+ *** Cannot select both OpenSSL and GnuTLS.])
+ fi
  
  #
  # Prefer libedit
***************
*** 692,697 ****
--- 709,720 ----
    fi
  fi
  
+ if test "$with_gnutls" = yes ; then
+      AC_CHECK_LIB(gnutls, gnutls_init, [], [AC_MSG_ERROR([library 'gnutls' is required for GnuTLS])])
+      # Technically we only need this with --enable-thread-safety
+      AC_CHECK_LIB(gcrypt, gcry_control, [], [AC_MSG_ERROR([library 'gcrypt' is required for GnuTLS])])
+ fi
+ 
  if test "$with_pam" = yes ; then
    AC_CHECK_LIB(pam,    pam_start, [], [AC_MSG_ERROR([library 'pam' is required for PAM])])
  fi
***************
*** 774,779 ****
--- 797,807 ----
    AC_CHECK_HEADER(openssl/err.h, [], [AC_MSG_ERROR([header file <openssl/err.h> is required for OpenSSL])])
  fi
  
+ if test "$with_gnutls" = yes ; then
+   AC_CHECK_HEADER(gnutls/gnutls.h, [], [AC_MSG_ERROR([header file <gnutls/gnutls.h> is required for GnuTLS])])
+   AC_CHECK_HEADER(gcrypt.h,        [], [AC_MSG_ERROR([header file <gcrypt.h> is required for GnuTLS])])
+ fi
+ 
  if test "$with_pam" = yes ; then
    AC_CHECK_HEADERS(security/pam_appl.h, [],
                     [AC_CHECK_HEADERS(pam/pam_appl.h, [],
Index: src/Makefile.global.in
===================================================================
RCS file: /projects/cvsroot/pgsql/src/Makefile.global.in,v
retrieving revision 1.222
diff -c -r1.222 Makefile.global.in
*** src/Makefile.global.in	19 Apr 2006 16:32:08 -0000	1.222
--- src/Makefile.global.in	4 May 2006 13:35:52 -0000
***************
*** 150,155 ****
--- 150,156 ----
  with_python	= @with_python@
  with_tcl	= @with_tcl@
  with_openssl	= @with_openssl@
+ with_gnutls	= @with_gnutls@
  with_zlib	= @with_zlib@
  enable_shared	= @enable_shared@
  enable_rpath	= @enable_rpath@
Index: src/backend/libpq/Makefile
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/libpq/Makefile,v
retrieving revision 1.37
diff -c -r1.37 Makefile
*** src/backend/libpq/Makefile	29 Nov 2003 19:51:49 -0000	1.37
--- src/backend/libpq/Makefile	4 May 2006 13:35:52 -0000
***************
*** 17,22 ****
--- 17,29 ----
  OBJS = be-fsstubs.o be-secure.o auth.o crypt.o hba.o ip.o md5.o pqcomm.o \
         pqformat.o pqsignal.o
  
+ ifeq ($(with_openssl),yes)
+ OBJS += be-secure-openssl.o
+ endif
+ 
+ ifeq ($(with_gnutls),yes)
+ OBJS += be-secure-gnutls.o
+ endif
  
  all: SUBSYS.o
  
Index: src/backend/libpq/be-secure.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/libpq/be-secure.c,v
retrieving revision 1.66
diff -c -r1.66 be-secure.c
*** src/backend/libpq/be-secure.c	27 Apr 2006 15:35:15 -0000	1.66
--- src/backend/libpq/be-secure.c	4 May 2006 13:35:52 -0000
***************
*** 89,99 ****
  #include <arpa/inet.h>
  #endif
  
- #ifdef USE_SSL
- #include <openssl/ssl.h>
- #include <openssl/dh.h>
- #endif
- 
  #include "libpq/libpq.h"
  #include "miscadmin.h"
  #include "tcop/tcopprot.h"
--- 89,94 ----
***************
*** 106,131 ****
  #define SERVER_CERT_FILE		"server.crt"
  #define SERVER_PRIVATE_KEY_FILE "server.key"
  
- static DH  *load_dh_file(int keylength);
- static DH  *load_dh_buffer(const char *, size_t);
- static DH  *tmp_dh_cb(SSL *s, int is_export, int keylength);
- static int	verify_cb(int, X509_STORE_CTX *);
- static void info_cb(const SSL *ssl, int type, int args);
- static void	initialize_SSL(void);
- static void destroy_SSL(void);
- static int	open_server_SSL(Port *);
- static void close_SSL(Port *);
- static const char *SSLerrmessage(void);
- #endif
- 
- #ifdef USE_SSL
- /*
-  *	How much data can be sent across a secure connection
-  *	(total in both directions) before we require renegotiation.
-  */
- #define RENEGOTIATION_LIMIT (512 * 1024 * 1024)
- 
- static SSL_CTX *SSL_context = NULL;
  #endif
  
  /* ------------------------------------------------------------ */
--- 101,106 ----
***************
*** 206,212 ****
  secure_initialize(void)
  {
  #ifdef USE_SSL
! 	initialize_SSL();
  #endif
  
  	return 0;
--- 181,187 ----
  secure_initialize(void)
  {
  #ifdef USE_SSL
! 	pgtls_initialize();
  #endif
  
  	return 0;
***************
*** 219,225 ****
  secure_destroy(void)
  {
  #ifdef USE_SSL
! 	destroy_SSL();
  #endif
  }
  
--- 194,200 ----
  secure_destroy(void)
  {
  #ifdef USE_SSL
! 	pgtls_destroy();
  #endif
  }
  
***************
*** 232,238 ****
  	int			r = 0;
  
  #ifdef USE_SSL
! 	r = open_server_SSL(port);
  #endif
  
  	return r;
--- 207,213 ----
  	int			r = 0;
  
  #ifdef USE_SSL
! 	r = pgtls_open_server(port);
  #endif
  
  	return r;
***************
*** 246,252 ****
  {
  #ifdef USE_SSL
  	if (port->ssl)
! 		close_SSL(port);
  #endif
  }
  
--- 221,227 ----
  {
  #ifdef USE_SSL
  	if (port->ssl)
! 		pgtls_close(port);
  #endif
  }
  
***************
*** 260,316 ****
  
  #ifdef USE_SSL
  	if (port->ssl)
! 	{
! 		int			err;
! 
! rloop:
! 		n = SSL_read(port->ssl, ptr, len);
! 		err = SSL_get_error(port->ssl, n);
! 		switch (err)
! 		{
! 			case SSL_ERROR_NONE:
! 				port->count += n;
! 				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)
! 					ereport(COMMERROR,
! 							(errcode_for_socket_access(),
! 							 errmsg("SSL SYSCALL error: %m")));
! 				else
! 				{
! 					ereport(COMMERROR,
! 							(errcode(ERRCODE_PROTOCOL_VIOLATION),
! 							 errmsg("SSL SYSCALL error: EOF detected")));
! 					errno = ECONNRESET;
! 					n = -1;
! 				}
! 				break;
! 			case SSL_ERROR_SSL:
! 				ereport(COMMERROR,
! 						(errcode(ERRCODE_PROTOCOL_VIOLATION),
! 						 errmsg("SSL error: %s", SSLerrmessage())));
! 				/* fall through */
! 			case SSL_ERROR_ZERO_RETURN:
! 				errno = ECONNRESET;
! 				n = -1;
! 				break;
! 			default:
! 				ereport(COMMERROR,
! 						(errcode(ERRCODE_PROTOCOL_VIOLATION),
! 						 errmsg("unrecognized SSL error code: %d",
! 								err)));
! 				n = -1;
! 				break;
! 		}
! 	}
  	else
  #endif
  	{
--- 235,241 ----
  
  #ifdef USE_SSL
  	if (port->ssl)
! 		n = pgtls_read(port, ptr, len);
  	else
  #endif
  	{
***************
*** 334,415 ****
  
  #ifdef USE_SSL
  	if (port->ssl)
! 	{
! 		int			err;
! 
! 		if (port->count > RENEGOTIATION_LIMIT)
! 		{
! 			SSL_set_session_id_context(port->ssl, (void *) &SSL_context,
! 									   sizeof(SSL_context));
! 			if (SSL_renegotiate(port->ssl) <= 0)
! 				ereport(COMMERROR,
! 						(errcode(ERRCODE_PROTOCOL_VIOLATION),
! 						 errmsg("SSL renegotiation failure")));
! 			if (SSL_do_handshake(port->ssl) <= 0)
! 				ereport(COMMERROR,
! 						(errcode(ERRCODE_PROTOCOL_VIOLATION),
! 						 errmsg("SSL renegotiation failure")));
! 			if (port->ssl->state != SSL_ST_OK)
! 				ereport(COMMERROR,
! 						(errcode(ERRCODE_PROTOCOL_VIOLATION),
! 						 errmsg("SSL failed to send renegotiation request")));
! 			port->ssl->state |= SSL_ST_ACCEPT;
! 			SSL_do_handshake(port->ssl);
! 			if (port->ssl->state != SSL_ST_OK)
! 				ereport(COMMERROR,
! 						(errcode(ERRCODE_PROTOCOL_VIOLATION),
! 						 errmsg("SSL renegotiation failure")));
! 			port->count = 0;
! 		}
! 
! wloop:
! 		n = SSL_write(port->ssl, ptr, len);
! 		err = SSL_get_error(port->ssl, n);
! 		switch (err)
! 		{
! 			case SSL_ERROR_NONE:
! 				port->count += n;
! 				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)
! 					ereport(COMMERROR,
! 							(errcode_for_socket_access(),
! 							 errmsg("SSL SYSCALL error: %m")));
! 				else
! 				{
! 					ereport(COMMERROR,
! 							(errcode(ERRCODE_PROTOCOL_VIOLATION),
! 							 errmsg("SSL SYSCALL error: EOF detected")));
! 					errno = ECONNRESET;
! 					n = -1;
! 				}
! 				break;
! 			case SSL_ERROR_SSL:
! 				ereport(COMMERROR,
! 						(errcode(ERRCODE_PROTOCOL_VIOLATION),
! 						 errmsg("SSL error: %s", SSLerrmessage())));
! 				/* fall through */
! 			case SSL_ERROR_ZERO_RETURN:
! 				errno = ECONNRESET;
! 				n = -1;
! 				break;
! 			default:
! 				ereport(COMMERROR,
! 						(errcode(ERRCODE_PROTOCOL_VIOLATION),
! 						 errmsg("unrecognized SSL error code: %d",
! 								err)));
! 				n = -1;
! 				break;
! 		}
! 	}
  	else
  #endif
  		n = send(port->sock, ptr, len, 0);
--- 259,265 ----
  
  #ifdef USE_SSL
  	if (port->ssl)
! 		n = pgtls_write(port, ptr, len);
  	else
  #endif
  		n = send(port->sock, ptr, len, 0);
***************
*** 417,990 ****
  	return n;
  }
  
- /* ------------------------------------------------------------ */
- /*						  SSL specific code						*/
- /* ------------------------------------------------------------ */
- #ifdef USE_SSL
- 
- /*
-  * Private substitute BIO: this wraps the SSL library's standard socket BIO
-  * so that we can enable and disable interrupts just while calling recv().
-  * We cannot have interrupts occurring while the bulk of openssl runs,
-  * because it uses malloc() and possibly other non-reentrant libc facilities.
-  *
-  * As of openssl 0.9.7, we can use the reasonably clean method of interposing
-  * a wrapper around the standard socket BIO's sock_read() method.  This relies
-  * on the fact that sock_read() doesn't call anything non-reentrant, in fact
-  * not much of anything at all except recv().  If this ever changes we'd
-  * probably need to duplicate the code of sock_read() in order to push the
-  * interrupt enable/disable down yet another level.
-  */
- 
- static bool my_bio_initialized = false;
- static BIO_METHOD my_bio_methods;
- static int	(*std_sock_read) (BIO *h, char *buf, int size);
- 
- static int
- my_sock_read(BIO *h, char *buf, int size)
- {
- 	int			res;
- 
- 	prepare_for_client_read();
- 
- 	res = std_sock_read(h, buf, size);
- 
- 	client_read_ended();
- 
- 	return res;
- }
- 
- static BIO_METHOD *
- my_BIO_s_socket(void)
- {
- 	if (!my_bio_initialized)
- 	{
- 		memcpy(&my_bio_methods, BIO_s_socket(), sizeof(BIO_METHOD));
- 		std_sock_read = my_bio_methods.bread;
- 		my_bio_methods.bread = my_sock_read;
- 		my_bio_initialized = true;
- 	}
- 	return &my_bio_methods;
- }
- 
- /* This should exactly match openssl's SSL_set_fd except for using my BIO */
- static int
- my_SSL_set_fd(SSL *s, int fd)
- {
- 	int			ret = 0;
- 	BIO		   *bio = NULL;
- 
- 	bio = BIO_new(my_BIO_s_socket());
- 
- 	if (bio == NULL)
- 	{
- 		SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
- 		goto err;
- 	}
- 	BIO_set_fd(bio, fd, BIO_NOCLOSE);
- 	SSL_set_bio(s, bio, bio);
- 	ret = 1;
- err:
- 	return ret;
- }
- 
- /*
-  *	Load precomputed DH parameters.
-  *
-  *	To prevent "downgrade" attacks, we perform a number of checks
-  *	to verify that the DBA-generated DH parameters file contains
-  *	what we expect it to contain.
-  */
- static DH  *
- load_dh_file(int keylength)
- {
- 	FILE	   *fp;
- 	char		fnbuf[MAXPGPATH];
- 	DH		   *dh = NULL;
- 	int			codes;
- 
- 	/* attempt to open file.  It's not an error if it doesn't exist. */
- 	snprintf(fnbuf, sizeof(fnbuf), "dh%d.pem", keylength);
- 	if ((fp = fopen(fnbuf, "r")) == NULL)
- 		return NULL;
- 
- /*	flock(fileno(fp), LOCK_SH); */
- 	dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
- /*	flock(fileno(fp), LOCK_UN); */
- 	fclose(fp);
- 
- 	/* is the prime the correct size? */
- 	if (dh != NULL && 8 * DH_size(dh) < keylength)
- 	{
- 		elog(LOG, "DH errors (%s): %d bits expected, %d bits found",
- 			 fnbuf, keylength, 8 * DH_size(dh));
- 		dh = NULL;
- 	}
- 
- 	/* make sure the DH parameters are usable */
- 	if (dh != NULL)
- 	{
- 		if (DH_check(dh, &codes))
- 		{
- 			elog(LOG, "DH_check error (%s): %s", fnbuf, SSLerrmessage());
- 			return NULL;
- 		}
- 		if (codes & DH_CHECK_P_NOT_PRIME)
- 		{
- 			elog(LOG, "DH error (%s): p is not prime", fnbuf);
- 			return NULL;
- 		}
- 		if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
- 			(codes & DH_CHECK_P_NOT_SAFE_PRIME))
- 		{
- 			elog(LOG,
- 				 "DH error (%s): neither suitable generator or safe prime",
- 				 fnbuf);
- 			return NULL;
- 		}
- 	}
- 
- 	return dh;
- }
- 
- /*
-  *	Load hardcoded DH parameters.
-  *
-  *	To prevent problems if the DH parameters files don't even
-  *	exist, we can load DH parameters hardcoded into this file.
-  */
- static DH  *
- load_dh_buffer(const char *buffer, size_t len)
- {
- 	BIO		   *bio;
- 	DH		   *dh = NULL;
- 
- 	bio = BIO_new_mem_buf((char *) buffer, len);
- 	if (bio == NULL)
- 		return NULL;
- 	dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
- 	if (dh == NULL)
- 		ereport(DEBUG2,
- 				(errmsg_internal("DH load buffer: %s",
- 								 SSLerrmessage())));
- 	BIO_free(bio);
- 
- 	return dh;
- }
- 
- /*
-  *	Generate an empheral DH key.  Because this can take a long
-  *	time to compute, we can use precomputed parameters of the
-  *	common key sizes.
-  *
-  *	Since few sites will bother to precompute these parameter
-  *	files, we also provide a fallback to the parameters provided
-  *	by the OpenSSL project.
-  *
-  *	These values can be static (once loaded or computed) since
-  *	the OpenSSL library can efficiently generate random keys from
-  *	the information provided.
-  */
- static DH  *
- tmp_dh_cb(SSL *s, int is_export, int keylength)
- {
- 	DH		   *r = NULL;
- 	static DH  *dh = NULL;
- 	static DH  *dh512 = NULL;
- 	static DH  *dh1024 = NULL;
- 	static DH  *dh2048 = NULL;
- 	static DH  *dh4096 = NULL;
- 
- 	switch (keylength)
- 	{
- 		case 512:
- 			if (dh512 == NULL)
- 				dh512 = load_dh_file(keylength);
- 			if (dh512 == NULL)
- 				dh512 = load_dh_buffer(file_dh512, sizeof file_dh512);
- 			r = dh512;
- 			break;
- 
- 		case 1024:
- 			if (dh1024 == NULL)
- 				dh1024 = load_dh_file(keylength);
- 			if (dh1024 == NULL)
- 				dh1024 = load_dh_buffer(file_dh1024, sizeof file_dh1024);
- 			r = dh1024;
- 			break;
- 
- 		case 2048:
- 			if (dh2048 == NULL)
- 				dh2048 = load_dh_file(keylength);
- 			if (dh2048 == NULL)
- 				dh2048 = load_dh_buffer(file_dh2048, sizeof file_dh2048);
- 			r = dh2048;
- 			break;
- 
- 		case 4096:
- 			if (dh4096 == NULL)
- 				dh4096 = load_dh_file(keylength);
- 			if (dh4096 == NULL)
- 				dh4096 = load_dh_buffer(file_dh4096, sizeof file_dh4096);
- 			r = dh4096;
- 			break;
- 
- 		default:
- 			if (dh == NULL)
- 				dh = load_dh_file(keylength);
- 			r = dh;
- 	}
- 
- 	/* this may take a long time, but it may be necessary... */
- 	if (r == NULL || 8 * DH_size(r) < keylength)
- 	{
- 		ereport(DEBUG2,
- 				(errmsg_internal("DH: generating parameters (%d bits)....",
- 								 keylength)));
- 		r = DH_generate_parameters(keylength, DH_GENERATOR_2, NULL, NULL);
- 	}
- 
- 	return r;
- }
- 
- /*
-  *	Certificate verification callback
-  *
-  *	This callback allows us to log intermediate problems during
-  *	verification, but for now we'll see if the final error message
-  *	contains enough information.
-  *
-  *	This callback also allows us to override the default acceptance
-  *	criteria (e.g., accepting self-signed or expired certs), but
-  *	for now we accept the default checks.
-  */
- static int
- verify_cb(int ok, X509_STORE_CTX *ctx)
- {
- 	return ok;
- }
- 
- /*
-  *	This callback is used to copy SSL information messages
-  *	into the PostgreSQL log.
-  */
- static void
- info_cb(const SSL *ssl, int type, int args)
- {
- 	switch (type)
- 	{
- 		case SSL_CB_HANDSHAKE_START:
- 			ereport(DEBUG4,
- 					(errmsg_internal("SSL: handshake start")));
- 			break;
- 		case SSL_CB_HANDSHAKE_DONE:
- 			ereport(DEBUG4,
- 					(errmsg_internal("SSL: handshake done")));
- 			break;
- 		case SSL_CB_ACCEPT_LOOP:
- 			ereport(DEBUG4,
- 					(errmsg_internal("SSL: accept loop")));
- 			break;
- 		case SSL_CB_ACCEPT_EXIT:
- 			ereport(DEBUG4,
- 					(errmsg_internal("SSL: accept exit (%d)", args)));
- 			break;
- 		case SSL_CB_CONNECT_LOOP:
- 			ereport(DEBUG4,
- 					(errmsg_internal("SSL: connect loop")));
- 			break;
- 		case SSL_CB_CONNECT_EXIT:
- 			ereport(DEBUG4,
- 					(errmsg_internal("SSL: connect exit (%d)", args)));
- 			break;
- 		case SSL_CB_READ_ALERT:
- 			ereport(DEBUG4,
- 					(errmsg_internal("SSL: read alert (0x%04x)", args)));
- 			break;
- 		case SSL_CB_WRITE_ALERT:
- 			ereport(DEBUG4,
- 					(errmsg_internal("SSL: write alert (0x%04x)", args)));
- 			break;
- 	}
- }
- 
- /*
-  *	Initialize global SSL context.
-  */
- static void
- initialize_SSL(void)
- {
- 	struct stat buf;
- 
- 	if (!SSL_context)
- 	{
- 		SSL_library_init();
- 		SSL_load_error_strings();
- 		SSL_context = SSL_CTX_new(SSLv23_method());
- 		if (!SSL_context)
- 			ereport(FATAL,
- 					(errmsg("could not create SSL context: %s",
- 							SSLerrmessage())));
- 
- 		/*
- 		 * Load and verify certificate and private key
- 		 */
- 		if (!SSL_CTX_use_certificate_file(SSL_context,
- 										  SERVER_CERT_FILE,
- 										  SSL_FILETYPE_PEM))
- 			ereport(FATAL,
- 					(errcode(ERRCODE_CONFIG_FILE_ERROR),
- 				  errmsg("could not load server certificate file \"%s\": %s",
- 						 SERVER_CERT_FILE, SSLerrmessage())));
- 
- 		if (stat(SERVER_PRIVATE_KEY_FILE, &buf) == -1)
- 			ereport(FATAL,
- 					(errcode_for_file_access(),
- 					 errmsg("could not access private key file \"%s\": %m",
- 							SERVER_PRIVATE_KEY_FILE)));
- 
- 		/*
- 		 * Require no public access to key file.
- 		 *
- 		 * XXX temporarily suppress check when on Windows, because there may
- 		 * not be proper support for Unix-y file permissions.  Need to think
- 		 * of a reasonable check to apply on Windows.  (See also the data
- 		 * directory permission check in postmaster.c)
- 		 */
- #if !defined(WIN32) && !defined(__CYGWIN__)
- 		if (!S_ISREG(buf.st_mode) || (buf.st_mode & (S_IRWXG | S_IRWXO)) ||
- 			buf.st_uid != geteuid())
- 			ereport(FATAL,
- 					(errcode(ERRCODE_CONFIG_FILE_ERROR),
- 					 errmsg("unsafe permissions on private key file \"%s\"",
- 							SERVER_PRIVATE_KEY_FILE),
- 					 errdetail("File must be owned by the database user and must have no permissions for \"group\" or \"other\".")));
- #endif
- 
- 		if (!SSL_CTX_use_PrivateKey_file(SSL_context,
- 										 SERVER_PRIVATE_KEY_FILE,
- 										 SSL_FILETYPE_PEM))
- 			ereport(FATAL,
- 					(errmsg("could not load private key file \"%s\": %s",
- 							SERVER_PRIVATE_KEY_FILE, SSLerrmessage())));
- 
- 		if (!SSL_CTX_check_private_key(SSL_context))
- 			ereport(FATAL,
- 					(errmsg("check of private key failed: %s",
- 							SSLerrmessage())));
- 	}
- 
- 	/* set up empheral DH keys */
- 	SSL_CTX_set_tmp_dh_callback(SSL_context, tmp_dh_cb);
- 	SSL_CTX_set_options(SSL_context, SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv2);
- 
- 	/* setup the allowed cipher list */
- 	if (SSL_CTX_set_cipher_list(SSL_context, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH") != 1)
- 		elog(FATAL, "could not set the cipher list (no valid ciphers available)");
- 
- 	/*
- 	 * Require and check client certificates only if we have a root.crt file.
- 	 */
- 	if (!SSL_CTX_load_verify_locations(SSL_context, ROOT_CERT_FILE, NULL))
- 	{
- 		/* Not fatal - we do not require client certificates */
- 		ereport(LOG,
- 				(errmsg("could not load root certificate file \"%s\": %s",
- 						ROOT_CERT_FILE, SSLerrmessage()),
- 				 errdetail("Will not verify client certificates.")));
- 	}
- 	else
- 	{
- 		/*
- 		 *	Check the Certificate Revocation List (CRL) if file exists.
- 		 *	http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html
- 		 */
- 		X509_STORE *cvstore = SSL_CTX_get_cert_store(SSL_context);
- 
- 		if (cvstore)
- 		{
- 			if (X509_STORE_load_locations(cvstore, ROOT_CRL_FILE, NULL) != 0)
- 			   /* setting the flags to check against the complete CRL chain */
- 			   X509_STORE_set_flags(cvstore,
- 							X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
- 			else
- 			{
- 				/* Not fatal - we do not require CRL */
- 				ereport(LOG,
- 					(errmsg("SSL Certificate Revocation List (CRL) file \"%s\" not found, skipping: %s",
- 							ROOT_CRL_FILE, SSLerrmessage()),
- 					 errdetail("Will not check certificates against CRL.")));
- 			}
- 		}
- 
- 		SSL_CTX_set_verify(SSL_context,
- 						   (SSL_VERIFY_PEER |
- 							SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
- 							SSL_VERIFY_CLIENT_ONCE),
- 						   verify_cb);
- 	}
- }
- 
- /*
-  *	Destroy global SSL context.
-  */
- static void
- destroy_SSL(void)
- {
- 	if (SSL_context)
- 	{
- 		SSL_CTX_free(SSL_context);
- 		SSL_context = NULL;
- 	}
- }
- 
- /*
-  *	Attempt to negotiate SSL connection.
-  */
- static int
- open_server_SSL(Port *port)
- {
- 	int			r;
- 	int			err;
- 
- 	Assert(!port->ssl);
- 	Assert(!port->peer);
- 
- 	if (!(port->ssl = SSL_new(SSL_context)))
- 	{
- 		ereport(COMMERROR,
- 				(errcode(ERRCODE_PROTOCOL_VIOLATION),
- 				 errmsg("could not initialize SSL connection: %s",
- 						SSLerrmessage())));
- 		close_SSL(port);
- 		return -1;
- 	}
- 	if (!my_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;
- 	}
- 
- aloop:
- 	r = SSL_accept(port->ssl);
- 	if (r <= 0)
- 	{
- 		err = SSL_get_error(port->ssl, r);
- 		switch (err)
- 		{
- 			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_ACCEPT : FD_WRITE | FD_CLOSE);
- #endif
- 				goto aloop;
- 			case SSL_ERROR_SYSCALL:
- 				if (r < 0)
- 					ereport(COMMERROR,
- 							(errcode_for_socket_access(),
- 							 errmsg("could not accept SSL connection: %m")));
- 				else
- 					ereport(COMMERROR,
- 							(errcode(ERRCODE_PROTOCOL_VIOLATION),
- 					errmsg("could not accept SSL connection: EOF detected")));
- 				break;
- 			case SSL_ERROR_SSL:
- 				ereport(COMMERROR,
- 						(errcode(ERRCODE_PROTOCOL_VIOLATION),
- 						 errmsg("could not accept SSL connection: %s",
- 								SSLerrmessage())));
- 				break;
- 			case SSL_ERROR_ZERO_RETURN:
- 				ereport(COMMERROR,
- 						(errcode(ERRCODE_PROTOCOL_VIOLATION),
- 				   errmsg("could not accept SSL connection: EOF detected")));
- 				break;
- 			default:
- 				ereport(COMMERROR,
- 						(errcode(ERRCODE_PROTOCOL_VIOLATION),
- 						 errmsg("unrecognized SSL error code: %d",
- 								err)));
- 				break;
- 		}
- 		close_SSL(port);
- 		return -1;
- 	}
- 
- 	port->count = 0;
- 
- 	/* get client certificate, if available. */
- 	port->peer = SSL_get_peer_certificate(port->ssl);
- 	if (port->peer == NULL)
- 	{
- 		strncpy(port->peer_dn, "(anonymous)", sizeof(port->peer_dn));
- 		strncpy(port->peer_cn, "(anonymous)", sizeof(port->peer_cn));
- 	}
- 	else
- 	{
- 		X509_NAME_oneline(X509_get_subject_name(port->peer),
- 						  port->peer_dn, sizeof(port->peer_dn));
- 		port->peer_dn[sizeof(port->peer_dn) - 1] = '\0';
- 		X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
- 					   NID_commonName, port->peer_cn, sizeof(port->peer_cn));
- 		port->peer_cn[sizeof(port->peer_cn) - 1] = '\0';
- 	}
- 	ereport(DEBUG2,
- 			(errmsg("SSL connection from \"%s\"", port->peer_cn)));
- 
- 	/* set up debugging/info callback */
- 	SSL_CTX_set_info_callback(SSL_context, info_cb);
- 
- 	return 0;
- }
- 
- /*
-  *	Close SSL connection.
-  */
- static void
- close_SSL(Port *port)
- {
- 	if (port->ssl)
- 	{
- 		SSL_shutdown(port->ssl);
- 		SSL_free(port->ssl);
- 		port->ssl = NULL;
- 	}
- 
- 	if (port->peer)
- 	{
- 		X509_free(port->peer);
- 		port->peer = NULL;
- 	}
- }
- 
- /*
-  * Obtain reason string for last SSL error
-  *
-  * Some caution is needed here since ERR_reason_error_string will
-  * return NULL if it doesn't recognize the error code.  We don't
-  * want to return NULL ever.
-  */
- static const char *
- SSLerrmessage(void)
- {
- 	unsigned long errcode;
- 	const char *errreason;
- 	static char errbuf[32];
- 
- 	errcode = ERR_get_error();
- 	if (errcode == 0)
- 		return "No SSL error reported";
- 	errreason = ERR_reason_error_string(errcode);
- 	if (errreason != NULL)
- 		return errreason;
- 	snprintf(errbuf, sizeof(errbuf), "SSL error code %lu", errcode);
- 	return errbuf;
- }
- 
- #endif   /* USE_SSL */
--- 267,269 ----
Index: src/bin/psql/Makefile
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/Makefile,v
retrieving revision 1.57
diff -c -r1.57 Makefile
*** src/bin/psql/Makefile	5 Mar 2006 15:58:51 -0000	1.57
--- src/bin/psql/Makefile	4 May 2006 13:35:52 -0000
***************
*** 27,32 ****
--- 27,34 ----
  
  FLEXFLAGS = -Cfe
  
+ # Remove libs not needed for psql as they may conflict with libpq
+ LIBS := $(filter-out -lz -lgnutls -lgcrypt -lssl -lcrypto, $(LIBS))
  
  all: submake-libpq submake-libpgport submake-backend psql
  
Index: src/bin/psql/command.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/command.c,v
retrieving revision 1.166
diff -c -r1.166 command.c
*** src/bin/psql/command.c	2 Apr 2006 20:08:22 -0000	1.166
--- src/bin/psql/command.c	4 May 2006 13:35:52 -0000
***************
*** 800,805 ****
--- 800,818 ----
  		}
  		free(opt0);
  	}
+ 	
+ 	/* \ssl -- Display SSL connection info */
+ 	else if (strcmp(cmd, "ssl") == 0 )
+ 	{
+ 		PGresult *res = PQgettlsinfo(pset.db);
+ 		if( !res )
+ 			printf(gettext("No SSL available"));
+ 		else
+ 		{
+ 			printQuery( res, &pset.popt, stdout, NULL );
+ 			PQclear(res);
+ 		}
+ 	}
  
  	/* \t -- turn off headers and row count */
  	else if (strcmp(cmd, "t") == 0)
Index: src/bin/psql/help.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/help.c,v
retrieving revision 1.110
diff -c -r1.110 help.c
*** src/bin/psql/help.c	5 Mar 2006 15:58:51 -0000	1.110
--- src/bin/psql/help.c	4 May 2006 13:35:52 -0000
***************
*** 199,204 ****
--- 199,205 ----
  #ifdef USE_READLINE
  	fprintf(output, _("  \\s [FILE]      display history or save it to file\n"));
  #endif
+ 	fprintf(output, _("  \\ssl           display SSL information\n"));
  	fprintf(output, _("  \\w FILE        write query buffer to file\n"));
  	fprintf(output, "\n");
  
Index: src/bin/psql/startup.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/startup.c,v
retrieving revision 1.132
diff -c -r1.132 startup.c
*** src/bin/psql/startup.c	27 Apr 2006 02:58:08 -0000	1.132
--- src/bin/psql/startup.c	4 May 2006 13:35:52 -0000
***************
*** 8,16 ****
  #include "postgres_fe.h"
  
  #include <sys/types.h>
- #ifdef USE_SSL
- #include <openssl/ssl.h>
- #endif
  
  #ifndef WIN32
  #include <unistd.h>
--- 8,13 ----
***************
*** 89,97 ****
  static void process_psqlrc_file(char *filename);
  static void showVersion(void);
  
- #ifdef USE_SSL
  static void printSSLInfo(void);
- #endif
  
  #ifdef WIN32
  static void
--- 86,92 ----
***************
*** 358,366 ****
  					   pset.progname,
  					   client_ver / 10000, (client_ver / 100) % 100);
  
- #ifdef USE_SSL
  			printSSLInfo();
- #endif
  #ifdef WIN32
  			checkWin32Codepage();
  #endif
--- 353,359 ----
***************
*** 721,748 ****
  }
  
  
  
  /*
   * printSSLInfo
   *
   * Prints information about the current SSL connection, if SSL is in use
   */
- #ifdef USE_SSL
  static void
  printSSLInfo(void)
  {
! 	int			sslbits = -1;
! 	SSL		   *ssl;
! 
! 	ssl = PQgetssl(pset.db);
! 	if (!ssl)
! 		return;					/* no SSL */
! 
! 	SSL_get_cipher_bits(ssl, &sslbits);
! 	printf(_("SSL connection (cipher: %s, bits: %i)\n\n"),
! 		   SSL_get_cipher(ssl), sslbits);
  }
- #endif
  
  
  
--- 714,755 ----
  }
  
  
+ /* getSSLinfostring
+  *
+  * Gets a string from the returned SSL info
+  */
+ static const char *
+ getSSLinfostring( PGresult *sslinfo, const char *key )
+ {
+ 	int i;
+ 	for( i=0; i<PQntuples(sslinfo); i++ )
+ 		if( strcmp( PQgetvalue( sslinfo, i, 0 ), key ) == 0 )
+ 			return PQgetvalue( sslinfo, i, 1 );
+ 	return "";
+ }
  
  /*
   * printSSLInfo
   *
   * Prints information about the current SSL connection, if SSL is in use
   */
  static void
  printSSLInfo(void)
  {
! 	PGresult *res = PQgettlsinfo(pset.db);
! 	
! 	if( !res )
! 		return;
! 
! 	if( strcmp( getSSLinfostring( res, "tls_active" ), "yes" ) != 0 ) 
! 		return;
! 	printf( "SSL connection established: %s (version %s), encryption %s\n", 
! 	            getSSLinfostring( res, "tls_library" ),
! 	            getSSLinfostring( res, "tls_library_version" ),
! 	            getSSLinfostring( res, "tls_cipher" ) );
! 	 
! 	PQclear(res);
  }
  
  
  
Index: src/include/pg_config.h.in
Index: src/include/libpq/libpq-be.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/libpq/libpq-be.h,v
retrieving revision 1.55
diff -c -r1.55 libpq-be.h
*** src/include/libpq/libpq-be.h	5 Mar 2006 15:58:56 -0000	1.55
--- src/include/libpq/libpq-be.h	4 May 2006 13:35:53 -0000
***************
*** 21,29 ****
  #ifdef HAVE_SYS_TIME_H
  #include <sys/time.h>
  #endif
! #ifdef USE_SSL
  #include <openssl/ssl.h>
  #include <openssl/err.h>
  #endif
  #ifdef HAVE_NETINET_TCP_H
  #include <netinet/tcp.h>
--- 21,35 ----
  #ifdef HAVE_SYS_TIME_H
  #include <sys/time.h>
  #endif
! #ifdef USE_SSL_OPENSSL
  #include <openssl/ssl.h>
  #include <openssl/err.h>
+ typedef SSL *pg_sslcontext;
+ typedef X509 *pg_sslcert;
+ #elif USE_SSL_GNUTLS
+ #include <gnutls/gnutls.h>
+ typedef gnutls_session pg_sslcontext;
+ typedef const gnutls_datum *pg_sslcert;
  #endif
  #ifdef HAVE_NETINET_TCP_H
  #include <netinet/tcp.h>
***************
*** 100,107 ****
  	 * SSL structures
  	 */
  #ifdef USE_SSL
! 	SSL		   *ssl;
! 	X509	   *peer;
  	char		peer_dn[128 + 1];
  	char		peer_cn[SM_USER + 1];
  	unsigned long count;
--- 106,113 ----
  	 * SSL structures
  	 */
  #ifdef USE_SSL
! 	pg_sslcontext ssl;
! 	pg_sslcert    peer;
  	char		peer_dn[128 + 1];
  	char		peer_cn[SM_USER + 1];
  	unsigned long count;
Index: src/include/libpq/libpq.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/libpq/libpq.h,v
retrieving revision 1.66
diff -c -r1.66 libpq.h
*** src/include/libpq/libpq.h	5 Mar 2006 15:58:56 -0000	1.66
--- src/include/libpq/libpq.h	4 May 2006 13:35:53 -0000
***************
*** 74,77 ****
--- 74,95 ----
  extern ssize_t secure_read(Port *port, void *ptr, size_t len);
  extern ssize_t secure_write(Port *port, void *ptr, size_t len);
  
+ #ifdef USE_SSL
+ /*
+  * prototypes for functions that implement the TLS layer
+  */
+ #define ROOT_CERT_FILE			"root.crt"
+ #define ROOT_CRL_FILE			"root.crl"
+ #define SERVER_CERT_FILE		"server.crt"
+ #define SERVER_PRIVATE_KEY_FILE "server.key"
+ 
+ extern void	pgtls_initialize(void);
+ extern void pgtls_destroy(void);
+ extern int	pgtls_open_server(Port *);
+ extern void pgtls_close(Port *);
+ extern ssize_t pgtls_read(Port *port, void *ptr, size_t len);
+ extern ssize_t pgtls_write(Port *port, void *ptr, size_t len);
+ 
+ #endif
+ 
  #endif   /* LIBPQ_H */
Index: src/interfaces/libpq/Makefile
===================================================================
RCS file: /projects/cvsroot/pgsql/src/interfaces/libpq/Makefile,v
retrieving revision 1.144
diff -c -r1.144 Makefile
*** src/interfaces/libpq/Makefile	28 Apr 2006 02:53:20 -0000	1.144
--- src/interfaces/libpq/Makefile	4 May 2006 13:35:53 -0000
***************
*** 36,41 ****
--- 36,49 ----
  	md5.o ip.o wchar.o encnames.o noblock.o pgstrcasecmp.o thread.o \
  	$(filter crypt.o getaddrinfo.o inet_aton.o open.o snprintf.o strerror.o, $(LIBOBJS))
  
+ ifeq ($(with_openssl),yes)
+ OBJS += fe-secure-openssl.o
+ endif
+ 
+ ifeq ($(with_gnutls),yes)
+ OBJS += fe-secure-gnutls.o
+ endif
+ 
  ifeq ($(PORTNAME), cygwin)
  override shlib = cyg$(NAME)$(DLSUFFIX)
  endif
***************
*** 57,71 ****
  # shared library link.  (The order in which you list them here doesn't
  # matter.)
  ifneq ($(PORTNAME), win32)
! SHLIB_LINK += $(filter -lcrypt -ldes -lcom_err -lcrypto -lk5crypto -lkrb5 -lssl -lsocket -lnsl -lresolv -lintl, $(LIBS)) $(PTHREAD_LIBS)
  else
! SHLIB_LINK += $(filter -lcrypt -ldes -lcom_err -lcrypto -lk5crypto -lkrb5 -lssl -lsocket -lnsl -lresolv -lintl $(PTHREAD_LIBS), $(LIBS))
  endif
  ifeq ($(PORTNAME), win32)
  SHLIB_LINK += -lshfolder -lwsock32 -lws2_32 $(filter -leay32 -lssleay32 -lcomerr32 -lkrb5_32, $(LIBS))
  endif
  
- 
  all: def-files $(srcdir)/libpq.rc all-lib
  
  # Shared library stuff
--- 65,78 ----
  # shared library link.  (The order in which you list them here doesn't
  # matter.)
  ifneq ($(PORTNAME), win32)
! SHLIB_LINK += $(filter -lcrypt -ldes -lcom_err -lcrypto -lk5crypto -lkrb5 -lssl -lsocket -lnsl -lresolv -lintl -lgnutls -lgcrypt, $(LIBS)) $(PTHREAD_LIBS)
  else
! SHLIB_LINK += $(filter -lcrypt -ldes -lcom_err -lcrypto -lk5crypto -lkrb5 -lssl -lsocket -lnsl -lresolv -lintl -lgnutls -lgcrypt $(PTHREAD_LIBS), $(LIBS))
  endif
  ifeq ($(PORTNAME), win32)
  SHLIB_LINK += -lshfolder -lwsock32 -lws2_32 $(filter -leay32 -lssleay32 -lcomerr32 -lkrb5_32, $(LIBS))
  endif
  
  all: def-files $(srcdir)/libpq.rc all-lib
  
  # Shared library stuff
Index: src/interfaces/libpq/exports.txt
===================================================================
RCS file: /projects/cvsroot/pgsql/src/interfaces/libpq/exports.txt,v
retrieving revision 1.7
diff -c -r1.7 exports.txt
*** src/interfaces/libpq/exports.txt	26 Dec 2005 14:58:05 -0000	1.7
--- src/interfaces/libpq/exports.txt	4 May 2006 13:35:53 -0000
***************
*** 126,128 ****
--- 126,130 ----
  PQinitSSL                 124
  PQregisterThreadLock      125
  PQencryptPassword         126
+ PQgettlsinfo              127
+ PQsetPassthrough          128
Index: src/interfaces/libpq/fe-exec.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v
retrieving revision 1.182
diff -c -r1.182 fe-exec.c
*** src/interfaces/libpq/fe-exec.c	14 Mar 2006 22:48:23 -0000	1.182
--- src/interfaces/libpq/fe-exec.c	4 May 2006 13:35:53 -0000
***************
*** 863,868 ****
--- 863,875 ----
  	/* clear the error string */
  	resetPQExpBuffer(&conn->errorMessage);
  
+ 	/* Don't try to send if the user has taken the connection */
+ 	if (conn->status == CONNECTION_PASSTHROUGH)
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 						  libpq_gettext("connection is in passthrough mode\n"));
+ 		return false;
+ 	}
  	/* Don't try to send if we know there's no live connection. */
  	if (conn->status != CONNECTION_OK)
  	{
***************
*** 1091,1096 ****
--- 1098,1110 ----
  	if (!conn)
  		return 0;
  
+ 	/* Not possible in passthrough mode */
+ 	if (conn->status == CONNECTION_PASSTHROUGH)
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 						  libpq_gettext("connection is in passthrough mode\n"));
+ 		return false;
+ 	}
  	/*
  	 * for non-blocking connections try to flush the send-queue, otherwise we
  	 * may never get a response for something that may not have already been
***************
*** 1788,1793 ****
--- 1802,1843 ----
  		return pqEndcopy2(conn);
  }
  
+ /*
+  * PQsetPassthrough
+  *		Once a connection has been established to the server, using
+  *		this function it is possible to take connection and
+  *		communicate to the server directly. If true is returned, the
+  *		state variable points to a filled in structure. The
+  *		functions read and write will send and receive data from the
+  *		server. The function PQsetnonblocking has effect. If true
+  *		these functions will return appropriate states.
+  *
+  *		It is no possible to return to normal query state from here.
+  *		The connection state will be CONNECTION_PASSTHROUGH. The
+  *		only way out is to close the connection.
+  *		
+  * RETURNS
+  *		true if passthrough has been enabled
+  *
+  *		*state points to a newly allocated structure with the
+  *		necessary information. This pointer must be freed using
+  *		PQfreemem when no longer needed.
+  */
+ int
+ PQsetPassthrough(PGconn *conn, PQpassthrough **state )
+ {
+ 	if( !state )
+ 		return false;
+ 		
+ 	if(!PQsendQueryStart(conn))
+ 		return false;
+ 	
+ 	*state = (PQpassthrough *)malloc(sizeof(PQpassthrough));
+ 	(*state)->len = sizeof(PQpassthrough);
+ 	pqsecure_pt_setup(*state);
+ 	conn->status = CONNECTION_PASSTHROUGH;
+ 	return true;
+ }
  
  /* ----------------
   *		PQfn -	Send a function call to the POSTGRES backend.
Index: src/interfaces/libpq/fe-misc.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v
retrieving revision 1.125
diff -c -r1.125 fe-misc.c
*** src/interfaces/libpq/fe-misc.c	5 Mar 2006 15:59:09 -0000	1.125
--- src/interfaces/libpq/fe-misc.c	4 May 2006 13:35:53 -0000
***************
*** 969,975 ****
  
  #ifdef USE_SSL
  	/* Check for SSL library buffering read bytes */
! 	if (forRead && conn->ssl && SSL_pending(conn->ssl) > 0)
  	{
  		/* short-circuit the select */
  		return 1;
--- 969,975 ----
  
  #ifdef USE_SSL
  	/* Check for SSL library buffering read bytes */
! 	if (forRead && conn->ssl && pqsecure_pending(conn) > 0)
  	{
  		/* short-circuit the select */
  		return 1;
Index: src/interfaces/libpq/fe-secure.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/interfaces/libpq/fe-secure.c,v
retrieving revision 1.79
diff -c -r1.79 fe-secure.c
*** src/interfaces/libpq/fe-secure.c	27 Apr 2006 14:02:36 -0000	1.79
--- src/interfaces/libpq/fe-secure.c	4 May 2006 13:35:53 -0000
***************
*** 114,156 ****
  #include "strdup.h"
  #endif
  
! #ifdef USE_SSL
! #include <openssl/ssl.h>
! #endif   /* USE_SSL */
! 
! 
! #ifdef USE_SSL
! 
! #ifndef WIN32
! #define USER_CERT_FILE		".postgresql/postgresql.crt"
! #define USER_KEY_FILE		".postgresql/postgresql.key"
! #define ROOT_CERT_FILE		".postgresql/root.crt"
! #else
! /* On Windows, the "home" directory is already PostgreSQL-specific */
! #define USER_CERT_FILE		"postgresql.crt"
! #define USER_KEY_FILE		"postgresql.key"
! #define ROOT_CERT_FILE		"root.crt"
! #endif
! 
! #ifdef NOT_USED
! static int	verify_peer(PGconn *);
! #endif
! static int	verify_cb(int ok, X509_STORE_CTX *ctx);
! static int	client_cert_cb(SSL *, X509 **, EVP_PKEY **);
! static int	init_ssl_system(PGconn *conn);
! static int	initialize_SSL(PGconn *);
! static void destroy_SSL(void);
! static PostgresPollingStatusType open_client_SSL(PGconn *);
! static void close_SSL(PGconn *);
! static char *SSLerrmessage(void);
! static void SSLerrfree(char *buf);
! #endif
  
- #ifdef USE_SSL
- static bool pq_initssllib = true;
  
! static SSL_CTX *SSL_context = NULL;
! #endif
  
  /* ------------------------------------------------------------ */
  /*			 Procedures common to all secure sessions			*/
--- 114,123 ----
  #include "strdup.h"
  #endif
  
! #include "libpq-tls.h"
  
  
! char pqTLS_ssl_nomem[] = "Out of memory allocating error description";
  
  /* ------------------------------------------------------------ */
  /*			 Procedures common to all secure sessions			*/
***************
*** 158,175 ****
  
  
  /*
-  *	Exported function to allow application to tell us it's already
-  *	initialized OpenSSL.
-  */
- void
- PQinitSSL(int do_init)
- {
- #ifdef USE_SSL
- 	pq_initssllib = do_init;
- #endif
- }
- 
- /*
   *	Initialize global context
   */
  int
--- 125,130 ----
***************
*** 178,184 ****
  	int			r = 0;
  
  #ifdef USE_SSL
! 	r = initialize_SSL(conn);
  #endif
  
  	return r;
--- 133,139 ----
  	int			r = 0;
  
  #ifdef USE_SSL
! 	r = pqTLS_initialize(conn);
  #endif
  
  	return r;
***************
*** 191,197 ****
  pqsecure_destroy(void)
  {
  #ifdef USE_SSL
! 	destroy_SSL();
  #endif
  }
  
--- 146,152 ----
  pqsecure_destroy(void)
  {
  #ifdef USE_SSL
! 	pqTLS_destroy();
  #endif
  }
  
***************
*** 205,232 ****
  	/* First time through? */
  	if (conn->ssl == NULL)
  	{
! 		if (!(conn->ssl = SSL_new(SSL_context)) ||
! 			!SSL_set_app_data(conn->ssl, conn) ||
! 			!SSL_set_fd(conn->ssl, conn->sock))
! 		{
! 			char	   *err = SSLerrmessage();
! 
! 			printfPQExpBuffer(&conn->errorMessage,
! 				   libpq_gettext("could not establish SSL connection: %s\n"),
! 							  err);
! 			SSLerrfree(err);
! 			close_SSL(conn);
! 			return PGRES_POLLING_FAILED;
! 		}
! 
! 		/*
! 		 * Initialize errorMessage to empty.  This allows open_client_SSL() to
! 		 * detect whether client_cert_cb() has stored a message.
! 		 */
! 		resetPQExpBuffer(&conn->errorMessage);
  	}
  	/* Begin or continue the actual handshake */
! 	return open_client_SSL(conn);
  #else
  	/* shouldn't get here */
  	return PGRES_POLLING_FAILED;
--- 160,171 ----
  	/* First time through? */
  	if (conn->ssl == NULL)
  	{
! 		PostgresPollingStatusType status = pqTLS_initconn(conn);
! 		if( status != PGRES_POLLING_OK )
! 			return status;
  	}
  	/* Begin or continue the actual handshake */
! 	return pqTLS_open_client(conn);
  #else
  	/* shouldn't get here */
  	return PGRES_POLLING_FAILED;
***************
*** 241,247 ****
  {
  #ifdef USE_SSL
  	if (conn->ssl)
! 		close_SSL(conn);
  #endif
  }
  
--- 180,186 ----
  {
  #ifdef USE_SSL
  	if (conn->ssl)
! 		pqTLS_close(conn);
  #endif
  }
  
***************
*** 255,321 ****
  
  #ifdef USE_SSL
  	if (conn->ssl)
! 	{
! 		int			err;
! 
! rloop:
! 		n = SSL_read(conn->ssl, ptr, len);
! 		err = SSL_get_error(conn->ssl, n);
! 		switch (err)
! 		{
! 			case SSL_ERROR_NONE:
! 				break;
! 			case SSL_ERROR_WANT_READ:
! 				n = 0;
! 				break;
! 			case SSL_ERROR_WANT_WRITE:
! 
! 				/*
! 				 * Returning 0 here would cause caller to wait for read-ready,
! 				 * which is not correct since what SSL wants is wait for
! 				 * write-ready.  The former could get us stuck in an infinite
! 				 * wait, so don't risk it; busy-loop instead.
! 				 */
! 				goto rloop;
! 			case SSL_ERROR_SYSCALL:
! 				{
! 					char		sebuf[256];
! 
! 					if (n == -1)
! 						printfPQExpBuffer(&conn->errorMessage,
! 									libpq_gettext("SSL SYSCALL error: %s\n"),
! 							SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
! 					else
! 					{
! 						printfPQExpBuffer(&conn->errorMessage,
! 						 libpq_gettext("SSL SYSCALL error: EOF detected\n"));
! 
! 						SOCK_ERRNO_SET(ECONNRESET);
! 						n = -1;
! 					}
! 					break;
! 				}
! 			case SSL_ERROR_SSL:
! 				{
! 					char	   *err = SSLerrmessage();
! 
! 					printfPQExpBuffer(&conn->errorMessage,
! 									  libpq_gettext("SSL error: %s\n"), err);
! 					SSLerrfree(err);
! 				}
! 				/* fall through */
! 			case SSL_ERROR_ZERO_RETURN:
! 				SOCK_ERRNO_SET(ECONNRESET);
! 				n = -1;
! 				break;
! 			default:
! 				printfPQExpBuffer(&conn->errorMessage,
! 						  libpq_gettext("unrecognized SSL error code: %d\n"),
! 								  err);
! 				n = -1;
! 				break;
! 		}
! 	}
  	else
  #endif
  		n = recv(conn->sock, ptr, len, 0);
--- 194,200 ----
  
  #ifdef USE_SSL
  	if (conn->ssl)
! 		n = pqTLS_read( conn, ptr, len );
  	else
  #endif
  		n = recv(conn->sock, ptr, len, 0);
***************
*** 331,341 ****
  {
  	ssize_t		n;
  
  #ifndef WIN32
  #ifdef ENABLE_THREAD_SAFETY
  	sigset_t	osigmask;
  	bool		sigpipe_pending;
- 	bool		got_epipe = false;
  
  
  	if (pq_block_sigpipe(&osigmask, &sigpipe_pending) < 0)
--- 210,220 ----
  {
  	ssize_t		n;
  
+ 	bool		got_epipe = false;
  #ifndef WIN32
  #ifdef ENABLE_THREAD_SAFETY
  	sigset_t	osigmask;
  	bool		sigpipe_pending;
  
  
  	if (pq_block_sigpipe(&osigmask, &sigpipe_pending) < 0)
***************
*** 347,417 ****
  
  #ifdef USE_SSL
  	if (conn->ssl)
! 	{
! 		int			err;
! 
! 		n = SSL_write(conn->ssl, ptr, len);
! 		err = SSL_get_error(conn->ssl, n);
! 		switch (err)
! 		{
! 			case SSL_ERROR_NONE:
! 				break;
! 			case SSL_ERROR_WANT_READ:
! 
! 				/*
! 				 * Returning 0 here causes caller to wait for write-ready,
! 				 * which is not really the right thing, but it's the best we
! 				 * can do.
! 				 */
! 				n = 0;
! 				break;
! 			case SSL_ERROR_WANT_WRITE:
! 				n = 0;
! 				break;
! 			case SSL_ERROR_SYSCALL:
! 				{
! 					char		sebuf[256];
! 
! 					if (n == -1)
! 					{
! #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
! 						if (SOCK_ERRNO == EPIPE)
! 							got_epipe = true;
! #endif
! 						printfPQExpBuffer(&conn->errorMessage,
! 									libpq_gettext("SSL SYSCALL error: %s\n"),
! 							SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
! 					}
! 					else
! 					{
! 						printfPQExpBuffer(&conn->errorMessage,
! 						 libpq_gettext("SSL SYSCALL error: EOF detected\n"));
! 						SOCK_ERRNO_SET(ECONNRESET);
! 						n = -1;
! 					}
! 					break;
! 				}
! 			case SSL_ERROR_SSL:
! 				{
! 					char	   *err = SSLerrmessage();
! 
! 					printfPQExpBuffer(&conn->errorMessage,
! 									  libpq_gettext("SSL error: %s\n"), err);
! 					SSLerrfree(err);
! 				}
! 				/* fall through */
! 			case SSL_ERROR_ZERO_RETURN:
! 				SOCK_ERRNO_SET(ECONNRESET);
! 				n = -1;
! 				break;
! 			default:
! 				printfPQExpBuffer(&conn->errorMessage,
! 						  libpq_gettext("unrecognized SSL error code: %d\n"),
! 								  err);
! 				n = -1;
! 				break;
! 		}
! 	}
  	else
  #endif
  	{
--- 226,232 ----
  
  #ifdef USE_SSL
  	if (conn->ssl)
! 		n = pqTLS_write(conn, ptr, len, &got_epipe);
  	else
  #endif
  	{
***************
*** 433,1036 ****
  	return n;
  }
  
- /* ------------------------------------------------------------ */
- /*						  SSL specific code						*/
- /* ------------------------------------------------------------ */
- #ifdef USE_SSL
- 
- /*
-  *	Certificate verification callback
-  *
-  *	This callback allows us to log intermediate problems during
-  *	verification, but there doesn't seem to be a clean way to get
-  *	our PGconn * structure.  So we can't log anything!
-  *
-  *	This callback also allows us to override the default acceptance
-  *	criteria (e.g., accepting self-signed or expired certs), but
-  *	for now we accept the default checks.
-  */
- static int
- verify_cb(int ok, X509_STORE_CTX *ctx)
- {
- 	return ok;
- }
- 
- #ifdef NOT_USED
  /*
!  *	Verify that common name resolves to peer.
   */
! static int
! verify_peer(PGconn *conn)
! {
! 	struct hostent *h = NULL;
! 	struct sockaddr addr;
! 	struct sockaddr_in *sin;
! 	ACCEPT_TYPE_ARG3 len;
! 	char	  **s;
! 	unsigned long l;
! 
! 	/* get the address on the other side of the socket */
! 	len = sizeof(addr);
! 	if (getpeername(conn->sock, &addr, &len) == -1)
! 	{
! 		char		sebuf[256];
! 
! 		printfPQExpBuffer(&conn->errorMessage,
! 						  libpq_gettext("error querying socket: %s\n"),
! 						  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
! 		return -1;
! 	}
! 
! 	/* weird, but legal case */
! 	if (addr.sa_family == AF_UNIX)
! 		return 0;
! 
! 	{
! 		struct hostent hpstr;
! 		char		buf[BUFSIZ];
! 		int			herrno = 0;
! 
! 		/*
! 		 * Currently, pqGethostbyname() is used only on platforms that don't
! 		 * have getaddrinfo().	If you enable this function, you should
! 		 * convert the pqGethostbyname() function call to use getaddrinfo().
! 		 */
! 		pqGethostbyname(conn->peer_cn, &hpstr, buf, sizeof(buf),
! 						&h, &herrno);
! 	}
! 
! 	/* what do we know about the peer's common name? */
! 	if (h == NULL)
! 	{
! 		printfPQExpBuffer(&conn->errorMessage,
! 		  libpq_gettext("could not get information about host \"%s\": %s\n"),
! 						  conn->peer_cn, hstrerror(h_errno));
! 		return -1;
! 	}
! 
! 	/* does the address match? */
! 	switch (addr.sa_family)
! 	{
! 		case AF_INET:
! 			sin = (struct sockaddr_in *) & addr;
! 			for (s = h->h_addr_list; *s != NULL; s++)
! 			{
! 				if (!memcmp(&sin->sin_addr.s_addr, *s, h->h_length))
! 					return 0;
! 			}
! 			break;
! 
! 		default:
! 			printfPQExpBuffer(&conn->errorMessage,
! 							  libpq_gettext("unsupported protocol\n"));
! 			return -1;
! 	}
! 
! 	/*
! 	 * the prior test should be definitive, but in practice it sometimes
! 	 * fails.  So we also check the aliases.
! 	 */
! 	for (s = h->h_aliases; *s != NULL; s++)
! 	{
! 		if (pg_strcasecmp(conn->peer_cn, *s) == 0)
! 			return 0;
! 	}
! 
! 	/* generate protocol-aware error message */
! 	switch (addr.sa_family)
! 	{
! 		case AF_INET:
! 			sin = (struct sockaddr_in *) & addr;
! 			l = ntohl(sin->sin_addr.s_addr);
! 			printfPQExpBuffer(&conn->errorMessage,
! 							  libpq_gettext(
! 											"server common name \"%s\" does not resolve to %ld.%ld.%ld.%ld\n"),
! 						 conn->peer_cn, (l >> 24) % 0x100, (l >> 16) % 0x100,
! 							  (l >> 8) % 0x100, l % 0x100);
! 			break;
! 		default:
! 			printfPQExpBuffer(&conn->errorMessage,
! 							  libpq_gettext(
! 			 "server common name \"%s\" does not resolve to peer address\n"),
! 							  conn->peer_cn);
! 	}
! 
! 	return -1;
! }
! #endif   /* NOT_USED */
! 
! /*
!  *	Callback used by SSL to load client cert and key.
!  *	This callback is only called when the server wants a
!  *	client cert.
!  *
!  *	Must return 1 on success, 0 on no data or error.
!  */
! static int
! client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
! {
! 	char		homedir[MAXPGPATH];
! 	struct stat buf;
! 
! #ifndef WIN32
! 	struct stat buf2;
! #endif
! 	char		fnbuf[MAXPGPATH];
! 	FILE	   *fp;
! 	PGconn	   *conn = (PGconn *) SSL_get_app_data(ssl);
! 	int			(*cb) () = NULL;	/* how to read user password */
! 	char		sebuf[256];
! 
! 	if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
! 	{
! 		printfPQExpBuffer(&conn->errorMessage,
! 						  libpq_gettext("could not get user information\n"));
! 		return 0;
! 	}
! 
! 	/* read the user certificate */
! 	snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_CERT_FILE);
! 	if ((fp = fopen(fnbuf, "r")) == NULL)
! 	{
! 		printfPQExpBuffer(&conn->errorMessage,
! 			   libpq_gettext("could not open certificate file \"%s\": %s\n"),
! 						  fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
! 		return 0;
! 	}
! 	if (PEM_read_X509(fp, x509, NULL, NULL) == NULL)
! 	{
! 		char	   *err = SSLerrmessage();
! 
! 		printfPQExpBuffer(&conn->errorMessage,
! 			   libpq_gettext("could not read certificate file \"%s\": %s\n"),
! 						  fnbuf, err);
! 		SSLerrfree(err);
! 		fclose(fp);
! 		return 0;
! 	}
! 	fclose(fp);
! 
! 	/* read the user key */
! 	snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_KEY_FILE);
! 	if (stat(fnbuf, &buf) == -1)
! 	{
! 		printfPQExpBuffer(&conn->errorMessage,
! 						  libpq_gettext("certificate present, but not private key file \"%s\"\n"),
! 						  fnbuf);
! 		return 0;
! 	}
! #ifndef WIN32
! 	if (!S_ISREG(buf.st_mode) || (buf.st_mode & 0077) ||
! 		buf.st_uid != geteuid())
! 	{
! 		printfPQExpBuffer(&conn->errorMessage,
! 			libpq_gettext("private key file \"%s\" has wrong permissions\n"),
! 						  fnbuf);
! 		return 0;
! 	}
! #endif
! 	if ((fp = fopen(fnbuf, "r")) == NULL)
! 	{
! 		printfPQExpBuffer(&conn->errorMessage,
! 			   libpq_gettext("could not open private key file \"%s\": %s\n"),
! 						  fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
! 		return 0;
! 	}
! #ifndef WIN32
! 	if (fstat(fileno(fp), &buf2) == -1 ||
! 		buf.st_dev != buf2.st_dev || buf.st_ino != buf2.st_ino)
! 	{
! 		printfPQExpBuffer(&conn->errorMessage,
! 						  libpq_gettext("private key file \"%s\" changed during execution\n"), fnbuf);
! 		return 0;
! 	}
! #endif
! 	if (PEM_read_PrivateKey(fp, pkey, cb, NULL) == NULL)
! 	{
! 		char	   *err = SSLerrmessage();
! 
! 		printfPQExpBuffer(&conn->errorMessage,
! 			   libpq_gettext("could not read private key file \"%s\": %s\n"),
! 						  fnbuf, err);
! 		SSLerrfree(err);
! 		fclose(fp);
! 		return 0;
! 	}
! 	fclose(fp);
! 
! 	/* verify that the cert and key go together */
! 	if (!X509_check_private_key(*x509, *pkey))
! 	{
! 		char	   *err = SSLerrmessage();
! 
! 		printfPQExpBuffer(&conn->errorMessage,
! 						  libpq_gettext("certificate does not match private key file \"%s\": %s\n"),
! 						  fnbuf, err);
! 		SSLerrfree(err);
! 		return 0;
! 	}
! 
! 	return 1;
! }
! 
! #ifdef ENABLE_THREAD_SAFETY
! 
! static unsigned long
! pq_threadidcallback(void)
! {
! 	/*
! 	 * This is not starndard-compliant.  pthread_self() returns pthread_t, and
! 	 * shouldn't be cast to unsigned long, but CRYPTO_set_id_callback requires
! 	 * it, so we have to do it.
! 	 */
! 	return (unsigned long) pthread_self();
! }
! 
! static pthread_mutex_t *pq_lockarray;
! 
! static void
! pq_lockingcallback(int mode, int n, const char *file, int line)
! {
! 	if (mode & CRYPTO_LOCK)
! 		pthread_mutex_lock(&pq_lockarray[n]);
! 	else
! 		pthread_mutex_unlock(&pq_lockarray[n]);
! }
! #endif   /* ENABLE_THREAD_SAFETY */
! 
! static int
! init_ssl_system(PGconn *conn)
! {
! #ifdef ENABLE_THREAD_SAFETY
! #ifndef WIN32
! 	static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
! #else
! 	static pthread_mutex_t init_mutex = NULL;
! 	static long mutex_initlock = 0;
! 
! 	if (init_mutex == NULL)
! 	{
! 		while (InterlockedExchange(&mutex_initlock, 1) == 1)
! 			 /* loop, another thread own the lock */ ;
! 		if (init_mutex == NULL)
! 			pthread_mutex_init(&init_mutex, NULL);
! 		InterlockedExchange(&mutex_initlock, 0);
! 	}
! #endif
! 	pthread_mutex_lock(&init_mutex);
! 
! 	if (pq_initssllib && pq_lockarray == NULL)
! 	{
! 		int			i;
! 
! 		CRYPTO_set_id_callback(pq_threadidcallback);
! 
! 		pq_lockarray = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
! 		if (!pq_lockarray)
! 		{
! 			pthread_mutex_unlock(&init_mutex);
! 			return -1;
! 		}
! 		for (i = 0; i < CRYPTO_num_locks(); i++)
! 			pthread_mutex_init(&pq_lockarray[i], NULL);
! 
! 		CRYPTO_set_locking_callback(pq_lockingcallback);
! 	}
! #endif
! 	if (!SSL_context)
! 	{
! 		if (pq_initssllib)
! 		{
! 			SSL_library_init();
! 			SSL_load_error_strings();
! 		}
! 		SSL_context = SSL_CTX_new(TLSv1_method());
! 		if (!SSL_context)
! 		{
! 			char	   *err = SSLerrmessage();
! 
! 			printfPQExpBuffer(&conn->errorMessage,
! 						 libpq_gettext("could not create SSL context: %s\n"),
! 							  err);
! 			SSLerrfree(err);
! #ifdef ENABLE_THREAD_SAFETY
! 			pthread_mutex_unlock(&init_mutex);
! #endif
! 			return -1;
! 		}
! 	}
! #ifdef ENABLE_THREAD_SAFETY
! 	pthread_mutex_unlock(&init_mutex);
! #endif
! 	return 0;
! }
! 
! /*
!  *	Initialize global SSL context.
!  */
! static int
! initialize_SSL(PGconn *conn)
! {
! 	struct stat buf;
! 	char		homedir[MAXPGPATH];
! 	char		fnbuf[MAXPGPATH];
! 
! 	if (init_ssl_system(conn))
! 		return -1;
! 
! 	/* Set up to verify server cert, if root.crt is present */
! 	if (pqGetHomeDirectory(homedir, sizeof(homedir)))
! 	{
! 		snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CERT_FILE);
! 		if (stat(fnbuf, &buf) == 0)
! 		{
! 			if (!SSL_CTX_load_verify_locations(SSL_context, fnbuf, NULL))
! 			{
! 				char	   *err = SSLerrmessage();
! 
! 				printfPQExpBuffer(&conn->errorMessage,
! 								  libpq_gettext("could not read root certificate file \"%s\": %s\n"),
! 								  fnbuf, err);
! 				SSLerrfree(err);
! 				return -1;
! 			}
! 
! 			SSL_CTX_set_verify(SSL_context, SSL_VERIFY_PEER, verify_cb);
! 		}
! 	}
! 
! 	/* set up mechanism to provide client certificate, if available */
! 	SSL_CTX_set_client_cert_cb(SSL_context, client_cert_cb);
! 
! 	return 0;
! }
! 
! /*
!  *	Destroy global SSL context.
!  */
! static void
! destroy_SSL(void)
! {
! 	if (SSL_context)
! 	{
! 		SSL_CTX_free(SSL_context);
! 		SSL_context = NULL;
! 	}
! }
! 
! /*
!  *	Attempt to negotiate SSL connection.
!  */
! static PostgresPollingStatusType
! open_client_SSL(PGconn *conn)
  {
! 	int			r;
! 
! 	r = SSL_connect(conn->ssl);
! 	if (r <= 0)
! 	{
! 		int			err = SSL_get_error(conn->ssl, r);
! 
! 		switch (err)
! 		{
! 			case SSL_ERROR_WANT_READ:
! 				return PGRES_POLLING_READING;
! 
! 			case SSL_ERROR_WANT_WRITE:
! 				return PGRES_POLLING_WRITING;
! 
! 			case SSL_ERROR_SYSCALL:
! 				{
! 					char		sebuf[256];
! 
! 					if (r == -1)
! 						printfPQExpBuffer(&conn->errorMessage,
! 									libpq_gettext("SSL SYSCALL error: %s\n"),
! 							SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
! 					else
! 						printfPQExpBuffer(&conn->errorMessage,
! 						 libpq_gettext("SSL SYSCALL error: EOF detected\n"));
! 					close_SSL(conn);
! 					return PGRES_POLLING_FAILED;
! 				}
! 			case SSL_ERROR_SSL:
! 				{
! 					/*
! 					 * If there are problems with the local certificate files,
! 					 * these will be detected by client_cert_cb() which is
! 					 * called from SSL_connect().  We want to return that
! 					 * error message and not the rather unhelpful error that
! 					 * OpenSSL itself returns.	So check to see if an error
! 					 * message was already stored.
! 					 */
! 					if (conn->errorMessage.len == 0)
! 					{
! 						char	   *err = SSLerrmessage();
! 
! 						printfPQExpBuffer(&conn->errorMessage,
! 										  libpq_gettext("SSL error: %s\n"),
! 										  err);
! 						SSLerrfree(err);
! 					}
! 					close_SSL(conn);
! 					return PGRES_POLLING_FAILED;
! 				}
! 
! 			default:
! 				printfPQExpBuffer(&conn->errorMessage,
! 						  libpq_gettext("unrecognized SSL error code: %d\n"),
! 								  err);
! 				close_SSL(conn);
! 				return PGRES_POLLING_FAILED;
! 		}
! 	}
! 
! 	/* check the certificate chain of the server */
! 
! #ifdef NOT_USED
! 	/* CLIENT CERTIFICATES NOT REQUIRED  bjm 2002-09-26 */
! 
! 	/*
! 	 * this eliminates simple man-in-the-middle attacks and simple
! 	 * impersonations
! 	 */
! 	r = SSL_get_verify_result(conn->ssl);
! 	if (r != X509_V_OK)
! 	{
! 		printfPQExpBuffer(&conn->errorMessage,
! 				   libpq_gettext("certificate could not be validated: %s\n"),
! 						  X509_verify_cert_error_string(r));
! 		close_SSL(conn);
! 		return PGRES_POLLING_FAILED;
! 	}
! #endif
! 
! 	/* pull out server distinguished and common names */
! 	conn->peer = SSL_get_peer_certificate(conn->ssl);
! 	if (conn->peer == NULL)
! 	{
! 		char	   *err = SSLerrmessage();
! 
! 		printfPQExpBuffer(&conn->errorMessage,
! 					libpq_gettext("certificate could not be obtained: %s\n"),
! 						  err);
! 		SSLerrfree(err);
! 		close_SSL(conn);
! 		return PGRES_POLLING_FAILED;
! 	}
! 
! 	X509_NAME_oneline(X509_get_subject_name(conn->peer),
! 					  conn->peer_dn, sizeof(conn->peer_dn));
! 	conn->peer_dn[sizeof(conn->peer_dn) - 1] = '\0';
! 
! 	X509_NAME_get_text_by_NID(X509_get_subject_name(conn->peer),
! 							  NID_commonName, conn->peer_cn, SM_USER);
! 	conn->peer_cn[SM_USER] = '\0';
! 
! 	/* verify that the common name resolves to peer */
! 
! #ifdef NOT_USED
! 	/* CLIENT CERTIFICATES NOT REQUIRED  bjm 2002-09-26 */
! 
! 	/*
! 	 * this is necessary to eliminate man-in-the-middle attacks and
! 	 * impersonations where the attacker somehow learned the server's private
! 	 * key
! 	 */
! 	if (verify_peer(conn) == -1)
! 	{
! 		close_SSL(conn);
! 		return PGRES_POLLING_FAILED;
! 	}
  #endif
! 
! 	/* SSL handshake is complete */
! 	return PGRES_POLLING_OK;
! }
! 
! /*
!  *	Close SSL connection.
!  */
! static void
! close_SSL(PGconn *conn)
! {
! 	if (conn->ssl)
! 	{
! 		SSL_shutdown(conn->ssl);
! 		SSL_free(conn->ssl);
! 		conn->ssl = NULL;
! 	}
! 
! 	if (conn->peer)
! 	{
! 		X509_free(conn->peer);
! 		conn->peer = NULL;
! 	}
! }
! 
! /*
!  * Obtain reason string for last SSL error
!  *
!  * Some caution is needed here since ERR_reason_error_string will
!  * return NULL if it doesn't recognize the error code.  We don't
!  * want to return NULL ever.
!  */
! static char ssl_nomem[] = "Out of memory allocating error description";
! 
! #define SSL_ERR_LEN 128
! 
! static char *
! SSLerrmessage(void)
! {
! 	unsigned long errcode;
! 	const char *errreason;
! 	char	   *errbuf;
! 
! 	errbuf = malloc(SSL_ERR_LEN);
! 	if (!errbuf)
! 		return ssl_nomem;
! 	errcode = ERR_get_error();
! 	if (errcode == 0)
! 	{
! 		strcpy(errbuf, "No SSL error reported");
! 		return errbuf;
! 	}
! 	errreason = ERR_reason_error_string(errcode);
! 	if (errreason != NULL)
! 	{
! 		strncpy(errbuf, errreason, SSL_ERR_LEN - 1);
! 		errbuf[SSL_ERR_LEN - 1] = '\0';
! 		return errbuf;
! 	}
! 	snprintf(errbuf, SSL_ERR_LEN, "SSL error code %lu", errcode);
! 	return errbuf;
! }
! 
! static void
! SSLerrfree(char *buf)
! {
! 	if (buf != ssl_nomem)
! 		free(buf);
! }
! 
! /*
!  *	Return pointer to OpenSSL object.
!  */
! void *
! PQgetssl(PGconn *conn)
! {
! 	if (!conn)
! 		return NULL;
! 	return conn->ssl;
! }
! #else							/* !USE_SSL */
! 
! void *
! PQgetssl(PGconn *conn)
! {
! 	return NULL;
  }
- #endif   /* USE_SSL */
  
  #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
  
--- 248,265 ----
  	return n;
  }
  
  /*
!  *	Returns true if the SSL connection has bytes to read
   */
! int
! pqsecure_pending(PGconn *conn)
  {
! #ifdef USE_SSL
!         if(conn->ssl)
!                 return pqTLS_pending(conn);
  #endif
!         return 0;
  }
  
  #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
  
***************
*** 1117,1119 ****
--- 346,493 ----
  }
  
  #endif   /* ENABLE_THREAD_SAFETY */
+ /* ------------------------------------------------------------ */
+ /*						  SSL public interface stub definitions						*/
+ /* ------------------------------------------------------------ */
+ 
+ #ifndef USE_SSL
+ /*
+  *      Return pointer to SSL object.
+  *
+  *	Normally defined in the file proving SSL service but if no SSL is compiled in we defined the function here
+  */
+  
+ void *
+ PQgetssl(PGconn *conn)
+ {
+ 	return NULL;
+ }
+ /*
+  *	Exported function to allow application to tell us it's already
+  *	initialized OpenSSL. Does nothing in the no-SSL case.
+  */
+ void
+ PQinitSSL(int do_init)
+ {
+ }
+ 
+ #endif   /* USE_SSL */
+ 
+ void 
+ pqsecure_tlsinfo_add_row( PGresult *res, const char *key, const char *value )
+ {
+ 	PGresAttValue *row = pqResultAlloc( res, sizeof( PGresAttValue ) * 2, false );
+ 	
+ 	row[0].value = pqResultStrdup( res, key );
+ 	row[0].len = strlen(key);
+ 	row[1].value = pqResultStrdup( res, value );
+ 	row[1].len = strlen(value);
+ 	
+ 	pqAddTuple( res, row );
+ }
+ 
+ 
+ PGresult *
+ PQgettlsinfo(PGconn *conn)
+ {
+ #ifdef USE_SSL
+ 	PGresult *res = PQmakeEmptyPGresult( conn, PGRES_TUPLES_OK );
+ 	res->numAttributes = 2;
+ 	res->attDescs = (PGresAttDesc *) pqResultAlloc(res, 2 * sizeof(PGresAttDesc), TRUE);
+ 	memset( res->attDescs, 0, 2 * sizeof(PGresAttDesc) );
+ 	res->attDescs[0].name = pqResultStrdup( res, "key" );
+ 	res->attDescs[0].format = 0;
+ 	res->attDescs[0].typid = 25;
+ 	res->attDescs[0].typlen = -1;
+ 	res->attDescs[0].format = 0;
+ 	res->attDescs[1].name = pqResultStrdup( res, "value" );
+ 	res->attDescs[1].format = 0;
+ 	res->attDescs[1].typid = 25;
+ 	res->attDescs[1].typlen = -1;
+ 	res->attDescs[1].format = 0;
+ 	
+ 	return pqTLS_gettlsinfo( conn, res );
+ #else
+         return NULL;
+ #endif
+ }
+ 
+ static PostgresPollingStatusType
+ pq_pt_read(PGconn *conn, void *buf, int *len)
+ {
+         size_t s;
+         
+         if( conn->status != CONNECTION_PASSTHROUGH )
+                 return PGRES_POLLING_FAILED;
+         
+ retry_read:
+         s = pqsecure_read(conn, buf, *len);
+         if( s < 0 )
+         {
+                 *len = 0;
+                 switch( SOCK_ERRNO )
+                 {
+                         case EINTR:
+                                 goto retry_read;
+ #ifdef EAGAIN
+                         case EAGAIN:
+                                 return PGRES_POLLING_READING;
+ #endif
+ #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EAGAIN != EWOULDBLOCK))
+                         case EWOULDBLOCK:
+                                 return PGRES_POLLING_READING;
+ #endif
+                         default:
+                                 return PGRES_POLLING_FAILED;
+                 }
+         }
+         else
+         {
+                 *len = s;
+                 return PGRES_POLLING_OK;
+         }
+ } 
+ 
+ static PostgresPollingStatusType
+ pq_pt_write(PGconn *conn, const void *buf, int *len)
+ {
+         size_t s;
+         
+         if( conn->status != CONNECTION_PASSTHROUGH )
+                 return PGRES_POLLING_FAILED;
+         
+ retry_write:
+         s = pqsecure_write(conn, buf, *len);
+         if( s < 0 )
+         {
+                 *len = 0;
+                 switch( SOCK_ERRNO )
+                 {
+                         case EINTR:
+                                 goto retry_write;
+ #ifdef EAGAIN
+                         case EAGAIN:
+                                 return PGRES_POLLING_WRITING;
+ #endif
+ #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EAGAIN != EWOULDBLOCK))
+                         case EWOULDBLOCK:
+                                 return PGRES_POLLING_WRITING;
+ #endif
+                         default:
+                                 return PGRES_POLLING_FAILED;
+                 }
+         }
+         else
+         {
+                 *len = s;
+                 return PGRES_POLLING_OK;
+         }
+ } 
+ 
+ void
+ pqsecure_pt_setup( PQpassthrough *state )
+ {
+         state->read = pq_pt_read;
+         state->write = pq_pt_write;
+         state->pending = pqsecure_pending;
+ }
Index: src/interfaces/libpq/libpq-fe.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/interfaces/libpq/libpq-fe.h,v
retrieving revision 1.127
diff -c -r1.127 libpq-fe.h
*** src/interfaces/libpq/libpq-fe.h	27 Apr 2006 00:53:58 -0000	1.127
--- src/interfaces/libpq/libpq-fe.h	4 May 2006 13:35:54 -0000
***************
*** 53,59 ****
  								 * backend startup. */
  	CONNECTION_SETENV,			/* Negotiating environment. */
  	CONNECTION_SSL_STARTUP,		/* Negotiating SSL. */
! 	CONNECTION_NEEDED			/* Internal state: connect() needed */
  } ConnStatusType;
  
  typedef enum
--- 53,61 ----
  								 * backend startup. */
  	CONNECTION_SETENV,			/* Negotiating environment. */
  	CONNECTION_SSL_STARTUP,		/* Negotiating SSL. */
! 	CONNECTION_NEEDED,			/* Internal state: connect() needed */
! 	
! 	CONNECTION_PASSTHROUGH,		/* Connection set for pass-through mode */
  } ConnStatusType;
  
  typedef enum
***************
*** 270,278 ****
--- 272,304 ----
   * unencrypted connections or if any other TLS library is in use. */
  extern void *PQgetssl(PGconn *conn);
  
+ /* Get data about current TLS connection */
+ extern PGresult *PQgettlsinfo(PGconn *conn);
+ 
  /* Tell libpq whether it needs to initialize OpenSSL */
  extern void PQinitSSL(int do_init);
  
+ /* Tell libpq we're taking over the connection. After this, no normal
+  * queries may be sent anymore. When finished you may close the connection */
+ typedef PostgresPollingStatusType (*pq_read_func)( PGconn *conn, void *buf, int *len);
+ typedef PostgresPollingStatusType (*pq_write_func)( PGconn *conn, const void *buf, int *len);
+ typedef int (*pq_pending_func)( PGconn *conn );
+ 
+ typedef struct {
+   int len;       /* Length of this structure, so users may determine if the
+                     info they require is there. For backward compatability,
+                     new members can only be added to the end. */
+   pq_read_func read;
+   pq_write_func write;
+   pq_pending_func pending;
+ 
+ /*  char *ssllibname;   Need not yet demonstrated. */
+ /*  void *sslptr;     */
+ } PQpassthrough;
+ 
+ /* The pointer returned in state must be freed with PQfreemem() */
+ extern int PQsetPassthrough(PGconn *conn, PQpassthrough **state );
+ 
  /* Set verbosity for PQerrorMessage and PQresultErrorMessage */
  extern PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity);
  
Index: src/interfaces/libpq/libpq-int.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/interfaces/libpq/libpq-int.h,v
retrieving revision 1.112
diff -c -r1.112 libpq-int.h
*** src/interfaces/libpq/libpq-int.h	14 Mar 2006 22:48:23 -0000	1.112
--- src/interfaces/libpq/libpq-int.h	4 May 2006 13:35:54 -0000
***************
*** 49,59 ****
  /* include stuff found in fe only */
  #include "pqexpbuffer.h"
  
- #ifdef USE_SSL
- #include <openssl/ssl.h>
- #include <openssl/err.h>
- #endif
- 
  /*
   * POSTGRES backend dependent Constants.
   */
--- 49,54 ----
***************
*** 337,344 ****
  	bool		allow_ssl_try;	/* Allowed to try SSL negotiation */
  	bool		wait_ssl_try;	/* Delay SSL negotiation until after
  								 * attempting normal connection */
! 	SSL		   *ssl;			/* SSL status, if have SSL connection */
! 	X509	   *peer;			/* X509 cert of server */
  	char		peer_dn[256 + 1];		/* peer distinguished name */
  	char		peer_cn[SM_USER + 1];	/* peer common name */
  #endif
--- 332,338 ----
  	bool		allow_ssl_try;	/* Allowed to try SSL negotiation */
  	bool		wait_ssl_try;	/* Delay SSL negotiation until after
  								 * attempting normal connection */
! 	void *ssl;			/* SSL status, if have SSL connection */
  	char		peer_dn[256 + 1];		/* peer distinguished name */
  	char		peer_cn[SM_USER + 1];	/* peer common name */
  #endif
***************
*** 479,484 ****
--- 473,481 ----
  extern void pqsecure_close(PGconn *);
  extern ssize_t pqsecure_read(PGconn *, void *ptr, size_t len);
  extern ssize_t pqsecure_write(PGconn *, const void *ptr, size_t len);
+ extern int pqsecure_pending(PGconn *);
+ extern void pqsecure_tlsinfo_add_row(PGresult *res, const char *key, const char *value);
+ extern void pqsecure_pt_setup( PQpassthrough *state );
  
  #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
  extern int	pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending);
Index: src/backend/libpq/be-secure-gnutls.c
=========================================================================
*** src/backend/libpq/be-secure-gnutls.c.orig	Thu May  4 15:35:59 2006
--- src/backend/libpq/be-secure-gnutls.c	Thu May  4 15:20:50 2006
***************
*** 0 ****
--- 1,511 ----
+ /*-------------------------------------------------------------------------
+  *
+  * be-secure.c
+  *	  functions related to setting up a secure connection to the frontend.
+  *	  Secure connections are expected to provide confidentiality,
+  *	  message integrity and endpoint authentication.
+  *
+  *
+  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  *
+  *
+  * IDENTIFICATION
+  *	  $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.63 2006/03/21 18:18:35 neilc Exp $
+  *
+  *        This file implements the GnuTLS version of the functions needed by be-secure.c
+  *
+  *-------------------------------------------------------------------------
+  */
+ 
+ #include "postgres.h"
+ 
+ #include <sys/stat.h>
+ #include <signal.h>
+ #include <fcntl.h>
+ #include <ctype.h>
+ #include <sys/socket.h>
+ #include <unistd.h>
+ #include <netdb.h>
+ #include <netinet/in.h>
+ #ifdef HAVE_NETINET_TCP_H
+ #include <netinet/tcp.h>
+ #include <arpa/inet.h>
+ #endif
+ 
+ #include <gnutls/gnutls.h>
+ #include <gnutls/x509.h>
+ 
+ /* If thread safety ever becomes an issue for the backend, we will need to
+  * include this. See the frontend code in libpq. */
+ /* #include <gcrypt.h> */
+ 
+ #include "libpq/libpq.h"
+ #include "miscadmin.h"
+ #include "tcop/tcopprot.h"
+ 
+ 
+ #ifdef NOT_USED
+ static int	verify_cb(int, X509_STORE_CTX *);
+ static void info_cb(const SSL *ssl, int type, int args);
+ #endif
+ 
+ static const char *SSLerrmessage(int);
+ 
+ static bool SSL_verify_client;
+ static gnutls_certificate_credentials SSL_cred;  /* Credentials for connecting */
+ /*
+  *	How much data can be sent across a secure connection
+  *	(total in both directions) before we require renegotiation.
+  */
+ #define RENEGOTIATION_LIMIT (512 * 1024 * 1024)
+ 
+ #define DH_BITS 1024
+ 
+ /*
+  *	Read data from a secure connection.
+  */
+ ssize_t
+ pgtls_read(Port *port, void *ptr, size_t len)
+ {
+ 	ssize_t		n;
+ 
+ rloop:
+ 	n = gnutls_record_recv(port->ssl, ptr, len);
+ 	if( n < 0 )
+ 	{
+ 		if( n == GNUTLS_E_INTERRUPTED ||
+ 		    n == GNUTLS_E_AGAIN )
+ 		{
+ #ifdef WIN32
+ 			pgwin32_waitforsinglesocket(gnutls_transport_get_ptr(port->ssl),
+ 							(gnutls_record_get_direction(port->ssl) == 0) ?
+ 							   FD_READ | FD_CLOSE : FD_WRITE | FD_CLOSE);
+ #endif
+ 			goto rloop;
+ 		}
+ 		else
+ 		{
+ 			ereport(COMMERROR,
+ 					(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 					 errmsg("SSL error: %s", SSLerrmessage(n))));
+ 			errno = ECONNRESET;
+ 			n = -1;
+ 		}
+ 	}
+ 	else
+ 		port->count += n;  /* count bytes */
+ 
+ 	return n;
+ }
+ 
+ /*
+  *	Write data to a secure connection.
+  */
+ ssize_t
+ pgtls_write(Port *port, void *ptr, size_t len)
+ {
+ 	ssize_t		n;
+ 
+ 	int			err;
+ 
+ wloop:
+ 	n = gnutls_record_send(port->ssl, ptr, len);
+ 	if( n < 0 )
+ 	{
+ 		if( n == GNUTLS_E_INTERRUPTED ||
+ 		    n == GNUTLS_E_AGAIN )
+ 		{
+ #ifdef WIN32
+ 			pgwin32_waitforsinglesocket(port->sock),
+ 										(gnutls_record_get_direction(port->ssl) == 0) ?
+ 							   FD_READ | FD_CLOSE : FD_WRITE | FD_CLOSE);
+ #endif
+ 			goto wloop;
+ 		}
+ 		else
+ 		{
+ 			ereport(COMMERROR,
+ 						(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 						 errmsg("SSL error: %s", SSLerrmessage(n))));
+ 			errno = ECONNRESET;
+ 			n = -1;
+ 		}
+ 		return n;
+ 	}
+ 	port->count += n;
+ 
+ 	if (port->count > RENEGOTIATION_LIMIT)
+ 	{
+ 		/* Note: we don't allow the user to ignore the renegotiation request. We could... */
+ 		do {
+ 			err = gnutls_rehandshake(port->ssl);
+ 		} while( err == GNUTLS_E_INTERRUPTED || err == GNUTLS_E_AGAIN );
+ 		
+ 		if (err < 0)
+ 		{
+ 			ereport(COMMERROR,
+ 					(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 					 errmsg("SSL renegotiation failure: %s",SSLerrmessage(err))));
+ 			errno = ECONNRESET;
+ 			return -1;
+ 		}
+ 		
+ 		do {
+ 			err = gnutls_handshake(port->ssl);
+ 		} while( err == GNUTLS_E_INTERRUPTED || err == GNUTLS_E_AGAIN );
+ 		
+ 		if (err < 0)
+ 		{
+ 			ereport(COMMERROR,
+ 					(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 					 errmsg("SSL renegotiation failure: %s", SSLerrmessage(err))));
+ 
+ 			errno = ECONNRESET;
+ 			return -1;
+ 		}
+ 		
+ 		port->count = 0;
+ 	}
+ 
+ 	return n;
+ }
+ 
+ /*
+  * Private substitute BIO: this wraps the SSL library's standard socket BIO
+  * so that we can enable and disable interrupts just while calling recv().
+  * We cannot have interrupts occurring while the bulk of openssl runs,
+  * because it uses malloc() and possibly other non-reentrant libc facilities.
+  */
+ 
+ static int
+ gnutls_raw_read(gnutls_transport_ptr fd, void *buf, size_t size)
+ {
+ 	int			res;
+ 
+ 	prepare_for_client_read();
+ 
+ 	res = read((int)fd, buf, size);
+ 
+ 	client_read_ended();
+ 
+ 	return res;
+ }
+ 
+ /*
+  *	Certificate verification callback
+  *
+  *	This callback allows us to log intermediate problems during
+  *	verification, but for now we'll see if the final error message
+  *	contains enough information.
+  *
+  *	This callback also allows us to override the default acceptance
+  *	criteria (e.g., accepting self-signed or expired certs), but
+  *	for now we accept the default checks.
+  */
+ #ifdef NOT_USED
+ static int
+ verify_cb(int ok, X509_STORE_CTX *ctx)
+ {
+ 	return ok;
+ }
+ #endif
+ 
+ /*
+  *	This callback is used to copy SSL information messages
+  *	into the PostgreSQL log.
+  */
+ #ifdef NOT_USED
+ static void
+ info_cb(const SSL *ssl, int type, int args)
+ {
+ }
+ #endif
+ 
+ /*
+  *	Initialize global SSL context. This will be called once, by the postmaster during startup
+  */
+ void
+ pgtls_initialize(void)
+ {
+ 	struct stat buf;
+ 	gnutls_dh_params dh_params;
+ 	int error;
+ 	
+ #ifdef ENABLE_THREAD_SAFETY
+ 	/* GnuTLS is thread-safe by design, but gcrypt may not be. Here we assume that the lib is pthread */
+ 	/* Thread safety not an issue for server */
+ 	/* gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); */
+ #endif
+ 	/* Do gnutls_check_version(LIBGNUTLS_VERSION) ? */
+ 	error = gnutls_global_init();  /* Check for error */
+ 	if( error < 0 )
+ 		ereport(FATAL,
+ 				(errmsg("could not initialize GnuTLS: %s",
+ 						SSLerrmessage(error))));
+ 		
+ 	gnutls_certificate_allocate_credentials (&SSL_cred);
+ 
+ 	if (stat(SERVER_PRIVATE_KEY_FILE, &buf) == -1)
+ 		ereport(FATAL,
+ 				(errcode_for_file_access(),
+ 				 errmsg("could not access private key file \"%s\": %m",
+ 						SERVER_PRIVATE_KEY_FILE)));
+ 
+ 	/*
+ 	 * Require no public access to key file.
+ 	 *
+ 	 * XXX temporarily suppress check when on Windows, because there may
+ 	 * not be proper support for Unix-y file permissions.  Need to think
+ 	 * of a reasonable check to apply on Windows.  (See also the data
+ 	 * directory permission check in postmaster.c)
+ 	 */
+ #if !defined(WIN32) && !defined(__CYGWIN__)
+ 	if (!S_ISREG(buf.st_mode) || (buf.st_mode & (S_IRWXG | S_IRWXO)) ||
+ 		buf.st_uid != geteuid())
+ 		ereport(FATAL,
+ 				(errcode(ERRCODE_CONFIG_FILE_ERROR),
+ 				 errmsg("unsafe permissions on private key file \"%s\"",
+ 						SERVER_PRIVATE_KEY_FILE),
+ 				 errdetail("File must be owned by the database user and must have no permissions for \"group\" or \"other\".")));
+ #endif
+ 
+ 	if( (error = gnutls_certificate_set_x509_key_file( SSL_cred, SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE, GNUTLS_X509_FMT_PEM )) < 0 )
+ 		ereport(FATAL,
+ 				(errmsg("could not load private key/certificate file \"%s\", \"%s\": %s",
+ 						SERVER_PRIVATE_KEY_FILE, SERVER_CERT_FILE, SSLerrmessage(error))));
+ 	
+ 
+ 	/* set up empheral DH keys */
+ #if 0
+ 	gnutls_certificate_set_params_function(SSL_cred, tmp_dh_cb);
+ #else
+ 	gnutls_dh_params_init (&dh_params);
+ 	gnutls_dh_params_generate2 (dh_params, DH_BITS);
+ 	gnutls_certificate_set_dh_params (SSL_cred, dh_params);
+ #endif
+ 
+ 	/* Cannot setup the allowed cipher list, must do that at connection start */
+ 
+ 	/*
+ 	 * Require and check client certificates only if we have a root.crt file.
+ 	 */
+ 	error = gnutls_certificate_set_x509_trust_file (SSL_cred, ROOT_CERT_FILE, GNUTLS_X509_FMT_PEM);
+ 	if ( error < 0 )
+ 	{
+ 		/* Not fatal - we do not require client certificates */
+ 		ereport(LOG,
+ 				(errmsg("could not load root certificate file \"%s\": %s",
+ 						ROOT_CERT_FILE, SSLerrmessage(error)),
+ 				 errdetail("Will not verify client certificates.")));
+ 	}
+ 	else
+ 	{
+ 		SSL_verify_client = TRUE;
+ 		error = gnutls_certificate_set_x509_crl_file (SSL_cred, ROOT_CRL_FILE, GNUTLS_X509_FMT_PEM);
+ 		if ( error < 0 )
+ 		{
+ 			/* Not fatal - we do not require a CRL file */
+ 			ereport(LOG,
+ 					(errmsg("SSL Certificate Revocation List (CRL) file \"%s\" not found, skipping: %s",
+ 							ROOT_CRL_FILE, SSLerrmessage(error)),
+ 					 errdetail("Will not check certificates against CRL.")));
+ 		}
+ 	}
+ 		
+ #ifdef NOT_USED
+ 		/* We don't use a verify function, but if we did, here's where we'd set it */
+ 		SSL_CTX_set_verify(SSL_context,
+ 						   (SSL_VERIFY_PEER |
+ 							SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
+ 							SSL_VERIFY_CLIENT_ONCE),
+ 						   verify_cb);
+ #endif
+ }
+ 
+ /*
+  *	Destroy global SSL context.
+  */
+ void
+ pgtls_destroy(void)
+ {
+ 	gnutls_certificate_free_credentials(SSL_cred);
+ 	SSL_cred = NULL;
+ 	gnutls_global_deinit();
+ }
+ 
+ /*
+  *	Attempt to negotiate SSL connection.
+  */
+ int
+ pgtls_open_server(Port *port)
+ {
+ 	int			err;
+ 	int certcount;
+ 
+ 	const int kx_prio[] = { GNUTLS_KX_DHE_RSA, GNUTLS_KX_DHE_DSS, 0 };
+ 	/* Only do X509 certificates */
+ 	const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
+ 	const int cipher_type_priority[] = { GNUTLS_CIPHER_AES_256_CBC, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_CIPHER_ARCFOUR_128, 0 };
+ 	const int mac_type_priority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_RMD160, 0 };
+ 
+ 	Assert(!port->ssl);
+ 	Assert(!port->peer);
+ 
+ 	err = gnutls_init (&port->ssl, GNUTLS_SERVER);
+ 	if( err < 0 )
+ 	{
+ 		ereport(COMMERROR,
+ 				(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 				 errmsg("could not initialize SSL connection: %s",
+ 						SSLerrmessage(err))));
+ 		pgtls_close(port);
+ 		return -1;
+ 	}
+ 	/* Use default priorities */
+ 	gnutls_set_default_priority (port->ssl);
+ 	/* Server uses: ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH. This means:
+ 	 * - No anonymous DH cipher suites.
+ 	 * - Low security keys
+ 	 * - No export algorithms
+ 	 * - No MD5 */
+ 	gnutls_kx_set_priority (port->ssl, kx_prio);  /* DH keyexchange only */
+ 	gnutls_certificate_type_set_priority (port->ssl, cert_type_priority); /* X.509 certs only */
+ 	gnutls_cipher_set_priority( port->ssl, cipher_type_priority );
+ 	gnutls_mac_set_priority( port->ssl, mac_type_priority );
+ 
+ 	gnutls_transport_set_ptr (port->ssl, (gnutls_transport_ptr) port->sock);
+ 	gnutls_session_set_ptr (port->ssl, port);
+ 	
+ 	/* setup customer read function */
+ 	gnutls_transport_set_pull_function( port->ssl, gnutls_raw_read );
+ 
+ 	/* set up mechanism to provide client certificate, if available */
+ 	gnutls_credentials_set (port->ssl, GNUTLS_CRD_CERTIFICATE, SSL_cred);
+ 	
+ 	/* Set the number of bits for DH */
+ 	gnutls_dh_set_prime_bits (port->ssl, DH_BITS);
+ 
+ 	/* Request a certificate, if any */
+ 	gnutls_certificate_server_set_request (port->ssl, GNUTLS_CERT_REQUEST);
+ 	
+ aloop:
+ 	err = gnutls_handshake (port->ssl);
+ 	if (err < 0)
+ 	{
+ 		if( err == GNUTLS_E_AGAIN ||
+ 		    err == GNUTLS_E_INTERRUPTED )
+ 		{
+ #ifdef WIN32
+ 			pgwin32_waitforsinglesocket(port->sock),
+ 										(gnutls_record_get_direction(port->ssl) == 0) ?
+ 				   FD_READ | FD_CLOSE | FD_ACCEPT : FD_WRITE | FD_CLOSE);
+ #endif
+ 			goto aloop;
+ 		}
+ 		ereport(COMMERROR,
+ 				(errcode_for_socket_access(),
+ 				 errmsg("could not accept SSL connection: %s", SSLerrmessage(err))));
+ 		pgtls_close(port);
+ 		return -1;
+ 	}
+ 
+ 	port->count = 0;
+ 
+ 	/* get server certificate */
+ 	port->peer = gnutls_certificate_get_peers(port->ssl, &certcount);
+ 
+ 	strncpy(port->peer_dn, "(anonymous)", sizeof(port->peer_dn));
+ 	strncpy(port->peer_cn, "(anonymous)", sizeof(port->peer_cn));
+ 
+ 	if( port->peer )
+ 	{
+ 		gnutls_x509_crt cert;
+ 		
+ 		err = gnutls_x509_crt_init (&cert);
+ 		if(err == 0)
+ 			err = gnutls_x509_crt_import (cert, &port->peer[0], GNUTLS_X509_FMT_DER);
+ 		if(err < 0)
+ 		{
+ 			ereport(WARNING,
+ 					 (errmsg("gnutls_x509_crt_import failure: %s\n", SSLerrmessage(err))));
+ 		}
+ 		else
+ 		{
+ 			int size = sizeof(port->peer_dn);
+ 			gnutls_x509_crt_get_dn (cert, port->peer_dn, &size);
+ 			port->peer_dn[sizeof(port->peer_dn) - 1] = '\0';
+ 		
+ 			size = sizeof(port->peer_cn);
+ 			gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME, 0, 0, port->peer_cn, &size );
+ 			port->peer_cn[sizeof(port->peer_cn) - 1] = '\0';
+ 
+ 			gnutls_x509_crt_deinit( cert );
+ 		}
+ 	}
+ 	/* If asked to verify server, do so */
+ 	if( SSL_verify_client )
+ 	{
+ 		int status;
+ 		err = gnutls_certificate_verify_peers2 (port->ssl, &status);
+ 		if(err < 0)
+ 		{
+ 			ereport(COMMERROR, 
+ 					(errmsg("SSL verification error: %s\n", SSLerrmessage(err))));
+ 			pgtls_close(port);
+ 			return -1;
+ 		}
+ 		if( status )
+ 		{
+ 			ereport(COMMERROR,
+ 					(errmsg("Server cert verification failure: %d\n", status)));
+ 			pgtls_close(port);
+ 			return -1;
+ 		}
+ 	}
+ 	ereport(DEBUG2,
+ 			(errmsg("SSL connection from \"%s\"", port->peer_cn)));
+ 
+ #ifdef NOT_USED
+ 	/* set up debugging/info callback */
+ 	SSL_CTX_set_info_callback(SSL_context, info_cb);
+ #endif
+ 
+ 	return 0;
+ }
+ 
+ /*
+  *	Close SSL connection.
+  */
+ void
+ pgtls_close(Port *port)
+ {
+ 	/* Isn't allocated, so don't free */
+ 	if (port->peer)
+ 		port->peer = NULL;
+ 	/* Clear SSL data */
+ 	if (port->ssl)
+ 	{
+ 		gnutls_deinit(port->ssl);
+ 		port->ssl = NULL;
+ 	}
+ 
+ }
+ 
+ /*
+  * Obtain reason string for last SSL error
+  *
+  * gnutls_strerror returns a useful string even if it doesn't recognise the error code
+  */
+ static const char *
+ SSLerrmessage(int errcode)
+ {
+ 	if (errcode == 0)
+ 		return "No SSL error reported";
+ 	/* Error in push/pull function is error in socket send/recv */
+ 	if( errcode == GNUTLS_E_PUSH_ERROR || errcode == GNUTLS_E_PULL_ERROR )
+ 		return strerror(errno);
+ 		
+ 	return gnutls_strerror(errcode);
+ }
+ 
Index: src/backend/libpq/be-secure-openssl.c
=========================================================================
*** src/backend/libpq/be-secure-openssl.c.orig	Thu May  4 15:35:59 2006
--- src/backend/libpq/be-secure-openssl.c	Thu May  4 13:04:32 2006
***************
*** 0 ****
--- 1,839 ----
+ /*-------------------------------------------------------------------------
+  *
+  * be-secure.c
+  *	  functions related to setting up a secure connection to the frontend.
+  *	  Secure connections are expected to provide confidentiality,
+  *	  message integrity and endpoint authentication.
+  *
+  *
+  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  *
+  *
+  * IDENTIFICATION
+  *	  $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.63 2006/03/21 18:18:35 neilc Exp $
+  *
+  *        This file implements the OpenSSL version of the functions needed by be-secure.c
+  *
+  *-------------------------------------------------------------------------
+  */
+ 
+ #include "postgres.h"
+ 
+ #include <sys/stat.h>
+ #include <signal.h>
+ #include <fcntl.h>
+ #include <ctype.h>
+ #include <sys/socket.h>
+ #include <unistd.h>
+ #include <netdb.h>
+ #include <netinet/in.h>
+ #ifdef HAVE_NETINET_TCP_H
+ #include <netinet/tcp.h>
+ #include <arpa/inet.h>
+ #endif
+ 
+ #include <openssl/ssl.h>
+ #include <openssl/dh.h>
+ 
+ #include "libpq/libpq.h"
+ #include "miscadmin.h"
+ #include "tcop/tcopprot.h"
+ 
+ 
+ static DH  *load_dh_file(int keylength);
+ static DH  *load_dh_buffer(const char *, size_t);
+ static DH  *tmp_dh_cb(SSL *s, int is_export, int keylength);
+ static int	verify_cb(int, X509_STORE_CTX *);
+ static void info_cb(const SSL *ssl, int type, int args);
+ static const char *SSLerrmessage(void);
+ 
+ /*
+  *	How much data can be sent across a secure connection
+  *	(total in both directions) before we require renegotiation.
+  */
+ #define RENEGOTIATION_LIMIT (512 * 1024 * 1024)
+ 
+ static SSL_CTX *SSL_context = NULL;
+ 
+ /* ------------------------------------------------------------ */
+ /*						 Hardcoded values						*/
+ /* ------------------------------------------------------------ */
+ 
+ /*
+  *	Hardcoded DH parameters, used in empheral DH keying.
+  *	As discussed above, EDH protects the confidentiality of
+  *	sessions even if the static private key is compromised,
+  *	so we are *highly* motivated to ensure that we can use
+  *	EDH even if the DBA... or an attacker... deletes the
+  *	$DataDir/dh*.pem files.
+  *
+  *	We could refuse SSL connections unless a good DH parameter
+  *	file exists, but some clients may quietly renegotiate an
+  *	unsecured connection without fully informing the user.
+  *	Very uncool.
+  *
+  *	Alternately, the backend could attempt to load these files
+  *	on startup if SSL is enabled - and refuse to start if any
+  *	do not exist - but this would tend to piss off DBAs.
+  *
+  *	If you want to create your own hardcoded DH parameters
+  *	for fun and profit, review "Assigned Number for SKIP
+  *	Protocols" (http://www.skip-vpn.org/spec/numbers.html)
+  *	for suggestions.
+  */
+ 
+ static const char file_dh512[] =
+ "-----BEGIN DH PARAMETERS-----\n\
+ MEYCQQD1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWak\n\
+ XUGfnHy9iUsiGSa6q6Jew1XpKgVfAgEC\n\
+ -----END DH PARAMETERS-----\n";
+ 
+ static const char file_dh1024[] =
+ "-----BEGIN DH PARAMETERS-----\n\
+ MIGHAoGBAPSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsY\n\
+ jY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6\n\
+ ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpL3jHAgEC\n\
+ -----END DH PARAMETERS-----\n";
+ 
+ static const char file_dh2048[] =
+ "-----BEGIN DH PARAMETERS-----\n\
+ MIIBCAKCAQEA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV\n\
+ 89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50\n\
+ T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknb\n\
+ zSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdX\n\
+ Q6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbT\n\
+ CD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwIBAg==\n\
+ -----END DH PARAMETERS-----\n";
+ 
+ static const char file_dh4096[] =
+ "-----BEGIN DH PARAMETERS-----\n\
+ MIICCAKCAgEA+hRyUsFN4VpJ1O8JLcCo/VWr19k3BCgJ4uk+d+KhehjdRqNDNyOQ\n\
+ l/MOyQNQfWXPeGKmOmIig6Ev/nm6Nf9Z2B1h3R4hExf+zTiHnvVPeRBhjdQi81rt\n\
+ Xeoh6TNrSBIKIHfUJWBh3va0TxxjQIs6IZOLeVNRLMqzeylWqMf49HsIXqbcokUS\n\
+ Vt1BkvLdW48j8PPv5DsKRN3tloTxqDJGo9tKvj1Fuk74A+Xda1kNhB7KFlqMyN98\n\
+ VETEJ6c7KpfOo30mnK30wqw3S8OtaIR/maYX72tGOno2ehFDkq3pnPtEbD2CScxc\n\
+ alJC+EL7RPk5c/tgeTvCngvc1KZn92Y//EI7G9tPZtylj2b56sHtMftIoYJ9+ODM\n\
+ sccD5Piz/rejE3Ome8EOOceUSCYAhXn8b3qvxVI1ddd1pED6FHRhFvLrZxFvBEM9\n\
+ ERRMp5QqOaHJkM+Dxv8Cj6MqrCbfC4u+ZErxodzuusgDgvZiLF22uxMZbobFWyte\n\
+ OvOzKGtwcTqO/1wV5gKkzu1ZVswVUQd5Gg8lJicwqRWyyNRczDDoG9jVDxmogKTH\n\
+ AaqLulO7R8Ifa1SwF2DteSGVtgWEN8gDpN3RBmmPTDngyF2DHb5qmpnznwtFKdTL\n\
+ KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI=\n\
+ -----END DH PARAMETERS-----\n";
+ 
+ /*
+  *	Read data from a secure connection.
+  */
+ ssize_t
+ pgtls_read(Port *port, void *ptr, size_t len)
+ {
+ 	ssize_t		n;
+ 
+ 	int			err;
+ 
+ rloop:
+ 	n = SSL_read(port->ssl, ptr, len);
+ 	err = SSL_get_error(port->ssl, n);
+ 	switch (err)
+ 	{
+ 		case SSL_ERROR_NONE:
+ 			port->count += n;
+ 			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)
+ 				ereport(COMMERROR,
+ 						(errcode_for_socket_access(),
+ 						 errmsg("SSL SYSCALL error: %m")));
+ 			else
+ 			{
+ 				ereport(COMMERROR,
+ 						(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 						 errmsg("SSL SYSCALL error: EOF detected")));
+ 				errno = ECONNRESET;
+ 				n = -1;
+ 			}
+ 			break;
+ 		case SSL_ERROR_SSL:
+ 			ereport(COMMERROR,
+ 					(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 					 errmsg("SSL error: %s", SSLerrmessage())));
+ 			/* fall through */
+ 		case SSL_ERROR_ZERO_RETURN:
+ 			errno = ECONNRESET;
+ 			n = -1;
+ 			break;
+ 		default:
+ 			ereport(COMMERROR,
+ 					(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 					 errmsg("unrecognized SSL error code: %d",
+ 							err)));
+ 			n = -1;
+ 			break;
+ 	}
+ 
+ 	return n;
+ }
+ 
+ /*
+  *	Write data to a secure connection.
+  */
+ ssize_t
+ pgtls_write(Port *port, void *ptr, size_t len)
+ {
+ 	ssize_t		n;
+ 
+ 	int			err;
+ 
+ 	if (port->count > RENEGOTIATION_LIMIT)
+ 	{
+ 		SSL_set_session_id_context(port->ssl, (void *) &SSL_context,
+ 								   sizeof(SSL_context));
+ 		if (SSL_renegotiate(port->ssl) <= 0)
+ 			ereport(COMMERROR,
+ 					(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 					 errmsg("SSL renegotiation failure")));
+ 		if (SSL_do_handshake(port->ssl) <= 0)
+ 			ereport(COMMERROR,
+ 					(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 					 errmsg("SSL renegotiation failure")));
+ 		if (port->ssl->state != SSL_ST_OK)
+ 			ereport(COMMERROR,
+ 					(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 					 errmsg("SSL failed to send renegotiation request")));
+ 		port->ssl->state |= SSL_ST_ACCEPT;
+ 		SSL_do_handshake(port->ssl);
+ 		if (port->ssl->state != SSL_ST_OK)
+ 			ereport(COMMERROR,
+ 					(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 					 errmsg("SSL renegotiation failure")));
+ 		port->count = 0;
+ 	}
+ 
+ wloop:
+ 	n = SSL_write(port->ssl, ptr, len);
+ 	err = SSL_get_error(port->ssl, n);
+ 	switch (err)
+ 	{
+ 		case SSL_ERROR_NONE:
+ 			port->count += n;
+ 			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)
+ 				ereport(COMMERROR,
+ 						(errcode_for_socket_access(),
+ 						 errmsg("SSL SYSCALL error: %m")));
+ 			else
+ 			{
+ 				ereport(COMMERROR,
+ 						(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 						 errmsg("SSL SYSCALL error: EOF detected")));
+ 				errno = ECONNRESET;
+ 				n = -1;
+ 			}
+ 			break;
+ 		case SSL_ERROR_SSL:
+ 			ereport(COMMERROR,
+ 					(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 					 errmsg("SSL error: %s", SSLerrmessage())));
+ 			/* fall through */
+ 		case SSL_ERROR_ZERO_RETURN:
+ 			errno = ECONNRESET;
+ 			n = -1;
+ 			break;
+ 		default:
+ 			ereport(COMMERROR,
+ 					(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 					 errmsg("unrecognized SSL error code: %d",
+ 							err)));
+ 			n = -1;
+ 			break;
+ 	}
+ 
+ 	return n;
+ }
+ 
+ /* ------------------------------------------------------------ */
+ /*						  SSL specific code						*/
+ /* ------------------------------------------------------------ */
+ 
+ /*
+  * Private substitute BIO: this wraps the SSL library's standard socket BIO
+  * so that we can enable and disable interrupts just while calling recv().
+  * We cannot have interrupts occurring while the bulk of openssl runs,
+  * because it uses malloc() and possibly other non-reentrant libc facilities.
+  *
+  * As of openssl 0.9.7, we can use the reasonably clean method of interposing
+  * a wrapper around the standard socket BIO's sock_read() method.  This relies
+  * on the fact that sock_read() doesn't call anything non-reentrant, in fact
+  * not much of anything at all except recv().  If this ever changes we'd
+  * probably need to duplicate the code of sock_read() in order to push the
+  * interrupt enable/disable down yet another level.
+  */
+ 
+ static bool my_bio_initialized = false;
+ static BIO_METHOD my_bio_methods;
+ static int	(*std_sock_read) (BIO *h, char *buf, int size);
+ 
+ static int
+ my_sock_read(BIO *h, char *buf, int size)
+ {
+ 	int			res;
+ 
+ 	prepare_for_client_read();
+ 
+ 	res = std_sock_read(h, buf, size);
+ 
+ 	client_read_ended();
+ 
+ 	return res;
+ }
+ 
+ static BIO_METHOD *
+ my_BIO_s_socket(void)
+ {
+ 	if (!my_bio_initialized)
+ 	{
+ 		memcpy(&my_bio_methods, BIO_s_socket(), sizeof(BIO_METHOD));
+ 		std_sock_read = my_bio_methods.bread;
+ 		my_bio_methods.bread = my_sock_read;
+ 		my_bio_initialized = true;
+ 	}
+ 	return &my_bio_methods;
+ }
+ 
+ /* This should exactly match openssl's SSL_set_fd except for using my BIO */
+ static int
+ my_SSL_set_fd(SSL *s, int fd)
+ {
+ 	int			ret = 0;
+ 	BIO		   *bio = NULL;
+ 
+ 	bio = BIO_new(my_BIO_s_socket());
+ 
+ 	if (bio == NULL)
+ 	{
+ 		SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
+ 		goto err;
+ 	}
+ 	BIO_set_fd(bio, fd, BIO_NOCLOSE);
+ 	SSL_set_bio(s, bio, bio);
+ 	ret = 1;
+ err:
+ 	return ret;
+ }
+ 
+ /*
+  *	Load precomputed DH parameters.
+  *
+  *	To prevent "downgrade" attacks, we perform a number of checks
+  *	to verify that the DBA-generated DH parameters file contains
+  *	what we expect it to contain.
+  */
+ static DH  *
+ load_dh_file(int keylength)
+ {
+ 	FILE	   *fp;
+ 	char		fnbuf[MAXPGPATH];
+ 	DH		   *dh = NULL;
+ 	int			codes;
+ 
+ 	/* attempt to open file.  It's not an error if it doesn't exist. */
+ 	snprintf(fnbuf, sizeof(fnbuf), "dh%d.pem", keylength);
+ 	if ((fp = fopen(fnbuf, "r")) == NULL)
+ 		return NULL;
+ 
+ /*	flock(fileno(fp), LOCK_SH); */
+ 	dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
+ /*	flock(fileno(fp), LOCK_UN); */
+ 	fclose(fp);
+ 
+ 	/* is the prime the correct size? */
+ 	if (dh != NULL && 8 * DH_size(dh) < keylength)
+ 	{
+ 		elog(LOG, "DH errors (%s): %d bits expected, %d bits found",
+ 			 fnbuf, keylength, 8 * DH_size(dh));
+ 		dh = NULL;
+ 	}
+ 
+ 	/* make sure the DH parameters are usable */
+ 	if (dh != NULL)
+ 	{
+ 		if (DH_check(dh, &codes))
+ 		{
+ 			elog(LOG, "DH_check error (%s): %s", fnbuf, SSLerrmessage());
+ 			return NULL;
+ 		}
+ 		if (codes & DH_CHECK_P_NOT_PRIME)
+ 		{
+ 			elog(LOG, "DH error (%s): p is not prime", fnbuf);
+ 			return NULL;
+ 		}
+ 		if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
+ 			(codes & DH_CHECK_P_NOT_SAFE_PRIME))
+ 		{
+ 			elog(LOG,
+ 				 "DH error (%s): neither suitable generator or safe prime",
+ 				 fnbuf);
+ 			return NULL;
+ 		}
+ 	}
+ 
+ 	return dh;
+ }
+ 
+ /*
+  *	Load hardcoded DH parameters.
+  *
+  *	To prevent problems if the DH parameters files don't even
+  *	exist, we can load DH parameters hardcoded into this file.
+  */
+ static DH  *
+ load_dh_buffer(const char *buffer, size_t len)
+ {
+ 	BIO		   *bio;
+ 	DH		   *dh = NULL;
+ 
+ 	bio = BIO_new_mem_buf((char *) buffer, len);
+ 	if (bio == NULL)
+ 		return NULL;
+ 	dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
+ 	if (dh == NULL)
+ 		ereport(DEBUG2,
+ 				(errmsg_internal("DH load buffer: %s",
+ 								 SSLerrmessage())));
+ 	BIO_free(bio);
+ 
+ 	return dh;
+ }
+ 
+ /*
+  *	Generate an empheral DH key.  Because this can take a long
+  *	time to compute, we can use precomputed parameters of the
+  *	common key sizes.
+  *
+  *	Since few sites will bother to precompute these parameter
+  *	files, we also provide a fallback to the parameters provided
+  *	by the OpenSSL project.
+  *
+  *	These values can be static (once loaded or computed) since
+  *	the OpenSSL library can efficiently generate random keys from
+  *	the information provided.
+  */
+ static DH  *
+ tmp_dh_cb(SSL *s, int is_export, int keylength)
+ {
+ 	DH		   *r = NULL;
+ 	static DH  *dh = NULL;
+ 	static DH  *dh512 = NULL;
+ 	static DH  *dh1024 = NULL;
+ 	static DH  *dh2048 = NULL;
+ 	static DH  *dh4096 = NULL;
+ 
+ 	switch (keylength)
+ 	{
+ 		case 512:
+ 			if (dh512 == NULL)
+ 				dh512 = load_dh_file(keylength);
+ 			if (dh512 == NULL)
+ 				dh512 = load_dh_buffer(file_dh512, sizeof file_dh512);
+ 			r = dh512;
+ 			break;
+ 
+ 		case 1024:
+ 			if (dh1024 == NULL)
+ 				dh1024 = load_dh_file(keylength);
+ 			if (dh1024 == NULL)
+ 				dh1024 = load_dh_buffer(file_dh1024, sizeof file_dh1024);
+ 			r = dh1024;
+ 			break;
+ 
+ 		case 2048:
+ 			if (dh2048 == NULL)
+ 				dh2048 = load_dh_file(keylength);
+ 			if (dh2048 == NULL)
+ 				dh2048 = load_dh_buffer(file_dh2048, sizeof file_dh2048);
+ 			r = dh2048;
+ 			break;
+ 
+ 		case 4096:
+ 			if (dh4096 == NULL)
+ 				dh4096 = load_dh_file(keylength);
+ 			if (dh4096 == NULL)
+ 				dh4096 = load_dh_buffer(file_dh4096, sizeof file_dh4096);
+ 			r = dh4096;
+ 			break;
+ 
+ 		default:
+ 			if (dh == NULL)
+ 				dh = load_dh_file(keylength);
+ 			r = dh;
+ 	}
+ 
+ 	/* this may take a long time, but it may be necessary... */
+ 	if (r == NULL || 8 * DH_size(r) < keylength)
+ 	{
+ 		ereport(DEBUG2,
+ 				(errmsg_internal("DH: generating parameters (%d bits)....",
+ 								 keylength)));
+ 		r = DH_generate_parameters(keylength, DH_GENERATOR_2, NULL, NULL);
+ 	}
+ 
+ 	return r;
+ }
+ 
+ /*
+  *	Certificate verification callback
+  *
+  *	This callback allows us to log intermediate problems during
+  *	verification, but for now we'll see if the final error message
+  *	contains enough information.
+  *
+  *	This callback also allows us to override the default acceptance
+  *	criteria (e.g., accepting self-signed or expired certs), but
+  *	for now we accept the default checks.
+  */
+ static int
+ verify_cb(int ok, X509_STORE_CTX *ctx)
+ {
+ 	return ok;
+ }
+ 
+ /*
+  *	This callback is used to copy SSL information messages
+  *	into the PostgreSQL log.
+  */
+ static void
+ info_cb(const SSL *ssl, int type, int args)
+ {
+ 	switch (type)
+ 	{
+ 		case SSL_CB_HANDSHAKE_START:
+ 			ereport(DEBUG4,
+ 					(errmsg_internal("SSL: handshake start")));
+ 			break;
+ 		case SSL_CB_HANDSHAKE_DONE:
+ 			ereport(DEBUG4,
+ 					(errmsg_internal("SSL: handshake done")));
+ 			break;
+ 		case SSL_CB_ACCEPT_LOOP:
+ 			ereport(DEBUG4,
+ 					(errmsg_internal("SSL: accept loop")));
+ 			break;
+ 		case SSL_CB_ACCEPT_EXIT:
+ 			ereport(DEBUG4,
+ 					(errmsg_internal("SSL: accept exit (%d)", args)));
+ 			break;
+ 		case SSL_CB_CONNECT_LOOP:
+ 			ereport(DEBUG4,
+ 					(errmsg_internal("SSL: connect loop")));
+ 			break;
+ 		case SSL_CB_CONNECT_EXIT:
+ 			ereport(DEBUG4,
+ 					(errmsg_internal("SSL: connect exit (%d)", args)));
+ 			break;
+ 		case SSL_CB_READ_ALERT:
+ 			ereport(DEBUG4,
+ 					(errmsg_internal("SSL: read alert (0x%04x)", args)));
+ 			break;
+ 		case SSL_CB_WRITE_ALERT:
+ 			ereport(DEBUG4,
+ 					(errmsg_internal("SSL: write alert (0x%04x)", args)));
+ 			break;
+ 	}
+ }
+ 
+ /*
+  *	Initialize global SSL context.
+  */
+ void
+ pgtls_initialize(void)
+ {
+ 	struct stat buf;
+ 
+ 	if (!SSL_context)
+ 	{
+ 		SSL_library_init();
+ 		SSL_load_error_strings();
+ 		SSL_context = SSL_CTX_new(SSLv23_method());
+ 		if (!SSL_context)
+ 			ereport(FATAL,
+ 					(errmsg("could not create SSL context: %s",
+ 							SSLerrmessage())));
+ 
+ 		/*
+ 		 * Load and verify certificate and private key
+ 		 */
+ 		if (!SSL_CTX_use_certificate_file(SSL_context,
+ 										  SERVER_CERT_FILE,
+ 										  SSL_FILETYPE_PEM))
+ 			ereport(FATAL,
+ 					(errcode(ERRCODE_CONFIG_FILE_ERROR),
+ 				  errmsg("could not load server certificate file \"%s\": %s",
+ 						 SERVER_CERT_FILE, SSLerrmessage())));
+ 
+ 		if (stat(SERVER_PRIVATE_KEY_FILE, &buf) == -1)
+ 			ereport(FATAL,
+ 					(errcode_for_file_access(),
+ 					 errmsg("could not access private key file \"%s\": %m",
+ 							SERVER_PRIVATE_KEY_FILE)));
+ 
+ 		/*
+ 		 * Require no public access to key file.
+ 		 *
+ 		 * XXX temporarily suppress check when on Windows, because there may
+ 		 * not be proper support for Unix-y file permissions.  Need to think
+ 		 * of a reasonable check to apply on Windows.  (See also the data
+ 		 * directory permission check in postmaster.c)
+ 		 */
+ #if !defined(WIN32) && !defined(__CYGWIN__)
+ 		if (!S_ISREG(buf.st_mode) || (buf.st_mode & (S_IRWXG | S_IRWXO)) ||
+ 			buf.st_uid != geteuid())
+ 			ereport(FATAL,
+ 					(errcode(ERRCODE_CONFIG_FILE_ERROR),
+ 					 errmsg("unsafe permissions on private key file \"%s\"",
+ 							SERVER_PRIVATE_KEY_FILE),
+ 					 errdetail("File must be owned by the database user and must have no permissions for \"group\" or \"other\".")));
+ #endif
+ 
+ 		if (!SSL_CTX_use_PrivateKey_file(SSL_context,
+ 										 SERVER_PRIVATE_KEY_FILE,
+ 										 SSL_FILETYPE_PEM))
+ 			ereport(FATAL,
+ 					(errmsg("could not load private key file \"%s\": %s",
+ 							SERVER_PRIVATE_KEY_FILE, SSLerrmessage())));
+ 
+ 		if (!SSL_CTX_check_private_key(SSL_context))
+ 			ereport(FATAL,
+ 					(errmsg("check of private key failed: %s",
+ 							SSLerrmessage())));
+ 	}
+ 
+ 	/* set up empheral DH keys */
+ 	SSL_CTX_set_tmp_dh_callback(SSL_context, tmp_dh_cb);
+ 	SSL_CTX_set_options(SSL_context, SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv2);
+ 
+ 	/* setup the allowed cipher list */
+ 	if (SSL_CTX_set_cipher_list(SSL_context, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH") != 1)
+ 		elog(FATAL, "could not set the cipher list (no valid ciphers available)");
+ 
+ 	/*
+ 	 * Require and check client certificates only if we have a root.crt file.
+ 	 */
+ 	if (!SSL_CTX_load_verify_locations(SSL_context, ROOT_CERT_FILE, NULL))
+ 	{
+ 		/* Not fatal - we do not require client certificates */
+ 		ereport(LOG,
+ 				(errmsg("could not load root certificate file \"%s\": %s",
+ 						ROOT_CERT_FILE, SSLerrmessage()),
+ 				 errdetail("Will not verify client certificates.")));
+ 	}
+ 	else
+ 	{
+ 		/*
+ 		 *	Check the Certificate Revocation List (CRL) if file exists.
+ 		 *	http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html
+ 		 */
+ 		X509_STORE *cvstore = SSL_CTX_get_cert_store(SSL_context);
+ 
+ 		if (cvstore)
+ 		{
+ 			if (X509_STORE_load_locations(cvstore, ROOT_CRL_FILE, NULL) != 0)
+ 			   /* setting the flags to check against the complete CRL chain */
+ 			   X509_STORE_set_flags(cvstore,
+ 							X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
+ 			else
+ 			{
+ 				/* Not fatal - we do not require CRL */
+ 				ereport(LOG,
+ 					(errmsg("SSL Certificate Revocation List (CRL) file \"%s\" not found, skipping: %s",
+ 							ROOT_CRL_FILE, SSLerrmessage()),
+ 					 errdetail("Will not check certificates against CRL.")));
+ 			}
+ 		}
+ 
+ 		SSL_CTX_set_verify(SSL_context,
+ 						   (SSL_VERIFY_PEER |
+ 							SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
+ 							SSL_VERIFY_CLIENT_ONCE),
+ 						   verify_cb);
+ 	}
+ }
+ 
+ /*
+  *	Destroy global SSL context.
+  */
+ void
+ pgtls_destroy(void)
+ {
+ 	if (SSL_context)
+ 	{
+ 		SSL_CTX_free(SSL_context);
+ 		SSL_context = NULL;
+ 	}
+ }
+ 
+ /*
+  *	Attempt to negotiate SSL connection.
+  */
+ int
+ pgtls_open_server(Port *port)
+ {
+ 	int			r;
+ 	int			err;
+ 
+ 	Assert(!port->ssl);
+ 	Assert(!port->peer);
+ 
+ 	if (!(port->ssl = SSL_new(SSL_context)))
+ 	{
+ 		ereport(COMMERROR,
+ 				(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 				 errmsg("could not initialize SSL connection: %s",
+ 						SSLerrmessage())));
+ 		pgtls_close(port);
+ 		return -1;
+ 	}
+ 	if (!my_SSL_set_fd(port->ssl, port->sock))
+ 	{
+ 		ereport(COMMERROR,
+ 				(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 				 errmsg("could not set SSL socket: %s",
+ 						SSLerrmessage())));
+ 		pgtls_close(port);
+ 		return -1;
+ 	}
+ 
+ aloop:
+ 	r = SSL_accept(port->ssl);
+ 	if (r <= 0)
+ 	{
+ 		err = SSL_get_error(port->ssl, r);
+ 		switch (err)
+ 		{
+ 			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_ACCEPT : FD_WRITE | FD_CLOSE);
+ #endif
+ 				goto aloop;
+ 			case SSL_ERROR_SYSCALL:
+ 				if (r < 0)
+ 					ereport(COMMERROR,
+ 							(errcode_for_socket_access(),
+ 							 errmsg("could not accept SSL connection: %m")));
+ 				else
+ 					ereport(COMMERROR,
+ 							(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 					errmsg("could not accept SSL connection: EOF detected")));
+ 				break;
+ 			case SSL_ERROR_SSL:
+ 				ereport(COMMERROR,
+ 						(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 						 errmsg("could not accept SSL connection: %s",
+ 								SSLerrmessage())));
+ 				break;
+ 			case SSL_ERROR_ZERO_RETURN:
+ 				ereport(COMMERROR,
+ 						(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 				   errmsg("could not accept SSL connection: EOF detected")));
+ 				break;
+ 			default:
+ 				ereport(COMMERROR,
+ 						(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ 						 errmsg("unrecognized SSL error code: %d",
+ 								err)));
+ 				break;
+ 		}
+ 		pgtls_close(port);
+ 		return -1;
+ 	}
+ 
+ 	port->count = 0;
+ 
+ 	/* get client certificate, if available. */
+ 	port->peer = SSL_get_peer_certificate(port->ssl);
+ 	if (port->peer == NULL)
+ 	{
+ 		strncpy(port->peer_dn, "(anonymous)", sizeof(port->peer_dn));
+ 		strncpy(port->peer_cn, "(anonymous)", sizeof(port->peer_cn));
+ 	}
+ 	else
+ 	{
+ 		X509_NAME_oneline(X509_get_subject_name(port->peer),
+ 						  port->peer_dn, sizeof(port->peer_dn));
+ 		port->peer_dn[sizeof(port->peer_dn) - 1] = '\0';
+ 		X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
+ 					   NID_commonName, port->peer_cn, sizeof(port->peer_cn));
+ 		port->peer_cn[sizeof(port->peer_cn) - 1] = '\0';
+ 	}
+ 	ereport(DEBUG2,
+ 			(errmsg("SSL connection from \"%s\"", port->peer_cn)));
+ 
+ 	/* set up debugging/info callback */
+ 	SSL_CTX_set_info_callback(SSL_context, info_cb);
+ 
+ 	return 0;
+ }
+ 
+ /*
+  *	Close SSL connection.
+  */
+ void
+ pgtls_close(Port *port)
+ {
+ 	if (port->ssl)
+ 	{
+ 		SSL_shutdown(port->ssl);
+ 		SSL_free(port->ssl);
+ 		port->ssl = NULL;
+ 	}
+ 
+ 	if (port->peer)
+ 	{
+ 		X509_free(port->peer);
+ 		port->peer = NULL;
+ 	}
+ }
+ 
+ /*
+  * Obtain reason string for last SSL error
+  *
+  * Some caution is needed here since ERR_reason_error_string will
+  * return NULL if it doesn't recognize the error code.  We don't
+  * want to return NULL ever.
+  */
+ static const char *
+ SSLerrmessage(void)
+ {
+ 	unsigned long errcode;
+ 	const char *errreason;
+ 	static char errbuf[32];
+ 
+ 	errcode = ERR_get_error();
+ 	if (errcode == 0)
+ 		return "No SSL error reported";
+ 	errreason = ERR_reason_error_string(errcode);
+ 	if (errreason != NULL)
+ 		return errreason;
+ 	snprintf(errbuf, sizeof(errbuf), "SSL error code %lu", errcode);
+ 	return errbuf;
+ }
+ 
Index: src/interfaces/libpq/fe-secure-gnutls.c
=========================================================================
*** src/interfaces/libpq/fe-secure-gnutls.c.orig	Thu May  4 15:35:59 2006
--- src/interfaces/libpq/fe-secure-gnutls.c	Thu May  4 14:02:16 2006
***************
*** 0 ****
--- 1,756 ----
+ /*-------------------------------------------------------------------------
+  *
+  * fe-secure.c
+  *	  GnuTLS specific functions related to setting up a secure
+  *	  connection to the backend.  Secure connections are expected to
+  *	  provide confidentiality, message integrity and endpoint
+  *	  authentication.
+  *
+  *
+  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  *
+  *
+  * IDENTIFICATION
+  *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.74 2006/01/24 16:38:42 tgl Exp $
+  *
+  *-------------------------------------------------------------------------
+  */
+ 
+ #include "postgres_fe.h"
+ 
+ #include "libpq-fe.h"
+ #include "libpq-int.h"
+ 
+ #ifdef WIN32
+ #include "win32.h"
+ #else
+ #include <unistd.h>
+ #endif
+ #include <sys/stat.h>
+ 
+ #ifdef ENABLE_THREAD_SAFETY
+ #ifdef WIN32
+ #include "pthread-win32.h"
+ #else
+ #include <pthread.h>
+ #endif
+ #endif
+ 
+ #include <gnutls/gnutls.h>
+ #include <gnutls/x509.h>
+ 
+ #ifdef ENABLE_THREAD_SAFETY
+ #include <gcrypt.h>
+ #endif
+ 
+ #include "libpq-tls.h"
+ 
+ /* Define this for extra debugging info */
+ /* #define GNUTLS_DEBUG */
+ 
+ static int	pq_gnutls_init_ssl_system(PGconn *conn);
+ static char *pq_gnutls_errmessage(int err);
+ static void pq_gnutls_errfree(char *buf);
+ 
+ static int SSL_verify_server;
+ static int SSL_handshake;
+ static gnutls_certificate_credentials SSL_cred;  /* Credentials for connecting */
+ 
+ /* ------------------------------------------------------------ */
+ /*			 Procedures common to all secure sessions			*/
+ /* ------------------------------------------------------------ */
+ 
+ 
+ /*
+  *	Read data from a secure connection.
+  */
+ ssize_t
+ pqTLS_read(PGconn *conn, void *ptr, size_t len)
+ {
+ 	ssize_t		n;
+ 
+ rloop:
+ 	if( SSL_handshake )
+ 		n = gnutls_handshake(conn->ssl);
+ 	else
+ 		n = gnutls_record_recv(conn->ssl, ptr, len);
+ 	if( n < 0 )
+ 	{
+ 		if( n == GNUTLS_E_INTERRUPTED ||
+ 		    n == GNUTLS_E_AGAIN )
+ 		{
+ 			/*
+ 			 * Returning 0 here would cause caller to wait for read-ready,
+ 			 * which is not correct since what SSL wants is wait for
+ 			 * write-ready.  The former could get us stuck in an infinite
+ 			 * wait, so don't risk it; busy-loop instead.
+ 			 */
+ 			if( gnutls_record_get_direction(conn->ssl) == 0 ) /* read */
+ 				n = 0;
+ 			else
+ 				goto rloop;
+ 		}
+ 		else if( n == GNUTLS_E_REHANDSHAKE )
+ 		{
+ 			/* Server wants a rehandshake. */
+ 			SSL_handshake = true;
+ 			goto rloop;
+ 		}
+ 		else
+ 		{
+ 			char	   *err = pq_gnutls_errmessage(n);
+ 			printfPQExpBuffer(&conn->errorMessage,
+ 							  libpq_gettext("SSL error: %s\n"), err);
+ 			pq_gnutls_errfree(err);
+ 			SOCK_ERRNO_SET(ECONNRESET);
+ 			n = -1;
+ 		}
+ 	}
+ 	/* If we get here, the handshake has completed */
+ 	else if( SSL_handshake )
+ 	{
+ 		SSL_handshake = false;
+ 		/* Go back and read actual data now */
+ 		goto rloop;
+ 	}
+ 	return n;
+ }
+ 
+ /*
+  *	Write data to a secure connection.
+  */
+ ssize_t
+ pqTLS_write(PGconn *conn, const void *ptr, size_t len, bool *got_epipe)
+ {
+ 	ssize_t		n;
+ 
+ 	*got_epipe = false;
+ 	if( SSL_handshake )
+ 		n = gnutls_handshake(conn->ssl);
+ 	else
+ 		n = gnutls_record_send(conn->ssl, ptr, len);
+ 	if( n < 0 )
+ 	{
+ #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
+ 		if (SOCK_ERRNO == EPIPE)
+ 			*got_epipe = true;
+ #endif
+ 		if( n == GNUTLS_E_INTERRUPTED ||
+ 		    n == GNUTLS_E_AGAIN )
+ 		{
+ 			/*
+ 			 * Returning 0 here causes caller to wait
+ 			 * for write-ready, which is may not really
+ 			 * the right thing, but it's the best we can
+ 			 * do.
+ 			 */
+ 			n = 0;
+ 		}
+ 		else
+ 		{
+ 			char	   *err = pq_gnutls_errmessage(n);
+ 			printfPQExpBuffer(&conn->errorMessage,
+ 							  libpq_gettext("SSL error: %s\n"), err);
+ 			pq_gnutls_errfree(err);
+ 			SOCK_ERRNO_SET(ECONNRESET);
+ 			n = -1;
+ 			SSL_handshake = false;
+ 		}
+ 	}
+ 	else
+ 		SSL_handshake = false;
+ 
+ 	return n;
+ }
+ 
+ /* ------------------------------------------------------------ */
+ /*						  SSL specific code						*/
+ /* ------------------------------------------------------------ */
+ 
+ /*
+  *	Certificate verification callback
+  *
+  *	This callback allows us to log intermediate problems during
+  *	verification, but there doesn't seem to be a clean way to get
+  *	our PGconn * structure.  So we can't log anything!
+  *
+  *	This callback also allows us to override the default acceptance
+  *	criteria (e.g., accepting self-signed or expired certs), but
+  *	for now we accept the default checks.
+  */
+ #ifdef NOT_USED
+ static int
+ pq_gnutls_verify_cb(int ok, X509_STORE_CTX *ctx)
+ {
+ 	return ok;
+ }
+ #endif
+ 
+ static void
+ pq_gnutls_load_file( PGconn *conn, const char *filename, gnutls_datum *datum )
+ {
+ 	int filesize;
+ 	FILE *f;
+ 	
+ 	datum->size = 0;
+ 	datum->data = NULL;
+ 	
+ 	if( (f = fopen( filename, "r" )) == NULL )
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 						  libpq_gettext("could not open file \"%s\": %m\n"),
+ 						  filename);
+ 		return;
+ 	}
+ 	if( (filesize = fseek( f, SEEK_END, 0 )) < 0 )
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 						  libpq_gettext("could not seek file \"%s\": %m\n"),
+ 						  filename);
+ 		return;
+ 	}
+ 	if( fseek( f, SEEK_SET, 0 ) < 0 )
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 						  libpq_gettext("could not seek file \"%s\": %m\n"),
+ 						  filename);
+ 		return;
+ 	}
+ 	datum->data = malloc( filesize );
+ 	if( fread( datum->data, filesize, 1, f ) != 1 )
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 						  libpq_gettext("could not read file \"%s\": %m\n"),
+ 						  filename);
+ 		return;
+ 	}
+ 	fclose(f);
+ 	datum->size = filesize;
+ 	return;
+ }
+ /*
+  *	Callback used by SSL to load client cert and key.
+  *	This callback is only called when the server wants a
+  *	client cert.
+  *
+  *	Must return 0 on success.
+  */
+ static int
+ pg_gnutls_client_cert_cb(gnutls_session session, const gnutls_datum * req_ca_rdn, int nreqs,
+  const gnutls_pk_algorithm * pk_algos,
+  int pk_algos_length,  gnutls_retr_st *st)
+ {
+ 	gnutls_certificate_type type;
+ 	gnutls_x509_crt  ssl_clientcrt;
+ 	gnutls_x509_privkey ssl_clientkey;
+ 	
+ 	char		homedir[MAXPGPATH];
+ 	struct stat buf;
+ 	
+ 	char		crtfile[MAXPGPATH], keyfile[MAXPGPATH];
+ 	gnutls_datum  crtdatum, keydatum;
+ 	
+ 	PGconn	   *conn = (PGconn *) gnutls_session_get_ptr(session);
+ 
+ 	type = gnutls_certificate_type_get (session);
+ 	if (type != GNUTLS_CRT_X509)
+ 		return -1;
+ 	
+ 	/* Setup these values so we can return 0 at any time to try without cert */
+ 	st->type = type;
+ 	st->ncerts = 0;
+ 	st->cert.x509 = NULL;
+ 	st->key.x509 = NULL;
+ 	st->deinit_all = 0;
+ 
+ 	if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 						  libpq_gettext("could not get user information\n"));
+ 		return 0;
+ 	}
+ 
+ 	/* find the user certificate */
+ 	snprintf(crtfile, sizeof(crtfile), "%s/%s", homedir, USERCERTFILE);
+ 	if (stat(crtfile, &buf) == -1)
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 						  libpq_gettext("could not find certificate file \"%s\"\n"),
+ 						  crtfile);
+ 		return 0;
+ 	}
+ 	/* find the user key */
+ 	snprintf(keyfile, sizeof(keyfile), "%s/%s", homedir, USERKEYFILE);
+ 	if (stat(keyfile, &buf) == -1)
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 						  libpq_gettext("certificate present, but not private key file \"%s\"\n"),
+ 						  keyfile);
+ 		return 0;
+ 	}
+ #ifndef WIN32
+ 	if (!S_ISREG(buf.st_mode) || (buf.st_mode & 0077) ||
+ 		buf.st_uid != geteuid())
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 			libpq_gettext("private key file \"%s\" has wrong permissions\n"),
+ 						  keyfile);
+ 		return 0;
+ 	}
+ #endif
+ 	pq_gnutls_load_file( conn, crtfile, &crtdatum );
+ 	pq_gnutls_load_file( conn, keyfile, &keydatum );
+ 	
+ 	if( crtdatum.size && keydatum.size )
+ 	{
+ 		int err;
+ 		
+ 		gnutls_x509_crt_init( &ssl_clientcrt );
+ 		gnutls_x509_privkey_init( &ssl_clientkey );
+ 		
+ 		err = gnutls_x509_crt_import( ssl_clientcrt, &crtdatum, GNUTLS_X509_FMT_PEM );
+ 		if( err == 0 )
+ 			err = gnutls_x509_privkey_import( ssl_clientkey, &keydatum, GNUTLS_X509_FMT_PEM );
+ 		if( err == 0 )
+ 		{
+ 			st->ncerts = 1;
+ 			st->key.x509 = ssl_clientkey;
+ 			st->cert.x509 = malloc( sizeof(ssl_clientcrt)); /* No easy way to clean this up */
+ 			st->cert.x509[0] = ssl_clientcrt;
+ 			st->deinit_all = 1;
+ 		}
+ 		else
+ 		{
+ 			char	   *error = pq_gnutls_errmessage(err);
+ 
+ 			printfPQExpBuffer(&conn->errorMessage,
+ 						 libpq_gettext("could not parse key/cert files: %s\n"),
+ 							  error);
+ 			pq_gnutls_errfree(error);
+ 		}
+ 	}
+ 	if( crtdatum.data )
+ 		free( crtdatum.data );
+ 	if( keydatum.data )
+ 		free( keydatum.data );
+ 	
+ 	
+ 	return 0;
+ }
+ 
+ #ifdef ENABLE_THREAD_SAFETY
+ GCRY_THREAD_OPTION_PTHREAD_IMPL;
+ #endif
+ 
+ #ifdef GNUTLS_DEBUG
+ static void
+ pq_gnutls_log( int level, const char *str )
+ {
+ 	fprintf( stderr, "%d: %s\n", level, str );
+ }
+ #endif
+ 
+ static int
+ pq_gnutls_init_ssl_system(PGconn *conn)
+ {
+ 	int error;
+ 	
+ #ifdef ENABLE_THREAD_SAFETY
+ 	/* GnuTLS is thread-safe by design, but gcrypt may not be. Here we assume that the lib is pthread */
+ 	gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
+ #endif
+ 	/* Do gnutls_check_version(LIBGNUTLS_VERSION) ? */
+ 	error = gnutls_global_init();  /* Check for error */
+ 	if (error)
+ 	{
+ 		char	   *err = pq_gnutls_errmessage(error);
+ 
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 					 libpq_gettext("could not create SSL context: %s\n"),
+ 						  err);
+ 		pq_gnutls_errfree(err);
+ 		return -1;
+ 	}
+ #ifdef GNUTLS_DEBUG
+ 	gnutls_global_set_log_function( pq_gnutls_log );
+ 	gnutls_global_set_log_level (9);
+ #endif
+ 	return 0;
+ }
+ 
+ /*
+  *	Initialize global SSL context.
+  */
+ int
+ pqTLS_initialize(PGconn *conn)
+ {
+ 	struct stat buf;
+ 	char		homedir[MAXPGPATH];
+ 	char		fnbuf[MAXPGPATH];
+ 
+ 	if (pq_gnutls_init_ssl_system(conn))
+ 		return -1;
+ 
+ 	gnutls_certificate_allocate_credentials (&SSL_cred);
+ 
+ 	/* Set up to verify server cert, if root.crt is present */
+ 	if (pqGetHomeDirectory(homedir, sizeof(homedir)))
+ 	{
+ 		snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOTCERTFILE);
+ 		if (stat(fnbuf, &buf) == 0)
+ 		{
+ 			int error;
+ 			error = gnutls_certificate_set_x509_trust_file (SSL_cred, fnbuf, GNUTLS_X509_FMT_PEM);
+ 			if( error < 0 )
+ 			{
+ 				char	   *err = pq_gnutls_errmessage(error);
+ 
+ 				printfPQExpBuffer(&conn->errorMessage,
+ 								  libpq_gettext("could not read root certificate file \"%s\": %s\n"),
+ 								  fnbuf, err);
+ 				pq_gnutls_errfree(err);
+ 				return -1;
+ 			}
+ 			SSL_verify_server = TRUE;
+ 		}
+ 	}
+ 
+ 	gnutls_certificate_client_set_retrieve_function(SSL_cred, pg_gnutls_client_cert_cb);
+ 
+ 	return 0;
+ }
+ 
+ /*
+  *	Destroy global SSL context.
+  */
+ void
+ pqTLS_destroy(void)
+ {
+ 	if (SSL_cred)
+ 	{
+ 		gnutls_certificate_free_credentials (SSL_cred);
+ 		SSL_cred = NULL;
+ 
+ 		gnutls_global_deinit ();
+ 	}
+ }
+ 
+ /*
+  * Initialise the SSL on a single socket 
+  */
+ 
+ PostgresPollingStatusType
+ pqTLS_initconn(PGconn *conn)
+ {
+ 	const int kx_prio[] = { GNUTLS_KX_DHE_RSA, GNUTLS_KX_DHE_DSS, 0 };
+ 	/* Only do X509 certificates */
+ 	const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
+ 	const int cipher_type_priority[] = { GNUTLS_CIPHER_AES_256_CBC, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_CIPHER_ARCFOUR_128, 0 };
+ 	const int mac_type_priority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_RMD160, 0 };
+ 	
+ 	/* First time through? */
+ 	if (conn->ssl == NULL)
+ 	{
+ 		int error = gnutls_init ( (gnutls_session*)(&conn->ssl), GNUTLS_CLIENT);
+ 		if (error)
+ 		{
+ 			char	   *err = pq_gnutls_errmessage(error);
+ 
+ 			printfPQExpBuffer(&conn->errorMessage,
+ 						 libpq_gettext("could not create SSL context: %s\n"),
+ 							  err);
+ 			pq_gnutls_errfree(err);
+ 	
+ 			return PGRES_POLLING_FAILED;
+ 		}
+ //		gnutls_credentials_set (conn->ssl, GNUTLS_CRD_ANON, SSL_anoncred);
+ 
+ 		/* Use default priorities */
+ 		gnutls_set_default_priority (conn->ssl);
+ 		/* Server uses: ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH. This means:
+ 		 * - No anonymous DH cipher suites.
+ 		 * - Low security keys
+ 		 * - No export algorithms
+ 		 * - No MD5 */
+ 		gnutls_kx_set_priority (conn->ssl, kx_prio);  /* DH keyexchange only */
+ 		gnutls_certificate_type_set_priority (conn->ssl, cert_type_priority); /* X.509 certs only */
+ 		gnutls_cipher_set_priority( conn->ssl, cipher_type_priority );
+ 		gnutls_mac_set_priority( conn->ssl, mac_type_priority );
+ 
+ 		gnutls_transport_set_ptr (conn->ssl, (gnutls_transport_ptr) conn->sock);	
+ 		gnutls_session_set_ptr (conn->ssl, conn);
+ 
+ 		/* set up mechanism to provide client certificate, if available */
+ 		gnutls_credentials_set (conn->ssl, GNUTLS_CRD_CERTIFICATE, SSL_cred);
+ 		/*
+ 		 * Initialize errorMessage to empty.  This allows pqTLS_open_client() to
+ 		 * detect whether pg_gnutls_client_cert_cb() has stored a message.
+ 		 */
+ 		resetPQExpBuffer(&conn->errorMessage);
+ 	}
+ 	return PGRES_POLLING_OK;
+ }
+ 
+ /*
+  *	Attempt to negotiate SSL connection.
+  */
+ PostgresPollingStatusType
+ pqTLS_open_client(PGconn *conn)
+ {
+ 	int			err;
+ 	int cert_list_size, status, size;
+ 	gnutls_x509_crt cert;
+ 
+ 	err = gnutls_handshake(conn->ssl);
+ 	if (err < 0)
+ 	{
+ 		if( err == GNUTLS_E_AGAIN ||
+ 		    err == GNUTLS_E_INTERRUPTED )
+ 		{
+ 			if( gnutls_record_get_direction(conn->ssl) == 0 )
+ 				return PGRES_POLLING_READING;
+ 			else
+ 				return PGRES_POLLING_WRITING;
+ 		}
+ 		if( gnutls_error_is_fatal(err) )
+ 		{
+ 			printfPQExpBuffer(&conn->errorMessage,
+ 					libpq_gettext("SSL error: %s\n"),
+ 					gnutls_strerror(err));
+ 			pqTLS_close(conn);
+ 			return PGRES_POLLING_FAILED;
+ 		}
+ 		else
+ 		{
+ 			printfPQExpBuffer(&conn->errorMessage,
+ 					libpq_gettext("Unexpected non-fatal SSL error: %s\n"),
+ 					gnutls_strerror(err));
+ 			pqTLS_close(conn);
+ 			return PGRES_POLLING_FAILED;
+ 		}
+ 	}
+ 
+ 	/* If asked to verify server, do so */
+ 	if( SSL_verify_server )
+ 	{
+ 		err = gnutls_certificate_verify_peers2 (conn->ssl, &status);
+ 		if(err < 0)
+ 		{
+ 			printfPQExpBuffer(&conn->errorMessage,
+ 					libpq_gettext("SSL verification error: %s\n"),
+ 					gnutls_strerror(err));
+ 			pqTLS_close(conn);
+ 			return PGRES_POLLING_FAILED;
+ 		}
+ 		if( status )
+ 		{
+ 			printfPQExpBuffer(&conn->errorMessage,
+ 					libpq_gettext("Server cert verification failure: %d\n"),
+ 					status);
+ 			pqTLS_close(conn);
+ 			return PGRES_POLLING_FAILED;
+ 		}
+ 	}
+ 	/* pull out server distinguished and common names */
+ 	const gnutls_datum *peer = gnutls_certificate_get_peers (conn->ssl, &cert_list_size);
+ 	if (peer == NULL)
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 					libpq_gettext("certificate could not be obtained\n"));
+ 		pqTLS_close(conn);
+ 		return PGRES_POLLING_FAILED;
+ 	}
+ 	err = gnutls_x509_crt_init (&cert);
+ 	if(err < 0)
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 				libpq_gettext("gnutls_x509_crt_init failure: %s\n"),
+ 				gnutls_strerror(err));
+ 		pqTLS_close(conn);
+ 		return PGRES_POLLING_FAILED;
+ 	}
+ 	
+ 	err = gnutls_x509_crt_import (cert, &peer[0], GNUTLS_X509_FMT_DER);
+ 	if(err < 0)
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 				libpq_gettext("gnutls_x509_crt_import failure: %s\n"),
+ 				gnutls_strerror(err));
+ 		pqTLS_close(conn);
+ 		return PGRES_POLLING_FAILED;
+ 	}
+ 	size = sizeof(conn->peer_dn);
+ 	gnutls_x509_crt_get_dn (cert, conn->peer_dn, &size);
+ 	conn->peer_dn[sizeof(conn->peer_dn) - 1] = '\0';
+ 
+ 	size = sizeof(conn->peer_cn);
+ 	gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME, 0, 0, conn->peer_cn, &size );
+ 	conn->peer_cn[sizeof(conn->peer_cn) - 1] = '\0';
+ 
+ 	gnutls_x509_crt_deinit( cert );
+ 	/* SSL handshake is complete */
+ 	return PGRES_POLLING_OK;
+ }
+ 
+ /*
+  *	Close SSL connection.
+  */
+ void
+ pqTLS_close(PGconn *conn)
+ {
+ 	if (conn->ssl)
+ 	{
+ #ifdef NOT_USED
+ 		conn->peer = NULL;  /* Is allocated as part of session, no need to free */
+ #endif 
+ 		gnutls_bye (conn->ssl, GNUTLS_SHUT_RDWR);
+ 		gnutls_deinit (conn->ssl);
+ 		conn->ssl = NULL;
+ 	}
+ }
+ 
+ /*
+  * Obtain reason string for last SSL error
+  *
+  * Some caution is needed here since ERR_reason_error_string will
+  * return NULL if it doesn't recognize the error code.  We don't
+  * want to return NULL ever.
+  */
+ #define SSL_ERR_LEN 128
+ 
+ static char *
+ pq_gnutls_errmessage(int errcode)
+ {
+ 	const char *errreason;
+ 	char	   *errbuf;
+ 
+ 	errbuf = malloc(SSL_ERR_LEN);
+ 	if (!errbuf)
+ 		return pqTLS_ssl_nomem;
+ 	if (errcode >= 0)
+ 	{
+ 		strcpy(errbuf, "No SSL error reported");
+ 		return errbuf;
+ 	}
+ 	errreason = gnutls_strerror(errcode);
+ 	if (errreason != NULL)
+ 	{
+ 		strncpy(errbuf, errreason, SSL_ERR_LEN - 1);
+ 		errbuf[SSL_ERR_LEN - 1] = '\0';
+ 		return errbuf;
+ 	}
+ 	snprintf(errbuf, SSL_ERR_LEN, "SSL error code %u", errcode);
+ 	return errbuf;
+ }
+ 
+ static void
+ pq_gnutls_errfree(char *buf)
+ {
+ 	if (buf != pqTLS_ssl_nomem)
+ 		free(buf);
+ }
+ 
+ /*
+  *	Return pointer to SSL object.
+  *
+  *	Unfortunatly, this function was in the past defined to return a
+  *	pointer to an OpenSSL structure, so here we just return NULL.
+  *
+  */
+ void *
+ PQgetssl(PGconn *conn)
+ {
+ 	return NULL;
+ }
+ 
+ /*
+  *	Exported function to allow application to tell us it's already
+  *	initialized OpenSSL. GnuTLS doesn't need that info.
+  */
+ void
+ PQinitSSL(int do_init)
+ {
+ }
+ 
+ int 
+ pqTLS_pending(PGconn *conn)
+ {
+ 	return gnutls_record_check_pending(conn->ssl);
+ }
+ 
+ PGresult *
+ pqTLS_gettlsinfo( PGconn *conn, PGresult *res )
+ {
+ 	size_t keysize;
+ 	char buf[24];
+ 	
+ 	pqsecure_tlsinfo_add_row( res, "tls_library", "GnuTLS" );
+ 	pqsecure_tlsinfo_add_row( res, "tls_library_version", gnutls_check_version(NULL) );
+ 	pqsecure_tlsinfo_add_row( res, "tls_sslmode", conn->sslmode );
+ 	pqsecure_tlsinfo_add_row( res, "tls_active", conn->ssl ? "yes" : "no" );
+ 	
+ 	if( !conn->ssl )
+ 		return res;
+ 		
+ 	keysize = gnutls_cipher_get_key_size(gnutls_cipher_get(conn->ssl));
+ 	sprintf( buf, "%d bits", keysize*8 );
+ 	pqsecure_tlsinfo_add_row( res, "tls_verify_server", SSL_verify_server ? "yes" : "no" );
+ 	pqsecure_tlsinfo_add_row( res, "tls_peerdn", conn->peer_dn );
+ 	pqsecure_tlsinfo_add_row( res, "tls_peercn", conn->peer_cn );
+ 	pqsecure_tlsinfo_add_row( res, "tls_protocol",    gnutls_protocol_get_name(gnutls_protocol_get_version(conn->ssl)) );
+ 	pqsecure_tlsinfo_add_row( res, "tls_cipher",      gnutls_cipher_suite_get_name(gnutls_kx_get(conn->ssl),gnutls_cipher_get(conn->ssl),gnutls_mac_get(conn->ssl)));
+ 	pqsecure_tlsinfo_add_row( res, "tls_keysize",     buf );
+ 	pqsecure_tlsinfo_add_row( res, "tls_kx",          gnutls_kx_get_name(gnutls_kx_get(conn->ssl)) );
+ 	pqsecure_tlsinfo_add_row( res, "tls_mac",         gnutls_mac_get_name(gnutls_mac_get(conn->ssl)) );
+ 	pqsecure_tlsinfo_add_row( res, "tls_compression", gnutls_compression_get_name(gnutls_compression_get(conn->ssl)) );
+ 	pqsecure_tlsinfo_add_row( res, "tls_certtype",    gnutls_certificate_type_get_name(gnutls_certificate_type_get(conn->ssl)) );
+ 
+ 	{
+ 		int len;
+ 		const gnutls_datum *peer = gnutls_certificate_get_peers(conn->ssl, &len);
+ 		if( len > 0 )
+ 		{
+ 			gnutls_x509_crt cert;
+ 			int err = gnutls_x509_crt_init (&cert);
+ 			if(err == 0)
+ 			{
+ 				err = gnutls_x509_crt_import (cert, &peer[0], GNUTLS_X509_FMT_DER);
+ 				if(err == 0)
+ 				{
+ 					int crtlen = 4096;
+ 					char *ptr = malloc(crtlen);
+ 					err = gnutls_x509_crt_export (cert, GNUTLS_X509_FMT_PEM, ptr, &crtlen );
+ 					if( err == 0 )
+ 						pqsecure_tlsinfo_add_row( res, "x509_peercert", ptr );
+ 					free(ptr);
+ 				}
+ 				gnutls_x509_crt_deinit(cert);
+ 			}
+ 		}
+ 	}
+ 	{
+ 		const gnutls_datum *ours = gnutls_certificate_get_ours(conn->ssl);
+ 		if( ours )
+ 		{
+ 			gnutls_x509_crt cert;
+ 			int err = gnutls_x509_crt_init (&cert);
+ 			if(err == 0)
+ 			{
+ 				err = gnutls_x509_crt_import (cert, ours, GNUTLS_X509_FMT_DER);
+ 				if(err == 0)
+ 				{
+ 					int crtlen = 4096;
+ 					char *ptr = malloc(crtlen);
+ 					err = gnutls_x509_crt_export (cert, GNUTLS_X509_FMT_PEM, ptr, &crtlen );
+ 					if( err == 0 )
+ 						pqsecure_tlsinfo_add_row( res, "x509_clientcert", ptr );
+ 					free(ptr);
+ 				}
+ 				gnutls_x509_crt_deinit(cert);
+ 			}
+ 		}
+ 	}
+ 			
+ 	return res;
+ }
Index: src/interfaces/libpq/fe-secure-openssl.c
=========================================================================
*** src/interfaces/libpq/fe-secure-openssl.c.orig	Thu May  4 15:35:59 2006
--- src/interfaces/libpq/fe-secure-openssl.c	Thu May  4 13:04:32 2006
***************
*** 0 ****
--- 1,922 ----
+ /*-------------------------------------------------------------------------
+  *
+  * fe-secure.c
+  *	  OpenSSL functions related to setting up a secure connection to the
+  *	  backend.  Secure connections are expected to provide
+  *	  confidentiality, message integrity and endpoint authentication.
+  *
+  *
+  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  *
+  *
+  * IDENTIFICATION
+  *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.75 2006/03/05 15:59:09 momjian Exp $
+  *
+  *-------------------------------------------------------------------------
+  */
+ 
+ #include "postgres_fe.h"
+ 
+ #include <signal.h>
+ #include <fcntl.h>
+ #include <ctype.h>
+ 
+ #include "libpq-fe.h"
+ #include "libpq-int.h"
+ #include "fe-auth.h"
+ #include "pqsignal.h"
+ 
+ #ifdef WIN32
+ #include "win32.h"
+ #else
+ #include <sys/socket.h>
+ #include <unistd.h>
+ #include <netdb.h>
+ #include <netinet/in.h>
+ #ifdef HAVE_NETINET_TCP_H
+ #include <netinet/tcp.h>
+ #endif
+ #include <arpa/inet.h>
+ #endif
+ #include <sys/stat.h>
+ 
+ #ifdef ENABLE_THREAD_SAFETY
+ #ifdef WIN32
+ #include "pthread-win32.h"
+ #else
+ #include <pthread.h>
+ #endif
+ #endif
+ 
+ #ifndef HAVE_STRDUP
+ #include "strdup.h"
+ #endif
+ 
+ #include <openssl/ssl.h>
+ #include <openssl/err.h>
+ 
+ #include "libpq-tls.h"
+ 
+ #ifdef NOT_USED
+ static int	pq_openssl_verify_peer(PGconn *);
+ #endif
+ static int	pq_openssl_verify_cb(int ok, X509_STORE_CTX *ctx);
+ static int	pq_openssl_client_cert_cb(SSL *, X509 **, EVP_PKEY **);
+ static int	pq_openssl_init_ssl_system(PGconn *conn);
+ static char *pq_openssl_errmessage(void);
+ static void pq_openssl_errfree(char *buf);
+ static bool pq_initssllib = TRUE;
+ 
+ static SSL_CTX *SSL_context = NULL;
+ 
+ /* ------------------------------------------------------------ */
+ /*			 Procedures common to all secure sessions			*/
+ /* ------------------------------------------------------------ */
+ 
+ 
+ /*
+  *	Read data from a secure connection.
+  */
+ ssize_t
+ pqTLS_read(PGconn *conn, void *ptr, size_t len)
+ {
+ 	ssize_t		n;
+ 
+ 	int			err;
+ 
+ rloop:
+ 	n = SSL_read(conn->ssl, ptr, len);
+ 	err = SSL_get_error(conn->ssl, n);
+ 	switch (err)
+ 	{
+ 		case SSL_ERROR_NONE:
+ 			break;
+ 		case SSL_ERROR_WANT_READ:
+ 			n = 0;
+ 			break;
+ 		case SSL_ERROR_WANT_WRITE:
+ 			/*
+ 			 * Returning 0 here would cause caller to wait for read-ready,
+ 			 * which is not correct since what SSL wants is wait for
+ 			 * write-ready.  The former could get us stuck in an infinite
+ 			 * wait, so don't risk it; busy-loop instead.
+ 			 */
+ 			goto rloop;
+ 		case SSL_ERROR_SYSCALL:
+ 			{
+ 				char		sebuf[256];
+ 
+ 				if (n == -1)
+ 					printfPQExpBuffer(&conn->errorMessage,
+ 								libpq_gettext("SSL SYSCALL error: %s\n"),
+ 						SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
+ 				else
+ 				{
+ 					printfPQExpBuffer(&conn->errorMessage,
+ 					 libpq_gettext("SSL SYSCALL error: EOF detected\n"));
+ 						SOCK_ERRNO_SET(ECONNRESET);
+ 					n = -1;
+ 				}
+ 				break;
+ 			}
+ 		case SSL_ERROR_SSL:
+ 			{
+ 				char	   *err = pq_openssl_errmessage();
+ 					printfPQExpBuffer(&conn->errorMessage,
+ 								  libpq_gettext("SSL error: %s\n"), err);
+ 				pq_openssl_errfree(err);
+ 			}
+ 			/* fall through */
+ 		case SSL_ERROR_ZERO_RETURN:
+ 			SOCK_ERRNO_SET(ECONNRESET);
+ 			n = -1;
+ 			break;
+ 		default:
+ 			printfPQExpBuffer(&conn->errorMessage,
+ 					  libpq_gettext("unrecognized SSL error code: %d\n"),
+ 							  err);
+ 			n = -1;
+ 			break;
+ 	}
+ 	return n;
+ }
+ 
+ /*
+  *	Write data to a secure connection.
+  */
+ ssize_t
+ pqTLS_write(PGconn *conn, const void *ptr, size_t len, bool *got_epipe)
+ {
+ 	ssize_t		n;
+ 
+ 	*got_epipe = false;
+ 
+ 	int			err;
+ 
+ 	n = SSL_write(conn->ssl, ptr, len);
+ 	err = SSL_get_error(conn->ssl, n);
+ 	switch (err)
+ 	{
+ 		case SSL_ERROR_NONE:
+ 			break;
+ 		case SSL_ERROR_WANT_READ:
+ 			/*
+ 			 * Returning 0 here causes caller to wait for write-ready,
+ 			 * which is not really the right thing, but it's the best we
+ 			 * can do.
+ 			 */
+ 			n = 0;
+ 			break;
+ 		case SSL_ERROR_WANT_WRITE:
+ 			n = 0;
+ 			break;
+ 		case SSL_ERROR_SYSCALL:
+ 			{
+ 				char		sebuf[256];
+ 					if (n == -1)
+ 				{
+ #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
+ 					if (SOCK_ERRNO == EPIPE)
+ 						*got_epipe = true;
+ #endif
+ 					printfPQExpBuffer(&conn->errorMessage,
+ 								libpq_gettext("SSL SYSCALL error: %s\n"),
+ 						SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
+ 				}
+ 				else
+ 				{
+ 					printfPQExpBuffer(&conn->errorMessage,
+ 					 libpq_gettext("SSL SYSCALL error: EOF detected\n"));
+ 					SOCK_ERRNO_SET(ECONNRESET);
+ 					n = -1;
+ 				}
+ 				break;
+ 			}
+ 		case SSL_ERROR_SSL:
+ 			{
+ 				char	   *err = pq_openssl_errmessage();
+ 					printfPQExpBuffer(&conn->errorMessage,
+ 								  libpq_gettext("SSL error: %s\n"), err);
+ 				pq_openssl_errfree(err);
+ 			}
+ 			/* fall through */
+ 		case SSL_ERROR_ZERO_RETURN:
+ 			SOCK_ERRNO_SET(ECONNRESET);
+ 			n = -1;
+ 			break;
+ 		default:
+ 			printfPQExpBuffer(&conn->errorMessage,
+ 					  libpq_gettext("unrecognized SSL error code: %d\n"),
+ 							  err);
+ 			n = -1;
+ 			break;
+ 	}
+ 
+ 	return n;
+ }
+ 
+ /* ------------------------------------------------------------ */
+ /*						  SSL specific code						*/
+ /* ------------------------------------------------------------ */
+ 
+ /*
+  *	Certificate verification callback
+  *
+  *	This callback allows us to log intermediate problems during
+  *	verification, but there doesn't seem to be a clean way to get
+  *	our PGconn * structure.  So we can't log anything!
+  *
+  *	This callback also allows us to override the default acceptance
+  *	criteria (e.g., accepting self-signed or expired certs), but
+  *	for now we accept the default checks.
+  */
+ static int
+ pq_openssl_verify_cb(int ok, X509_STORE_CTX *ctx)
+ {
+ 	return ok;
+ }
+ 
+ #ifdef NOT_USED
+ /*
+  *	Verify that common name resolves to peer.
+  */
+ static int
+ pq_openssl_verify_peer(PGconn *conn)
+ {
+ 	struct hostent *h = NULL;
+ 	struct sockaddr addr;
+ 	struct sockaddr_in *sin;
+ 	ACCEPT_TYPE_ARG3 len;
+ 	char	  **s;
+ 	unsigned long l;
+ 
+ 	/* get the address on the other side of the socket */
+ 	len = sizeof(addr);
+ 	if (getpeername(conn->sock, &addr, &len) == -1)
+ 	{
+ 		char		sebuf[256];
+ 
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 						  libpq_gettext("error querying socket: %s\n"),
+ 						  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
+ 		return -1;
+ 	}
+ 
+ 	/* weird, but legal case */
+ 	if (addr.sa_family == AF_UNIX)
+ 		return 0;
+ 
+ 	{
+ 		struct hostent hpstr;
+ 		char		buf[BUFSIZ];
+ 		int			herrno = 0;
+ 
+ 		/*
+ 		 * Currently, pqGethostbyname() is used only on platforms that don't
+ 		 * have getaddrinfo().	If you enable this function, you should
+ 		 * convert the pqGethostbyname() function call to use getaddrinfo().
+ 		 */
+ 		pqGethostbyname(conn->peer_cn, &hpstr, buf, sizeof(buf),
+ 						&h, &herrno);
+ 	}
+ 
+ 	/* what do we know about the peer's common name? */
+ 	if (h == NULL)
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 		  libpq_gettext("could not get information about host \"%s\": %s\n"),
+ 						  conn->peer_cn, hstrerror(h_errno));
+ 		return -1;
+ 	}
+ 
+ 	/* does the address match? */
+ 	switch (addr.sa_family)
+ 	{
+ 		case AF_INET:
+ 			sin = (struct sockaddr_in *) & addr;
+ 			for (s = h->h_addr_list; *s != NULL; s++)
+ 			{
+ 				if (!memcmp(&sin->sin_addr.s_addr, *s, h->h_length))
+ 					return 0;
+ 			}
+ 			break;
+ 
+ 		default:
+ 			printfPQExpBuffer(&conn->errorMessage,
+ 							  libpq_gettext("unsupported protocol\n"));
+ 			return -1;
+ 	}
+ 
+ 	/*
+ 	 * the prior test should be definitive, but in practice it sometimes
+ 	 * fails.  So we also check the aliases.
+ 	 */
+ 	for (s = h->h_aliases; *s != NULL; s++)
+ 	{
+ 		if (pg_strcasecmp(conn->peer_cn, *s) == 0)
+ 			return 0;
+ 	}
+ 
+ 	/* generate protocol-aware error message */
+ 	switch (addr.sa_family)
+ 	{
+ 		case AF_INET:
+ 			sin = (struct sockaddr_in *) & addr;
+ 			l = ntohl(sin->sin_addr.s_addr);
+ 			printfPQExpBuffer(&conn->errorMessage,
+ 							  libpq_gettext(
+ 											"server common name \"%s\" does not resolve to %ld.%ld.%ld.%ld\n"),
+ 						 conn->peer_cn, (l >> 24) % 0x100, (l >> 16) % 0x100,
+ 							  (l >> 8) % 0x100, l % 0x100);
+ 			break;
+ 		default:
+ 			printfPQExpBuffer(&conn->errorMessage,
+ 							  libpq_gettext(
+ 			 "server common name \"%s\" does not resolve to peer address\n"),
+ 							  conn->peer_cn);
+ 	}
+ 
+ 	return -1;
+ }
+ #endif   /* NOT_USED */
+ 
+ /*
+  *	Callback used by SSL to load client cert and key.
+  *	This callback is only called when the server wants a
+  *	client cert.
+  *
+  *	Must return 1 on success, 0 on no data or error.
+  */
+ static int
+ pq_openssl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
+ {
+ 	char		homedir[MAXPGPATH];
+ 	struct stat buf;
+ 
+ #ifndef WIN32
+ 	struct stat buf2;
+ #endif
+ 	char		fnbuf[MAXPGPATH];
+ 	FILE	   *fp;
+ 	PGconn	   *conn = (PGconn *) SSL_get_app_data(ssl);
+ 	int			(*cb) () = NULL;	/* how to read user password */
+ 	char		sebuf[256];
+ 
+ 	if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 						  libpq_gettext("could not get user information\n"));
+ 		return 0;
+ 	}
+ 
+ 	/* read the user certificate */
+ 	snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USERCERTFILE);
+ 	if ((fp = fopen(fnbuf, "r")) == NULL)
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 			   libpq_gettext("could not open certificate file \"%s\": %s\n"),
+ 						  fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
+ 		return 0;
+ 	}
+ 	if (PEM_read_X509(fp, x509, NULL, NULL) == NULL)
+ 	{
+ 		char	   *err = pq_openssl_errmessage();
+ 
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 			   libpq_gettext("could not read certificate file \"%s\": %s\n"),
+ 						  fnbuf, err);
+ 		pq_openssl_errfree(err);
+ 		fclose(fp);
+ 		return 0;
+ 	}
+ 	fclose(fp);
+ 
+ 	/* read the user key */
+ 	snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USERKEYFILE);
+ 	if (stat(fnbuf, &buf) == -1)
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 						  libpq_gettext("certificate present, but not private key file \"%s\"\n"),
+ 						  fnbuf);
+ 		return 0;
+ 	}
+ #ifndef WIN32
+ 	if (!S_ISREG(buf.st_mode) || (buf.st_mode & 0077) ||
+ 		buf.st_uid != geteuid())
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 			libpq_gettext("private key file \"%s\" has wrong permissions\n"),
+ 						  fnbuf);
+ 		return 0;
+ 	}
+ #endif
+ 	if ((fp = fopen(fnbuf, "r")) == NULL)
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 			   libpq_gettext("could not open private key file \"%s\": %s\n"),
+ 						  fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
+ 		return 0;
+ 	}
+ #ifndef WIN32
+ 	if (fstat(fileno(fp), &buf2) == -1 ||
+ 		buf.st_dev != buf2.st_dev || buf.st_ino != buf2.st_ino)
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 						  libpq_gettext("private key file \"%s\" changed during execution\n"), fnbuf);
+ 		return 0;
+ 	}
+ #endif
+ 	if (PEM_read_PrivateKey(fp, pkey, cb, NULL) == NULL)
+ 	{
+ 		char	   *err = pq_openssl_errmessage();
+ 
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 			   libpq_gettext("could not read private key file \"%s\": %s\n"),
+ 						  fnbuf, err);
+ 		pq_openssl_errfree(err);
+ 		fclose(fp);
+ 		return 0;
+ 	}
+ 	fclose(fp);
+ 
+ 	/* verify that the cert and key go together */
+ 	if (!X509_check_private_key(*x509, *pkey))
+ 	{
+ 		char	   *err = pq_openssl_errmessage();
+ 
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 						  libpq_gettext("certificate does not match private key file \"%s\": %s\n"),
+ 						  fnbuf, err);
+ 		pq_openssl_errfree(err);
+ 		return 0;
+ 	}
+ 
+ 	return 1;
+ }
+ 
+ #ifdef ENABLE_THREAD_SAFETY
+ 
+ static unsigned long
+ pq_threadidcallback(void)
+ {
+ 	/*
+ 	 * This is not starndard-compliant.  pthread_self() returns pthread_t, and
+ 	 * shouldn't be cast to unsigned long, but CRYPTO_set_id_callback requires
+ 	 * it, so we have to do it.
+ 	 */
+ 	return (unsigned long) pthread_self();
+ }
+ 
+ static pthread_mutex_t *pq_lockarray;
+ 
+ static void
+ pq_lockingcallback(int mode, int n, const char *file, int line)
+ {
+ 	if (mode & CRYPTO_LOCK)
+ 		pthread_mutex_lock(&pq_lockarray[n]);
+ 	else
+ 		pthread_mutex_unlock(&pq_lockarray[n]);
+ }
+ #endif   /* ENABLE_THREAD_SAFETY */
+ 
+ static int
+ pq_openssl_init_ssl_system(PGconn *conn)
+ {
+ #ifdef ENABLE_THREAD_SAFETY
+ #ifndef WIN32
+ 	static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
+ #else
+ 	static pthread_mutex_t init_mutex = NULL;
+ 	static long mutex_initlock = 0;
+ 
+ 	if (init_mutex == NULL)
+ 	{
+ 		while (InterlockedExchange(&mutex_initlock, 1) == 1)
+ 			 /* loop, another thread own the lock */ ;
+ 		if (init_mutex == NULL)
+ 			pthread_mutex_init(&init_mutex, NULL);
+ 		InterlockedExchange(&mutex_initlock, 0);
+ 	}
+ #endif
+ 	pthread_mutex_lock(&init_mutex);
+ 
+ 	if (pq_initssllib && pq_lockarray == NULL)
+ 	{
+ 		int			i;
+ 
+ 		CRYPTO_set_id_callback(pq_threadidcallback);
+ 
+ 		pq_lockarray = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
+ 		if (!pq_lockarray)
+ 		{
+ 			pthread_mutex_unlock(&init_mutex);
+ 			return -1;
+ 		}
+ 		for (i = 0; i < CRYPTO_num_locks(); i++)
+ 			pthread_mutex_init(&pq_lockarray[i], NULL);
+ 
+ 		CRYPTO_set_locking_callback(pq_lockingcallback);
+ 	}
+ #endif
+ 	if (!SSL_context)
+ 	{
+ 		if (pq_initssllib)
+ 		{
+ 			SSL_library_init();
+ 			SSL_load_error_strings();
+ 		}
+ 		SSL_context = SSL_CTX_new(TLSv1_method());
+ 		if (!SSL_context)
+ 		{
+ 			char	   *err = pq_openssl_errmessage();
+ 
+ 			printfPQExpBuffer(&conn->errorMessage,
+ 						 libpq_gettext("could not create SSL context: %s\n"),
+ 							  err);
+ 			pq_openssl_errfree(err);
+ #ifdef ENABLE_THREAD_SAFETY
+ 			pthread_mutex_unlock(&init_mutex);
+ #endif
+ 			return -1;
+ 		}
+ 	}
+ #ifdef ENABLE_THREAD_SAFETY
+ 	pthread_mutex_unlock(&init_mutex);
+ #endif
+ 	return 0;
+ }
+ 
+ /*
+  *	Initialize global SSL context.
+  */
+ int
+ pqTLS_initialize(PGconn *conn)
+ {
+ 	struct stat buf;
+ 	char		homedir[MAXPGPATH];
+ 	char		fnbuf[MAXPGPATH];
+ 
+ 	if (pq_openssl_init_ssl_system(conn))
+ 		return -1;
+ 
+ 	/* Set up to verify server cert, if root.crt is present */
+ 	if (pqGetHomeDirectory(homedir, sizeof(homedir)))
+ 	{
+ 		snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOTCERTFILE);
+ 		if (stat(fnbuf, &buf) == 0)
+ 		{
+ 			if (!SSL_CTX_load_verify_locations(SSL_context, fnbuf, NULL))
+ 			{
+ 				char	   *err = pq_openssl_errmessage();
+ 
+ 				printfPQExpBuffer(&conn->errorMessage,
+ 								  libpq_gettext("could not read root certificate file \"%s\": %s\n"),
+ 								  fnbuf, err);
+ 				pq_openssl_errfree(err);
+ 				return -1;
+ 			}
+ 
+ 			SSL_CTX_set_verify(SSL_context, SSL_VERIFY_PEER, pq_openssl_verify_cb);
+ 		}
+ 	}
+ 
+ 	/* set up mechanism to provide client certificate, if available */
+ 	SSL_CTX_set_client_cert_cb(SSL_context, pq_openssl_client_cert_cb);
+ 
+ 	return 0;
+ }
+ 
+ /*
+  *	Destroy global SSL context.
+  */
+ void
+ pqTLS_destroy(void)
+ {
+ 	if (SSL_context)
+ 	{
+ 		SSL_CTX_free(SSL_context);
+ 		SSL_context = NULL;
+ 	}
+ }
+ 
+ /*
+  * Initialise the SSL on a single socket 
+  */
+   
+ PostgresPollingStatusType   
+ pqTLS_initconn(PGconn *conn)
+ {
+ 	/* First time through? */
+ 	if (conn->ssl == NULL)
+ 	{
+ 		if (!(conn->ssl = SSL_new(SSL_context)) ||
+ 			!SSL_set_app_data(conn->ssl, conn) ||
+ 			!SSL_set_fd(conn->ssl, conn->sock))
+ 		{
+ 			char	   *err = pq_openssl_errmessage();
+ 
+ 			printfPQExpBuffer(&conn->errorMessage,
+ 				   libpq_gettext("could not establish SSL connection: %s\n"),
+ 							  err);
+ 			pq_openssl_errfree(err);
+ 			pqTLS_close(conn);
+ 			return PGRES_POLLING_FAILED;
+ 		}
+ 
+ 		/*
+ 		 * Initialize errorMessage to empty.  This allows pqTLS_open_client() to
+ 		 * detect whether pq_openssl_client_cert_cb() has stored a message.
+ 		 */
+ 		resetPQExpBuffer(&conn->errorMessage);
+ 	}
+ 	return PGRES_POLLING_OK;
+ }
+   
+ /*
+  *	Attempt to negotiate SSL connection.
+  */
+ PostgresPollingStatusType
+ pqTLS_open_client(PGconn *conn)
+ {
+ 	int			r;
+ 
+ 	r = SSL_connect(conn->ssl);
+ 	if (r <= 0)
+ 	{
+ 		int			err = SSL_get_error(conn->ssl, r);
+ 
+ 		switch (err)
+ 		{
+ 			case SSL_ERROR_WANT_READ:
+ 				return PGRES_POLLING_READING;
+ 
+ 			case SSL_ERROR_WANT_WRITE:
+ 				return PGRES_POLLING_WRITING;
+ 
+ 			case SSL_ERROR_SYSCALL:
+ 				{
+ 					char		sebuf[256];
+ 
+ 					if (r == -1)
+ 						printfPQExpBuffer(&conn->errorMessage,
+ 									libpq_gettext("SSL SYSCALL error: %s\n"),
+ 							SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
+ 					else
+ 						printfPQExpBuffer(&conn->errorMessage,
+ 						 libpq_gettext("SSL SYSCALL error: EOF detected\n"));
+ 					pqTLS_close(conn);
+ 					return PGRES_POLLING_FAILED;
+ 				}
+ 			case SSL_ERROR_SSL:
+ 				{
+ 					/*
+ 					 * If there are problems with the local certificate files,
+ 					 * these will be detected by pq_openssl_client_cert_cb() which is
+ 					 * called from SSL_connect().  We want to return that
+ 					 * error message and not the rather unhelpful error that
+ 					 * OpenSSL itself returns.	So check to see if an error
+ 					 * message was already stored.
+ 					 */
+ 					if (conn->errorMessage.len == 0)
+ 					{
+ 						char	   *err = pq_openssl_errmessage();
+ 
+ 						printfPQExpBuffer(&conn->errorMessage,
+ 										  libpq_gettext("SSL error: %s\n"),
+ 										  err);
+ 						pq_openssl_errfree(err);
+ 					}
+ 					pqTLS_close(conn);
+ 					return PGRES_POLLING_FAILED;
+ 				}
+ 
+ 			default:
+ 				printfPQExpBuffer(&conn->errorMessage,
+ 						  libpq_gettext("unrecognized SSL error code: %d\n"),
+ 								  err);
+ 				pqTLS_close(conn);
+ 				return PGRES_POLLING_FAILED;
+ 		}
+ 	}
+ 
+ 	/* check the certificate chain of the server */
+ 
+ #ifdef NOT_USED
+ 	/* CLIENT CERTIFICATES NOT REQUIRED  bjm 2002-09-26 */
+ 
+ 	/*
+ 	 * this eliminates simple man-in-the-middle attacks and simple
+ 	 * impersonations
+ 	 */
+ 	r = SSL_get_verify_result(conn->ssl);
+ 	if (r != X509_V_OK)
+ 	{
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 				   libpq_gettext("certificate could not be validated: %s\n"),
+ 						  X509_verify_cert_error_string(r));
+ 		pqTLS_close(conn);
+ 		return PGRES_POLLING_FAILED;
+ 	}
+ #endif
+ 
+ 	/* pull out server distinguished and common names */
+ 	X509 *peer = SSL_get_peer_certificate(conn->ssl);
+ 	if (peer == NULL)
+ 	{
+ 		char	   *err = pq_openssl_errmessage();
+ 
+ 		printfPQExpBuffer(&conn->errorMessage,
+ 					libpq_gettext("certificate could not be obtained: %s\n"),
+ 						  err);
+ 		pq_openssl_errfree(err);
+ 		pqTLS_close(conn);
+ 		return PGRES_POLLING_FAILED;
+ 	}
+ 
+ 	X509_NAME_oneline(X509_get_subject_name(peer),
+ 					  conn->peer_dn, sizeof(conn->peer_dn));
+ 	conn->peer_dn[sizeof(conn->peer_dn) - 1] = '\0';
+ 
+ 	X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
+ 							  NID_commonName, conn->peer_cn, SM_USER);
+ 	conn->peer_cn[SM_USER] = '\0';
+ 
+ 	/* verify that the common name resolves to peer */
+ 
+ #ifdef NOT_USED
+ 	/* CLIENT CERTIFICATES NOT REQUIRED  bjm 2002-09-26 */
+ 
+ 	/*
+ 	 * this is necessary to eliminate man-in-the-middle attacks and
+ 	 * impersonations where the attacker somehow learned the server's private
+ 	 * key
+ 	 */
+ 	if (pq_openssl_verify_peer(conn) == -1)
+ 	{
+ 		pqTLS_close(conn);
+ 		return PGRES_POLLING_FAILED;
+ 	}
+ #endif
+ 
+ 	/* SSL handshake is complete */
+ 	return PGRES_POLLING_OK;
+ }
+ 
+ /*
+  *	Close SSL connection.
+  */
+ void
+ pqTLS_close(PGconn *conn)
+ {
+ 	if (conn->ssl)
+ 	{
+ 		SSL_shutdown(conn->ssl);
+ 		SSL_free(conn->ssl);
+ 		conn->ssl = NULL;
+ 	}
+ #ifdef NOT_USED
+ 	if (conn->peer)
+ 	{
+ 		X509_free(conn->peer);
+ 		conn->peer = NULL;
+ 	}
+ #endif
+ }
+ 
+ /*
+  * Obtain reason string for last SSL error
+  *
+  * Some caution is needed here since ERR_reason_error_string will
+  * return NULL if it doesn't recognize the error code.  We don't
+  * want to return NULL ever.
+  */
+ 
+ #define SSL_ERR_LEN 128
+ 
+ static char *
+ pq_openssl_errmessage(void)
+ {
+ 	unsigned long errcode;
+ 	const char *errreason;
+ 	char	   *errbuf;
+ 
+ 	errbuf = malloc(SSL_ERR_LEN);
+ 	if (!errbuf)
+ 		return pqTLS_ssl_nomem;
+ 	errcode = ERR_get_error();
+ 	if (errcode == 0)
+ 	{
+ 		strcpy(errbuf, "No SSL error reported");
+ 		return errbuf;
+ 	}
+ 	errreason = ERR_reason_error_string(errcode);
+ 	if (errreason != NULL)
+ 	{
+ 		strncpy(errbuf, errreason, SSL_ERR_LEN - 1);
+ 		errbuf[SSL_ERR_LEN - 1] = '\0';
+ 		return errbuf;
+ 	}
+ 	snprintf(errbuf, SSL_ERR_LEN, "SSL error code %lu", errcode);
+ 	return errbuf;
+ }
+ 
+ static void
+ pq_openssl_errfree(char *buf)
+ {
+ 	if (buf != pqTLS_ssl_nomem)
+ 		free(buf);
+ }
+ 
+ /*
+  *	Return pointer to SSL object.
+  */
+ void *
+ PQgetssl(PGconn *conn)
+ {
+ 	if (!conn)
+ 		return NULL;
+ 	return conn->ssl;
+ }
+ 
+ /*
+  *	Exported function to allow application to tell us it's already
+  *	initialized OpenSSL.
+  */
+ void
+ PQinitSSL(int do_init)
+ {
+ 	pq_initssllib = do_init;
+ }
+ 
+ int 
+ pqTLS_pending(PGconn *conn)
+ {
+ 	return SSL_pending(conn->ssl);
+ }
+ 
+ PGresult *
+ pqTLS_gettlsinfo( PGconn *conn, PGresult *res )
+ {
+ 	size_t keysize;
+ 	SSL_CIPHER *cipher;
+ //	SSL_METHOD *method;
+ 	char buf[24];
+ 	
+ 	pqsecure_tlsinfo_add_row( res, "tls_library", "OpenSSL" );
+ 	pqsecure_tlsinfo_add_row( res, "tls_library_version", SSLeay_version(SSLEAY_VERSION) );
+ 	pqsecure_tlsinfo_add_row( res, "tls_sslmode", conn->sslmode );
+ 	pqsecure_tlsinfo_add_row( res, "tls_active", conn->ssl ? "yes" : "no" );
+ 	
+ 	if( !conn->ssl )
+ 		return res;
+ 		
+ 	cipher  = SSL_get_current_cipher(conn->ssl);
+ //	method = SSL_get_ssl_method(conn->ssl)
+ 	
+ 	keysize = SSL_CIPHER_get_bits( cipher, NULL);
+ 	sprintf( buf, "%d bits", keysize );
+ //	pqsecure_tlsinfo_add_row( res, "tls_verify_server", SSL_verify_server ? "yes" : "no" );
+ 	pqsecure_tlsinfo_add_row( res, "tls_peerdn", conn->peer_dn );
+ 	pqsecure_tlsinfo_add_row( res, "tls_peercn", conn->peer_cn );
+ 	pqsecure_tlsinfo_add_row( res, "tls_cipher",   SSL_CIPHER_get_name(cipher) );
+ 	pqsecure_tlsinfo_add_row( res, "tls_protocol", SSL_CIPHER_get_version(cipher) );
+ 	pqsecure_tlsinfo_add_row( res, "tls_keysize",  buf );
+ 	
+ 	{
+ 		X509 *peer =  SSL_get_peer_certificate(conn->ssl);
+ 		if( peer )
+ 		{
+ 			BIO *bio = BIO_new( BIO_s_mem() );
+ 			if( PEM_write_bio_X509(bio, peer) )
+ 			{
+ 				char *data;
+ 				long len;
+ //				data = "\0";
+ //				BIO_write( bio, data, 1 );  /* Make sure NULL terminated */
+ 				len = BIO_get_mem_data(bio, &data);
+ 				pqsecure_tlsinfo_add_row( res, "x509_peercert", data );
+ 				BIO_free( bio );
+ 			}
+ 		}
+ 	}
+ 	{
+ 		X509 *ours =  SSL_get_certificate(conn->ssl);
+ 		if( ours )
+ 		{
+ 			BIO *bio = BIO_new( BIO_s_mem() );
+ 			if( PEM_write_bio_X509(bio, ours) )
+ 			{
+ 				char *data;
+ 				long len;
+ //				data = "\0";
+ //				BIO_write( bio, data, 1 );  /* Make sure NULL terminated */
+ 				len = BIO_get_mem_data(bio, &data);
+ 				pqsecure_tlsinfo_add_row( res, "x509_clientcert", data );
+ 				BIO_free( bio );
+ 			}
+ 		}
+ 	}
+ 		                
+ 	return res;
+ }
Index: src/interfaces/libpq/libpq-tls.h
=========================================================================
*** src/interfaces/libpq/libpq-tls.h.orig	Thu May  4 15:35:59 2006
--- src/interfaces/libpq/libpq-tls.h	Thu May  4 13:04:32 2006
***************
*** 0 ****
--- 1,33 ----
+ #ifdef USE_SSL
+ 
+ int	pqTLS_initialize(PGconn *);
+ void pqTLS_destroy(void);
+ PostgresPollingStatusType pqTLS_open_client(PGconn *);
+ void pqTLS_close(PGconn *);
+ ssize_t pqTLS_read(PGconn *conn, void *ptr, size_t len);
+ ssize_t pqTLS_write(PGconn *conn, const void *ptr, size_t len, bool *got_epipe);
+ PostgresPollingStatusType pqTLS_initconn(PGconn *conn);
+ int pqTLS_pending(PGconn *conn);
+ #ifndef WIN32
+ #define USERCERTFILE	".postgresql/postgresql.crt"
+ #define USERKEYFILE		".postgresql/postgresql.key"
+ #define ROOTCERTFILE	".postgresql/root.crt"
+ #else
+ /* On Windows, the "home" directory is already PostgreSQL-specific */
+ #define USERCERTFILE	"postgresql.crt"
+ #define USERKEYFILE		"postgresql.key"
+ #define ROOTCERTFILE	"root.crt"
+ #endif
+ 
+ int	pqTLS_initialize(PGconn *);
+ void pqTLS_destroy(void);
+ PostgresPollingStatusType pqTLS_open_client(PGconn *);
+ void pqTLS_close(PGconn *);
+ ssize_t pqTLS_read(PGconn *conn, void *ptr, size_t len);
+ ssize_t pqTLS_write(PGconn *conn, const void *ptr, size_t len, bool *got_epipe);
+ int pqTLS_pending(PGconn *conn);
+ PostgresPollingStatusType pqTLS_initconn(PGconn *conn);
+ PGresult *pqTLS_gettlsinfo( PGconn *conn, PGresult *res );
+ 
+ extern char pqTLS_ssl_nomem[];
+ #endif
Index: configure
===================================================================
RCS file: /projects/cvsroot/pgsql/configure,v
retrieving revision 1.492
diff -c -r1.492 configure
*** configure	29 Apr 2006 20:47:29 -0000	1.492
--- configure	4 May 2006 13:36:02 -0000
***************
*** 314,320 ****
  # include <unistd.h>
  #endif"
  
! ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS configure_args build build_cpu build_vendor build_os host host_cpu host_vendor host_os PORTNAME docdir enable_nls WANTED_LANGUAGES default_port enable_shared enable_rpath enable_debug CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP GCC TAS autodepend INCLUDES enable_thread_safety with_tcl with_perl with_python with_krb5 krb_srvtab with_pam with_ldap with_bonjour with_openssl with_zlib EGREP ELF_SYS LDFLAGS_SL AWK FLEX FLEXFLAGS LN_S LD with_gnu_ld ld_R_works RANLIB ac_ct_RANLIB TAR STRIP ac_ct_STRIP STRIP_STATIC_LIB STRIP_SHARED_LIB YACC YFLAGS PERL perl_archlibexp perl_privlibexp perl_useshrplib perl_embed_ldflags PYTHON python_version python_configdir python_includespec python_libdir python_libspec python_additional_libs HAVE_IPV6 LIBOBJS acx_pthread_config PTHREAD_CC PTHREAD_LIBS PTHREAD_CFLAGS HAVE_POSIX_SIGNALS MSGFMT MSGMERGE XGETTEXT localedir TCLSH TCL_CONFIG_SH TCL_INCLUDE_SPEC TCL_LIB_FILE TCL_LIBS TCL_LIB_SPEC TCL_SHARED_BUILD TCL_SHLIB_LD_LIBS NSGMLS JADE have_docbook DOCBOOKSTYLE COLLATEINDEX SGMLSPL vpath_build LTLIBOBJS'
  ac_subst_files=''
  
  # Initialize some variables set by options.
--- 314,320 ----
  # include <unistd.h>
  #endif"
  
! ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS configure_args build build_cpu build_vendor build_os host host_cpu host_vendor host_os PORTNAME docdir enable_nls WANTED_LANGUAGES default_port enable_shared enable_rpath enable_debug CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP GCC TAS autodepend INCLUDES enable_thread_safety with_tcl with_perl with_python with_krb5 krb_srvtab with_pam with_ldap with_bonjour with_openssl with_gnutls with_zlib EGREP ELF_SYS LDFLAGS_SL AWK FLEX FLEXFLAGS LN_S LD with_gnu_ld ld_R_works RANLIB ac_ct_RANLIB TAR STRIP ac_ct_STRIP STRIP_STATIC_LIB STRIP_SHARED_LIB YACC YFLAGS PERL perl_archlibexp perl_privlibexp perl_useshrplib perl_embed_ldflags PYTHON python_version python_configdir python_includespec python_libdir python_libspec python_additional_libs HAVE_IPV6 LIBOBJS acx_pthread_config PTHREAD_CC PTHREAD_LIBS PTHREAD_CFLAGS HAVE_POSIX_SIGNALS MSGFMT MSGMERGE XGETTEXT localedir TCLSH TCL_CONFIG_SH TCL_INCLUDE_SPEC TCL_LIB_FILE TCL_LIBS TCL_LIB_SPEC TCL_SHARED_BUILD TCL_SHLIB_LD_LIBS NSGMLS JADE have_docbook DOCBOOKSTYLE COLLATEINDEX SGMLSPL vpath_build LTLIBOBJS'
  ac_subst_files=''
  
  # Initialize some variables set by options.
***************
*** 891,896 ****
--- 891,897 ----
    --with-ldap             build with LDAP support
    --with-bonjour          build with Bonjour support
    --with-openssl          build with OpenSSL support
+   --with-gnutls           build with GnuTLS support
    --with-libedit-preferred  prefer BSD Libedit over GNU Readline
    --without-readline      do not use GNU Readline / BSD Libedit line editing
    --without-zlib          do not use Zlib
***************
*** 1000,1006 ****
      else
        echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
      fi
!     cd $ac_popdir
    done
  fi
  
--- 1001,1007 ----
      else
        echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
      fi
!     cd "$ac_popdir"
    done
  fi
  
***************
*** 2324,2331 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 2325,2331 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 2383,2390 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 2383,2389 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 2500,2507 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 2499,2505 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 2555,2562 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 2553,2559 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 2601,2608 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 2598,2604 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 2646,2653 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 2642,2648 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 2800,2807 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 2795,2801 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 2853,2860 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 2847,2853 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 2966,2973 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 2959,2965 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 3088,3095 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 3080,3086 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 3144,3151 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 3135,3141 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 3953,3959 ****
      yes)
  
  cat >>confdefs.h <<\_ACEOF
! #define USE_SSL 1
  _ACEOF
  
        ;;
--- 3943,3949 ----
      yes)
  
  cat >>confdefs.h <<\_ACEOF
! #define USE_SSL_OPENSSL 1
  _ACEOF
  
        ;;
***************
*** 3976,3981 ****
--- 3966,4025 ----
  echo "${ECHO_T}$with_openssl" >&6
  
  
+ #
+ # GnuTLS
+ #
+ echo "$as_me:$LINENO: checking whether to build with GnuTLS support" >&5
+ echo $ECHO_N "checking whether to build with GnuTLS support... $ECHO_C" >&6
+ 
+ 
+ 
+ # Check whether --with-gnutls or --without-gnutls was given.
+ if test "${with_gnutls+set}" = set; then
+   withval="$with_gnutls"
+ 
+   case $withval in
+     yes)
+ 
+ cat >>confdefs.h <<\_ACEOF
+ #define USE_SSL_GNUTLS 1
+ _ACEOF
+ 
+       ;;
+     no)
+       :
+       ;;
+     *)
+       { { echo "$as_me:$LINENO: error: no argument expected for --with-gnutls option" >&5
+ echo "$as_me: error: no argument expected for --with-gnutls option" >&2;}
+    { (exit 1); exit 1; }; }
+       ;;
+   esac
+ 
+ else
+   with_gnutls=no
+ 
+ fi;
+ 
+ echo "$as_me:$LINENO: result: $with_gnutls" >&5
+ echo "${ECHO_T}$with_gnutls" >&6
+ 
+ 
+ if test "$with_openssl" = yes -o "$with_gnutls" = yes ; then
+ 
+ cat >>confdefs.h <<\_ACEOF
+ #define USE_SSL 1
+ _ACEOF
+ 
+ fi
+ 
+ if test "$with_openssl" = yes -a "$with_gnutls" = yes ; then
+   { { echo "$as_me:$LINENO: error:
+ *** Cannot select both OpenSSL and GnuTLS." >&5
+ echo "$as_me: error:
+ *** Cannot select both OpenSSL and GnuTLS." >&2;}
+    { (exit 1); exit 1; }; }
+ fi
  
  #
  # Prefer libedit
***************
*** 4405,4412 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 4449,4455 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 4962,4969 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 5005,5011 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 5017,5024 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 5059,5065 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 5088,5095 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 5129,5135 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 5143,5150 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 5183,5189 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 5214,5221 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 5253,5259 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 5269,5276 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 5307,5313 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 5340,5347 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 5377,5383 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 5395,5402 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 5431,5437 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 5466,5473 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 5501,5507 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 5521,5528 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 5555,5561 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 5595,5602 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 5628,5634 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 5650,5657 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 5682,5688 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 5723,5730 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 5754,5760 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 5778,5785 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 5808,5814 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 5849,5856 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 5878,5884 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 5904,5911 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 5932,5938 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 5976,5983 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 6003,6009 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 6031,6038 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 6057,6063 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 6103,6110 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 6128,6134 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 6158,6165 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 6182,6188 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 6240,6247 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 6263,6269 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 6351,6358 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 6373,6379 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 6451,6458 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 6472,6478 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 6506,6513 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 6526,6532 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 6581,6588 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 6600,6606 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 6636,6643 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 6654,6660 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 6711,6718 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 6728,6734 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 6766,6773 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 6782,6788 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 6842,6849 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 6857,6863 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 6897,6904 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 6911,6917 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 6978,6985 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 6991,6997 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 7056,7063 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 7068,7074 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 7135,7142 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 7146,7152 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 7213,7220 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 7223,7229 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 7255,7269 ****
    fi
  fi
  
! if test "$with_pam" = yes ; then
  
! echo "$as_me:$LINENO: checking for pam_start in -lpam" >&5
! echo $ECHO_N "checking for pam_start in -lpam... $ECHO_C" >&6
! if test "${ac_cv_lib_pam_pam_start+set}" = set; then
    echo $ECHO_N "(cached) $ECHO_C" >&6
  else
    ac_check_lib_save_LIBS=$LIBS
! LIBS="-lpam  $LIBS"
  cat >conftest.$ac_ext <<_ACEOF
  /* confdefs.h.  */
  _ACEOF
--- 7264,7278 ----
    fi
  fi
  
! if test "$with_gnutls" = yes ; then
  
! echo "$as_me:$LINENO: checking for gnutls_init in -lgnutls" >&5
! echo $ECHO_N "checking for gnutls_init in -lgnutls... $ECHO_C" >&6
! if test "${ac_cv_lib_gnutls_gnutls_init+set}" = set; then
    echo $ECHO_N "(cached) $ECHO_C" >&6
  else
    ac_check_lib_save_LIBS=$LIBS
! LIBS="-lgnutls  $LIBS"
  cat >conftest.$ac_ext <<_ACEOF
  /* confdefs.h.  */
  _ACEOF
***************
*** 7277,7287 ****
  #endif
  /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
! char pam_start ();
  int
  main ()
  {
! pam_start ();
    ;
    return 0;
  }
--- 7286,7296 ----
  #endif
  /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
! char gnutls_init ();
  int
  main ()
  {
! gnutls_init ();
    ;
    return 0;
  }
***************
*** 7295,7302 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 7304,7310 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 7308,7352 ****
    ac_status=$?
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); }; }; then
!   ac_cv_lib_pam_pam_start=yes
  else
    echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
  
! ac_cv_lib_pam_pam_start=no
  fi
  rm -f conftest.err conftest.$ac_objext \
        conftest$ac_exeext conftest.$ac_ext
  LIBS=$ac_check_lib_save_LIBS
  fi
! echo "$as_me:$LINENO: result: $ac_cv_lib_pam_pam_start" >&5
! echo "${ECHO_T}$ac_cv_lib_pam_pam_start" >&6
! if test $ac_cv_lib_pam_pam_start = yes; then
    cat >>confdefs.h <<_ACEOF
! #define HAVE_LIBPAM 1
  _ACEOF
  
!   LIBS="-lpam $LIBS"
  
  else
!   { { echo "$as_me:$LINENO: error: library 'pam' is required for PAM" >&5
! echo "$as_me: error: library 'pam' is required for PAM" >&2;}
     { (exit 1); exit 1; }; }
  fi
  
! fi
! 
! 
! if test "$with_ldap" = yes ; then
!   if test "$PORTNAME" != "win32"; then
  
! echo "$as_me:$LINENO: checking for ldap_bind in -lldap" >&5
! echo $ECHO_N "checking for ldap_bind in -lldap... $ECHO_C" >&6
! if test "${ac_cv_lib_ldap_ldap_bind+set}" = set; then
    echo $ECHO_N "(cached) $ECHO_C" >&6
  else
    ac_check_lib_save_LIBS=$LIBS
! LIBS="-lldap  $LIBS"
  cat >conftest.$ac_ext <<_ACEOF
  /* confdefs.h.  */
  _ACEOF
--- 7316,7356 ----
    ac_status=$?
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); }; }; then
!   ac_cv_lib_gnutls_gnutls_init=yes
  else
    echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
  
! ac_cv_lib_gnutls_gnutls_init=no
  fi
  rm -f conftest.err conftest.$ac_objext \
        conftest$ac_exeext conftest.$ac_ext
  LIBS=$ac_check_lib_save_LIBS
  fi
! echo "$as_me:$LINENO: result: $ac_cv_lib_gnutls_gnutls_init" >&5
! echo "${ECHO_T}$ac_cv_lib_gnutls_gnutls_init" >&6
! if test $ac_cv_lib_gnutls_gnutls_init = yes; then
    cat >>confdefs.h <<_ACEOF
! #define HAVE_LIBGNUTLS 1
  _ACEOF
  
!   LIBS="-lgnutls $LIBS"
  
  else
!   { { echo "$as_me:$LINENO: error: library 'gnutls' is required for GnuTLS" >&5
! echo "$as_me: error: library 'gnutls' is required for GnuTLS" >&2;}
     { (exit 1); exit 1; }; }
  fi
  
!      # Technically we only need this with --enable-thread-safety
  
! echo "$as_me:$LINENO: checking for gcry_control in -lgcrypt" >&5
! echo $ECHO_N "checking for gcry_control in -lgcrypt... $ECHO_C" >&6
! if test "${ac_cv_lib_gcrypt_gcry_control+set}" = set; then
    echo $ECHO_N "(cached) $ECHO_C" >&6
  else
    ac_check_lib_save_LIBS=$LIBS
! LIBS="-lgcrypt  $LIBS"
  cat >conftest.$ac_ext <<_ACEOF
  /* confdefs.h.  */
  _ACEOF
***************
*** 7360,7370 ****
  #endif
  /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
! char ldap_bind ();
  int
  main ()
  {
! ldap_bind ();
    ;
    return 0;
  }
--- 7364,7374 ----
  #endif
  /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
! char gcry_control ();
  int
  main ()
  {
! gcry_control ();
    ;
    return 0;
  }
***************
*** 7378,7385 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 7382,7388 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 7391,7431 ****
    ac_status=$?
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); }; }; then
!   ac_cv_lib_ldap_ldap_bind=yes
  else
    echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
  
! ac_cv_lib_ldap_ldap_bind=no
  fi
  rm -f conftest.err conftest.$ac_objext \
        conftest$ac_exeext conftest.$ac_ext
  LIBS=$ac_check_lib_save_LIBS
  fi
! echo "$as_me:$LINENO: result: $ac_cv_lib_ldap_ldap_bind" >&5
! echo "${ECHO_T}$ac_cv_lib_ldap_ldap_bind" >&6
! if test $ac_cv_lib_ldap_ldap_bind = yes; then
    cat >>confdefs.h <<_ACEOF
! #define HAVE_LIBLDAP 1
  _ACEOF
  
!   LIBS="-lldap $LIBS"
  
  else
!   { { echo "$as_me:$LINENO: error: library 'ldap' is required for LDAP" >&5
! echo "$as_me: error: library 'ldap' is required for LDAP" >&2;}
     { (exit 1); exit 1; }; }
  fi
  
!   else
  
! echo "$as_me:$LINENO: checking for ldap_bind in -lwldap32" >&5
! echo $ECHO_N "checking for ldap_bind in -lwldap32... $ECHO_C" >&6
! if test "${ac_cv_lib_wldap32_ldap_bind+set}" = set; then
    echo $ECHO_N "(cached) $ECHO_C" >&6
  else
    ac_check_lib_save_LIBS=$LIBS
! LIBS="-lwldap32  $LIBS"
  cat >conftest.$ac_ext <<_ACEOF
  /* confdefs.h.  */
  _ACEOF
--- 7394,7436 ----
    ac_status=$?
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); }; }; then
!   ac_cv_lib_gcrypt_gcry_control=yes
  else
    echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
  
! ac_cv_lib_gcrypt_gcry_control=no
  fi
  rm -f conftest.err conftest.$ac_objext \
        conftest$ac_exeext conftest.$ac_ext
  LIBS=$ac_check_lib_save_LIBS
  fi
! echo "$as_me:$LINENO: result: $ac_cv_lib_gcrypt_gcry_control" >&5
! echo "${ECHO_T}$ac_cv_lib_gcrypt_gcry_control" >&6
! if test $ac_cv_lib_gcrypt_gcry_control = yes; then
    cat >>confdefs.h <<_ACEOF
! #define HAVE_LIBGCRYPT 1
  _ACEOF
  
!   LIBS="-lgcrypt $LIBS"
  
  else
!   { { echo "$as_me:$LINENO: error: library 'gcrypt' is required for GnuTLS" >&5
! echo "$as_me: error: library 'gcrypt' is required for GnuTLS" >&2;}
     { (exit 1); exit 1; }; }
  fi
  
! fi
  
! if test "$with_pam" = yes ; then
! 
! echo "$as_me:$LINENO: checking for pam_start in -lpam" >&5
! echo $ECHO_N "checking for pam_start in -lpam... $ECHO_C" >&6
! if test "${ac_cv_lib_pam_pam_start+set}" = set; then
    echo $ECHO_N "(cached) $ECHO_C" >&6
  else
    ac_check_lib_save_LIBS=$LIBS
! LIBS="-lpam  $LIBS"
  cat >conftest.$ac_ext <<_ACEOF
  /* confdefs.h.  */
  _ACEOF
***************
*** 7439,7449 ****
  #endif
  /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
! char ldap_bind ();
  int
  main ()
  {
! ldap_bind ();
    ;
    return 0;
  }
--- 7444,7454 ----
  #endif
  /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
! char pam_start ();
  int
  main ()
  {
! pam_start ();
    ;
    return 0;
  }
***************
*** 7457,7464 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 7462,7468 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 7470,7566 ****
    ac_status=$?
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); }; }; then
!   ac_cv_lib_wldap32_ldap_bind=yes
  else
    echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
  
! ac_cv_lib_wldap32_ldap_bind=no
  fi
  rm -f conftest.err conftest.$ac_objext \
        conftest$ac_exeext conftest.$ac_ext
  LIBS=$ac_check_lib_save_LIBS
  fi
! echo "$as_me:$LINENO: result: $ac_cv_lib_wldap32_ldap_bind" >&5
! echo "${ECHO_T}$ac_cv_lib_wldap32_ldap_bind" >&6
! if test $ac_cv_lib_wldap32_ldap_bind = yes; then
    cat >>confdefs.h <<_ACEOF
! #define HAVE_LIBWLDAP32 1
  _ACEOF
  
!   LIBS="-lwldap32 $LIBS"
  
  else
!   { { echo "$as_me:$LINENO: error: library 'wldap32' is required for LDAP" >&5
! echo "$as_me: error: library 'wldap32' is required for LDAP" >&2;}
     { (exit 1); exit 1; }; }
  fi
  
-   fi
  fi
  
- ##
- ## Header files
- ##
  
! echo "$as_me:$LINENO: checking for ANSI C header files" >&5
! echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
! if test "${ac_cv_header_stdc+set}" = set; then
    echo $ECHO_N "(cached) $ECHO_C" >&6
  else
!   cat >conftest.$ac_ext <<_ACEOF
  /* confdefs.h.  */
  _ACEOF
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
- #include <stdlib.h>
- #include <stdarg.h>
- #include <string.h>
- #include <float.h>
  
  int
  main ()
  {
! 
    ;
    return 0;
  }
  _ACEOF
! rm -f conftest.$ac_objext
! if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
!   (eval $ac_compile) 2>conftest.er1
    ac_status=$?
    grep -v '^ *+' conftest.er1 >conftest.err
    rm -f conftest.er1
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (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); }; } &&
! 	 { ac_try='test -s conftest.$ac_objext'
    { (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_header_stdc=yes
  else
    echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
  
! ac_cv_header_stdc=no
  fi
! rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
! 
! if test $ac_cv_header_stdc = yes; then
!   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
!   cat >conftest.$ac_ext <<_ACEOF
  /* confdefs.h.  */
  _ACEOF
  cat confdefs.h >>conftest.$ac_ext
--- 7474,7729 ----
    ac_status=$?
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); }; }; then
!   ac_cv_lib_pam_pam_start=yes
  else
    echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
  
! ac_cv_lib_pam_pam_start=no
  fi
  rm -f conftest.err conftest.$ac_objext \
        conftest$ac_exeext conftest.$ac_ext
  LIBS=$ac_check_lib_save_LIBS
  fi
! echo "$as_me:$LINENO: result: $ac_cv_lib_pam_pam_start" >&5
! echo "${ECHO_T}$ac_cv_lib_pam_pam_start" >&6
! if test $ac_cv_lib_pam_pam_start = yes; then
    cat >>confdefs.h <<_ACEOF
! #define HAVE_LIBPAM 1
  _ACEOF
  
!   LIBS="-lpam $LIBS"
  
  else
!   { { echo "$as_me:$LINENO: error: library 'pam' is required for PAM" >&5
! echo "$as_me: error: library 'pam' is required for PAM" >&2;}
     { (exit 1); exit 1; }; }
  fi
  
  fi
  
  
! if test "$with_ldap" = yes ; then
!   if test "$PORTNAME" != "win32"; then
! 
! echo "$as_me:$LINENO: checking for ldap_bind in -lldap" >&5
! echo $ECHO_N "checking for ldap_bind in -lldap... $ECHO_C" >&6
! if test "${ac_cv_lib_ldap_ldap_bind+set}" = set; then
    echo $ECHO_N "(cached) $ECHO_C" >&6
  else
!   ac_check_lib_save_LIBS=$LIBS
! LIBS="-lldap  $LIBS"
! cat >conftest.$ac_ext <<_ACEOF
  /* confdefs.h.  */
  _ACEOF
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end 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 ldap_bind ();
  int
  main ()
  {
! ldap_bind ();
    ;
    return 0;
  }
  _ACEOF
! rm -f conftest.$ac_objext conftest$ac_exeext
! if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
!   (eval $ac_link) 2>conftest.er1
    ac_status=$?
    grep -v '^ *+' conftest.er1 >conftest.err
    rm -f conftest.er1
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (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); }; } &&
! 	 { 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_ldap_ldap_bind=yes
  else
    echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
  
! ac_cv_lib_ldap_ldap_bind=no
  fi
! rm -f conftest.err conftest.$ac_objext \
!       conftest$ac_exeext conftest.$ac_ext
! LIBS=$ac_check_lib_save_LIBS
! fi
! echo "$as_me:$LINENO: result: $ac_cv_lib_ldap_ldap_bind" >&5
! echo "${ECHO_T}$ac_cv_lib_ldap_ldap_bind" >&6
! if test $ac_cv_lib_ldap_ldap_bind = yes; then
!   cat >>confdefs.h <<_ACEOF
! #define HAVE_LIBLDAP 1
! _ACEOF
! 
!   LIBS="-lldap $LIBS"
! 
! else
!   { { echo "$as_me:$LINENO: error: library 'ldap' is required for LDAP" >&5
! echo "$as_me: error: library 'ldap' is required for LDAP" >&2;}
!    { (exit 1); exit 1; }; }
! fi
! 
!   else
! 
! echo "$as_me:$LINENO: checking for ldap_bind in -lwldap32" >&5
! echo $ECHO_N "checking for ldap_bind in -lwldap32... $ECHO_C" >&6
! if test "${ac_cv_lib_wldap32_ldap_bind+set}" = set; then
!   echo $ECHO_N "(cached) $ECHO_C" >&6
! else
!   ac_check_lib_save_LIBS=$LIBS
! LIBS="-lwldap32  $LIBS"
! cat >conftest.$ac_ext <<_ACEOF
! /* confdefs.h.  */
! _ACEOF
! cat confdefs.h >>conftest.$ac_ext
! cat >>conftest.$ac_ext <<_ACEOF
! /* end 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 ldap_bind ();
! int
! main ()
! {
! ldap_bind ();
!   ;
!   return 0;
! }
! _ACEOF
! rm -f conftest.$ac_objext conftest$ac_exeext
! if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
!   (eval $ac_link) 2>conftest.er1
!   ac_status=$?
!   grep -v '^ *+' conftest.er1 >conftest.err
!   rm -f conftest.er1
!   cat conftest.err >&5
!   echo "$as_me:$LINENO: \$? = $ac_status" >&5
!   (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
!   { (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); }; } &&
! 	 { 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_wldap32_ldap_bind=yes
! else
!   echo "$as_me: failed program was:" >&5
! sed 's/^/| /' conftest.$ac_ext >&5
! 
! ac_cv_lib_wldap32_ldap_bind=no
! fi
! rm -f conftest.err conftest.$ac_objext \
!       conftest$ac_exeext conftest.$ac_ext
! LIBS=$ac_check_lib_save_LIBS
! fi
! echo "$as_me:$LINENO: result: $ac_cv_lib_wldap32_ldap_bind" >&5
! echo "${ECHO_T}$ac_cv_lib_wldap32_ldap_bind" >&6
! if test $ac_cv_lib_wldap32_ldap_bind = yes; then
!   cat >>confdefs.h <<_ACEOF
! #define HAVE_LIBWLDAP32 1
! _ACEOF
! 
!   LIBS="-lwldap32 $LIBS"
! 
! else
!   { { echo "$as_me:$LINENO: error: library 'wldap32' is required for LDAP" >&5
! echo "$as_me: error: library 'wldap32' is required for LDAP" >&2;}
!    { (exit 1); exit 1; }; }
! fi
! 
!   fi
! fi
! 
! ##
! ## Header files
! ##
! 
! echo "$as_me:$LINENO: checking for ANSI C header files" >&5
! echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
! if test "${ac_cv_header_stdc+set}" = set; then
!   echo $ECHO_N "(cached) $ECHO_C" >&6
! else
!   cat >conftest.$ac_ext <<_ACEOF
! /* confdefs.h.  */
! _ACEOF
! cat confdefs.h >>conftest.$ac_ext
! cat >>conftest.$ac_ext <<_ACEOF
! /* end confdefs.h.  */
! #include <stdlib.h>
! #include <stdarg.h>
! #include <string.h>
! #include <float.h>
! 
! int
! main ()
! {
! 
!   ;
!   return 0;
! }
! _ACEOF
! rm -f conftest.$ac_objext
! if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
!   (eval $ac_compile) 2>conftest.er1
!   ac_status=$?
!   grep -v '^ *+' conftest.er1 >conftest.err
!   rm -f conftest.er1
!   cat conftest.err >&5
!   echo "$as_me:$LINENO: \$? = $ac_status" >&5
!   (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
!   { (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); }; } &&
! 	 { ac_try='test -s conftest.$ac_objext'
!   { (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_header_stdc=yes
! else
!   echo "$as_me: failed program was:" >&5
! sed 's/^/| /' conftest.$ac_ext >&5
! 
! ac_cv_header_stdc=no
! fi
! rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
! 
! if test $ac_cv_header_stdc = yes; then
!   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
!   cat >conftest.$ac_ext <<_ACEOF
  /* confdefs.h.  */
  _ACEOF
  cat confdefs.h >>conftest.$ac_ext
***************
*** 7707,7714 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 7870,7876 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 7799,7806 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 7961,7967 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 7952,7959 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 8113,8119 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 8100,8107 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 8260,8266 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 8169,8176 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 8328,8334 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 8316,8323 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 8474,8480 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 8480,8487 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 8637,8643 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 8627,8634 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 8783,8789 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 8798,8805 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 8953,8959 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 8945,8952 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 9099,9105 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 9092,9099 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 9245,9251 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 9260,9267 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 9412,9418 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 9407,9414 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 9558,9564 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 9554,9561 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 9704,9710 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 9721,9728 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 9870,9876 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 9876,9883 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 10024,10030 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 10025,10032 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 10172,10178 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 10171,10178 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 10317,10323 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 10289,10294 ****
--- 10434,10732 ----
  
  fi
  
+ if test "$with_gnutls" = yes ; then
+   if test "${ac_cv_header_gnutls_gnutls_h+set}" = set; then
+   echo "$as_me:$LINENO: checking for gnutls/gnutls.h" >&5
+ echo $ECHO_N "checking for gnutls/gnutls.h... $ECHO_C" >&6
+ if test "${ac_cv_header_gnutls_gnutls_h+set}" = set; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ fi
+ echo "$as_me:$LINENO: result: $ac_cv_header_gnutls_gnutls_h" >&5
+ echo "${ECHO_T}$ac_cv_header_gnutls_gnutls_h" >&6
+ else
+   # Is the header compilable?
+ echo "$as_me:$LINENO: checking gnutls/gnutls.h usability" >&5
+ echo $ECHO_N "checking gnutls/gnutls.h usability... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ $ac_includes_default
+ #include <gnutls/gnutls.h>
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+   (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+ 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+   { (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); }; } &&
+ 	 { ac_try='test -s conftest.$ac_objext'
+   { (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_header_compiler=yes
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+ 
+ ac_header_compiler=no
+ fi
+ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+ echo "${ECHO_T}$ac_header_compiler" >&6
+ 
+ # Is the header present?
+ echo "$as_me:$LINENO: checking gnutls/gnutls.h presence" >&5
+ echo $ECHO_N "checking gnutls/gnutls.h presence... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ #include <gnutls/gnutls.h>
+ _ACEOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+   (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } >/dev/null; then
+   if test -s conftest.err; then
+     ac_cpp_err=$ac_c_preproc_warn_flag
+     ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+   else
+     ac_cpp_err=
+   fi
+ else
+   ac_cpp_err=yes
+ fi
+ if test -z "$ac_cpp_err"; then
+   ac_header_preproc=yes
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+ 
+   ac_header_preproc=no
+ fi
+ rm -f conftest.err conftest.$ac_ext
+ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+ echo "${ECHO_T}$ac_header_preproc" >&6
+ 
+ # So?  What about this header?
+ case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+   yes:no: )
+     { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: accepted by the compiler, rejected by the preprocessor!" >&5
+ echo "$as_me: WARNING: gnutls/gnutls.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+     { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: proceeding with the compiler's result" >&5
+ echo "$as_me: WARNING: gnutls/gnutls.h: proceeding with the compiler's result" >&2;}
+     ac_header_preproc=yes
+     ;;
+   no:yes:* )
+     { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: present but cannot be compiled" >&5
+ echo "$as_me: WARNING: gnutls/gnutls.h: present but cannot be compiled" >&2;}
+     { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h:     check for missing prerequisite headers?" >&5
+ echo "$as_me: WARNING: gnutls/gnutls.h:     check for missing prerequisite headers?" >&2;}
+     { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: see the Autoconf documentation" >&5
+ echo "$as_me: WARNING: gnutls/gnutls.h: see the Autoconf documentation" >&2;}
+     { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h:     section \"Present But Cannot Be Compiled\"" >&5
+ echo "$as_me: WARNING: gnutls/gnutls.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+     { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: proceeding with the preprocessor's result" >&5
+ echo "$as_me: WARNING: gnutls/gnutls.h: proceeding with the preprocessor's result" >&2;}
+     { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: in the future, the compiler will take precedence" >&5
+ echo "$as_me: WARNING: gnutls/gnutls.h: in the future, the compiler will take precedence" >&2;}
+     (
+       cat <<\_ASBOX
+ ## ---------------------------------------- ##
+ ## Report this to pgsql-bugs@postgresql.org ##
+ ## ---------------------------------------- ##
+ _ASBOX
+     ) |
+       sed "s/^/$as_me: WARNING:     /" >&2
+     ;;
+ esac
+ echo "$as_me:$LINENO: checking for gnutls/gnutls.h" >&5
+ echo $ECHO_N "checking for gnutls/gnutls.h... $ECHO_C" >&6
+ if test "${ac_cv_header_gnutls_gnutls_h+set}" = set; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   ac_cv_header_gnutls_gnutls_h=$ac_header_preproc
+ fi
+ echo "$as_me:$LINENO: result: $ac_cv_header_gnutls_gnutls_h" >&5
+ echo "${ECHO_T}$ac_cv_header_gnutls_gnutls_h" >&6
+ 
+ fi
+ if test $ac_cv_header_gnutls_gnutls_h = yes; then
+   :
+ else
+   { { echo "$as_me:$LINENO: error: header file <gnutls/gnutls.h> is required for GnuTLS" >&5
+ echo "$as_me: error: header file <gnutls/gnutls.h> is required for GnuTLS" >&2;}
+    { (exit 1); exit 1; }; }
+ fi
+ 
+ 
+   if test "${ac_cv_header_gcrypt_h+set}" = set; then
+   echo "$as_me:$LINENO: checking for gcrypt.h" >&5
+ echo $ECHO_N "checking for gcrypt.h... $ECHO_C" >&6
+ if test "${ac_cv_header_gcrypt_h+set}" = set; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ fi
+ echo "$as_me:$LINENO: result: $ac_cv_header_gcrypt_h" >&5
+ echo "${ECHO_T}$ac_cv_header_gcrypt_h" >&6
+ else
+   # Is the header compilable?
+ echo "$as_me:$LINENO: checking gcrypt.h usability" >&5
+ echo $ECHO_N "checking gcrypt.h usability... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ $ac_includes_default
+ #include <gcrypt.h>
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+   (eval $ac_compile) 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+ 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+   { (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); }; } &&
+ 	 { ac_try='test -s conftest.$ac_objext'
+   { (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_header_compiler=yes
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+ 
+ ac_header_compiler=no
+ fi
+ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+ echo "${ECHO_T}$ac_header_compiler" >&6
+ 
+ # Is the header present?
+ echo "$as_me:$LINENO: checking gcrypt.h presence" >&5
+ echo $ECHO_N "checking gcrypt.h presence... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ #include <gcrypt.h>
+ _ACEOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+   (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } >/dev/null; then
+   if test -s conftest.err; then
+     ac_cpp_err=$ac_c_preproc_warn_flag
+     ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+   else
+     ac_cpp_err=
+   fi
+ else
+   ac_cpp_err=yes
+ fi
+ if test -z "$ac_cpp_err"; then
+   ac_header_preproc=yes
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+ 
+   ac_header_preproc=no
+ fi
+ rm -f conftest.err conftest.$ac_ext
+ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+ echo "${ECHO_T}$ac_header_preproc" >&6
+ 
+ # So?  What about this header?
+ case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+   yes:no: )
+     { echo "$as_me:$LINENO: WARNING: gcrypt.h: accepted by the compiler, rejected by the preprocessor!" >&5
+ echo "$as_me: WARNING: gcrypt.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+     { echo "$as_me:$LINENO: WARNING: gcrypt.h: proceeding with the compiler's result" >&5
+ echo "$as_me: WARNING: gcrypt.h: proceeding with the compiler's result" >&2;}
+     ac_header_preproc=yes
+     ;;
+   no:yes:* )
+     { echo "$as_me:$LINENO: WARNING: gcrypt.h: present but cannot be compiled" >&5
+ echo "$as_me: WARNING: gcrypt.h: present but cannot be compiled" >&2;}
+     { echo "$as_me:$LINENO: WARNING: gcrypt.h:     check for missing prerequisite headers?" >&5
+ echo "$as_me: WARNING: gcrypt.h:     check for missing prerequisite headers?" >&2;}
+     { echo "$as_me:$LINENO: WARNING: gcrypt.h: see the Autoconf documentation" >&5
+ echo "$as_me: WARNING: gcrypt.h: see the Autoconf documentation" >&2;}
+     { echo "$as_me:$LINENO: WARNING: gcrypt.h:     section \"Present But Cannot Be Compiled\"" >&5
+ echo "$as_me: WARNING: gcrypt.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+     { echo "$as_me:$LINENO: WARNING: gcrypt.h: proceeding with the preprocessor's result" >&5
+ echo "$as_me: WARNING: gcrypt.h: proceeding with the preprocessor's result" >&2;}
+     { echo "$as_me:$LINENO: WARNING: gcrypt.h: in the future, the compiler will take precedence" >&5
+ echo "$as_me: WARNING: gcrypt.h: in the future, the compiler will take precedence" >&2;}
+     (
+       cat <<\_ASBOX
+ ## ---------------------------------------- ##
+ ## Report this to pgsql-bugs@postgresql.org ##
+ ## ---------------------------------------- ##
+ _ASBOX
+     ) |
+       sed "s/^/$as_me: WARNING:     /" >&2
+     ;;
+ esac
+ echo "$as_me:$LINENO: checking for gcrypt.h" >&5
+ echo $ECHO_N "checking for gcrypt.h... $ECHO_C" >&6
+ if test "${ac_cv_header_gcrypt_h+set}" = set; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   ac_cv_header_gcrypt_h=$ac_header_preproc
+ fi
+ echo "$as_me:$LINENO: result: $ac_cv_header_gcrypt_h" >&5
+ echo "${ECHO_T}$ac_cv_header_gcrypt_h" >&6
+ 
+ fi
+ if test $ac_cv_header_gcrypt_h = yes; then
+   :
+ else
+   { { echo "$as_me:$LINENO: error: header file <gcrypt.h> is required for GnuTLS" >&5
+ echo "$as_me: error: header file <gcrypt.h> is required for GnuTLS" >&2;}
+    { (exit 1); exit 1; }; }
+ fi
+ 
+ 
+ fi
+ 
  if test "$with_pam" = yes ; then
  
  for ac_header in security/pam_appl.h
***************
*** 10324,10331 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 10762,10768 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 10471,10478 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 10908,10914 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 10633,10640 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 11069,11075 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 10784,10791 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 11219,11225 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 10855,10862 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 11289,11295 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 11053,11060 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 11486,11492 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 11115,11122 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 11547,11553 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 11216,11223 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 11647,11653 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 11278,11285 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 11708,11714 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 11339,11346 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 11768,11774 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 11399,11406 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 11827,11833 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 11462,11469 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 11889,11895 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 11528,11535 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 11954,11960 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 11575,11582 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 12000,12006 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 11650,11657 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 12074,12080 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 11718,11725 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 12141,12147 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 11788,11795 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 12210,12216 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 11862,11869 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 12283,12289 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 11931,11938 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 12351,12357 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 11980,11987 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 12399,12405 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 12050,12057 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 12468,12474 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 12099,12106 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 12516,12522 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 12169,12176 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 12585,12591 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 12218,12225 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 12633,12639 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 12288,12295 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 12702,12708 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 12337,12344 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 12750,12756 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 12407,12414 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 12819,12825 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 12455,12463 ****
    rm -f conftest.er1
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
!   (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 12866,12873 ----
    rm -f conftest.er1
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
!   (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 12527,12534 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 12937,12943 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 12597,12604 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 13006,13012 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 12665,12672 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 13073,13079 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 12733,12740 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 13140,13146 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 12802,12809 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 13208,13214 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 12873,12880 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 13278,13284 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 12943,12950 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 13347,13353 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 12988,12995 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 13391,13397 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 13054,13061 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 13456,13462 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 13099,13106 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 13500,13506 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 13172,13179 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 13572,13578 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 13217,13224 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 13616,13622 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 13283,13290 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 13681,13687 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 13328,13335 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 13725,13731 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 13405,13412 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 13801,13807 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 13484,13491 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 13879,13885 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 13564,13571 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 13958,13964 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 13659,13666 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 14052,14058 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 13780,13787 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 14172,14178 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 13847,13854 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 14238,14244 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 13923,13930 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 14313,14319 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 13990,13997 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 14379,14385 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 14127,14134 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 14515,14521 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 14231,14238 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 14618,14624 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 14306,14313 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 14692,14698 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 14376,14383 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 14761,14767 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 14450,14457 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 14834,14840 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 14564,14571 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 14947,14953 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 14680,14687 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 15062,15068 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 14799,14806 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 15180,15186 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 14924,14931 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 15304,15310 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 15074,15081 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 15453,15459 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 15173,15180 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 15551,15557 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 15275,15282 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 15652,15658 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 15340,15347 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 15716,15722 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 15396,15403 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 15771,15777 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 15491,15498 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 15865,15871 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 15547,15554 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 15920,15926 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 15695,15702 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 16067,16073 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 15798,15805 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 16169,16175 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 15901,15908 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 16271,16277 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 16005,16012 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 16374,16380 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 16105,16112 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 16473,16479 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 16177,16184 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 16544,16550 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 16222,16229 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 16588,16594 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 16288,16295 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 16653,16659 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 16387,16394 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 16751,16757 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 16572,16579 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 16935,16941 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 16661,16668 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 17023,17029 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 16708,16715 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 17069,17075 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 16899,16906 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 17259,17265 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 17087,17094 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 17446,17452 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 17157,17164 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 17515,17521 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 17223,17230 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 17580,17586 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 17424,17431 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 17780,17786 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 17550,17557 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 17905,17911 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 17672,17679 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 18026,18032 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 17860,17867 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 18213,18219 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 17923,17930 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 18275,18281 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 17964,17971 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 18315,18321 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 18021,18028 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 18371,18377 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 18062,18069 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 18411,18417 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 18127,18134 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 18475,18481 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 18159,18168 ****
  esac
  else
    if test "$cross_compiling" = yes; then
!   { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
! See \`config.log' for more details." >&5
! echo "$as_me: error: cannot run test program while cross compiling
! See \`config.log' for more details." >&2;}
     { (exit 1); exit 1; }; }
  else
    cat >conftest.$ac_ext <<_ACEOF
--- 18506,18513 ----
  esac
  else
    if test "$cross_compiling" = yes; then
!   { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
! echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
     { (exit 1); exit 1; }; }
  else
    cat >conftest.$ac_ext <<_ACEOF
***************
*** 18276,18283 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 18621,18627 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 18339,18346 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 18683,18689 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 18380,18387 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 18723,18729 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 18437,18444 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 18779,18785 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 18478,18485 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 18819,18825 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 18543,18550 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 18883,18889 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 18575,18584 ****
  esac
  else
    if test "$cross_compiling" = yes; then
!   { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
! See \`config.log' for more details." >&5
! echo "$as_me: error: cannot run test program while cross compiling
! See \`config.log' for more details." >&2;}
     { (exit 1); exit 1; }; }
  else
    cat >conftest.$ac_ext <<_ACEOF
--- 18914,18921 ----
  esac
  else
    if test "$cross_compiling" = yes; then
!   { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
! echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
     { (exit 1); exit 1; }; }
  else
    cat >conftest.$ac_ext <<_ACEOF
***************
*** 18693,18700 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 19030,19036 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 18753,18760 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 19089,19095 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 18795,18802 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 19130,19136 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 18853,18860 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 19187,19193 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 18895,18902 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 19228,19234 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 18961,18968 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 19293,19299 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 18991,19000 ****
  esac
  else
    if test "$cross_compiling" = yes; then
!   { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
! See \`config.log' for more details." >&5
! echo "$as_me: error: cannot run test program while cross compiling
! See \`config.log' for more details." >&2;}
     { (exit 1); exit 1; }; }
  else
    cat >conftest.$ac_ext <<_ACEOF
--- 19322,19329 ----
  esac
  else
    if test "$cross_compiling" = yes; then
!   { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
! echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
     { (exit 1); exit 1; }; }
  else
    cat >conftest.$ac_ext <<_ACEOF
***************
*** 19105,19112 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 19434,19440 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 19165,19172 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 19493,19499 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 19207,19214 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 19534,19540 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 19265,19272 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 19591,19597 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 19307,19314 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 19632,19638 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 19373,19380 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 19697,19703 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 19403,19412 ****
  esac
  else
    if test "$cross_compiling" = yes; then
!   { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
! See \`config.log' for more details." >&5
! echo "$as_me: error: cannot run test program while cross compiling
! See \`config.log' for more details." >&2;}
     { (exit 1); exit 1; }; }
  else
    cat >conftest.$ac_ext <<_ACEOF
--- 19726,19733 ----
  esac
  else
    if test "$cross_compiling" = yes; then
!   { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
! echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
     { (exit 1); exit 1; }; }
  else
    cat >conftest.$ac_ext <<_ACEOF
***************
*** 19517,19524 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 19838,19844 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 19577,19584 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 19897,19903 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 19619,19626 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 19938,19944 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 19677,19684 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 19995,20001 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 19719,19726 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 20036,20042 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 19785,19792 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 20101,20107 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 19815,19824 ****
  esac
  else
    if test "$cross_compiling" = yes; then
!   { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
! See \`config.log' for more details." >&5
! echo "$as_me: error: cannot run test program while cross compiling
! See \`config.log' for more details." >&2;}
     { (exit 1); exit 1; }; }
  else
    cat >conftest.$ac_ext <<_ACEOF
--- 20130,20137 ----
  esac
  else
    if test "$cross_compiling" = yes; then
!   { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
! echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
     { (exit 1); exit 1; }; }
  else
    cat >conftest.$ac_ext <<_ACEOF
***************
*** 19930,19937 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 20243,20249 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 19990,19997 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 20302,20308 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 20032,20039 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 20343,20349 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 20090,20097 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 20400,20406 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 20132,20139 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 20441,20447 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 20198,20205 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 20506,20512 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 20228,20237 ****
  esac
  else
    if test "$cross_compiling" = yes; then
!   { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
! See \`config.log' for more details." >&5
! echo "$as_me: error: cannot run test program while cross compiling
! See \`config.log' for more details." >&2;}
     { (exit 1); exit 1; }; }
  else
    cat >conftest.$ac_ext <<_ACEOF
--- 20535,20542 ----
  esac
  else
    if test "$cross_compiling" = yes; then
!   { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
! echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
     { (exit 1); exit 1; }; }
  else
    cat >conftest.$ac_ext <<_ACEOF
***************
*** 20343,20350 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 20648,20654 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 20403,20410 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 20707,20713 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 20445,20452 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 20748,20754 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 20503,20510 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 20805,20811 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 20545,20552 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 20846,20852 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 20611,20618 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 20911,20917 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 20641,20650 ****
  esac
  else
    if test "$cross_compiling" = yes; then
!   { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
! See \`config.log' for more details." >&5
! echo "$as_me: error: cannot run test program while cross compiling
! See \`config.log' for more details." >&2;}
     { (exit 1); exit 1; }; }
  else
    cat >conftest.$ac_ext <<_ACEOF
--- 20940,20947 ----
  esac
  else
    if test "$cross_compiling" = yes; then
!   { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
! echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
     { (exit 1); exit 1; }; }
  else
    cat >conftest.$ac_ext <<_ACEOF
***************
*** 20780,20787 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 21077,21083 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 20848,20855 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 21144,21150 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 20916,20923 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 21211,21217 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 20984,20991 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 21278,21284 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 21053,21060 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 21346,21352 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 21123,21130 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 21415,21421 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 21221,21228 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 21512,21518 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 21251,21258 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 21541,21547 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 21322,21329 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 21611,21617 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 21375,21382 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 21663,21669 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 21447,21454 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 21734,21740 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 21500,21507 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 21786,21792 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 21717,21724 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 22002,22008 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 21772,21779 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 22056,22062 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 21839,21846 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 22122,22128 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 22219,22226 ****
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"
! 			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
--- 22501,22507 ----
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    (exit $ac_status); } &&
! 	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
    { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
    (eval $ac_try) 2>&5
    ac_status=$?
***************
*** 23436,23441 ****
--- 23717,23723 ----
  s,@with_ldap@,$with_ldap,;t t
  s,@with_bonjour@,$with_bonjour,;t t
  s,@with_openssl@,$with_openssl,;t t
+ s,@with_gnutls@,$with_gnutls,;t t
  s,@with_zlib@,$with_zlib,;t t
  s,@EGREP@,$EGREP,;t t
  s,@ELF_SYS@,$ELF_SYS,;t t
***************
*** 23657,23667 ****
  
  
  
-   if test x"$ac_file" != x-; then
-     { echo "$as_me:$LINENO: creating $ac_file" >&5
- echo "$as_me: creating $ac_file" >&6;}
-     rm -f "$ac_file"
-   fi
    # Let's still pretend it is `configure' which instantiates (i.e., don't
    # use $as_me), people would be surprised to read:
    #    /* config.h.  Generated by config.status.  */
--- 23939,23944 ----
***************
*** 23700,23705 ****
--- 23977,23988 ----
  	 fi;;
        esac
      done` || { (exit 1); exit 1; }
+ 
+   if test x"$ac_file" != x-; then
+     { echo "$as_me:$LINENO: creating $ac_file" >&5
+ echo "$as_me: creating $ac_file" >&6;}
+     rm -f "$ac_file"
+   fi
  _ACEOF
  cat >>$CONFIG_STATUS <<_ACEOF
    sed "$ac_vpsub
Index: src/include/pg_config.h.in
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/pg_config.h.in,v
retrieving revision 1.96
diff -c -r1.96 pg_config.h.in
*** src/include/pg_config.h.in	29 Apr 2006 20:47:31 -0000	1.96
--- src/include/pg_config.h.in	4 May 2006 13:36:02 -0000
***************
*** 213,218 ****
--- 213,224 ----
  /* Define to 1 if you have the `eay32' library (-leay32). */
  #undef HAVE_LIBEAY32
  
+ /* Define to 1 if you have the `gcrypt' library (-lgcrypt). */
+ #undef HAVE_LIBGCRYPT
+ 
+ /* Define to 1 if you have the `gnutls' library (-lgnutls). */
+ #undef HAVE_LIBGNUTLS
+ 
  /* Define to 1 if you have the `ldap' library (-lldap). */
  #undef HAVE_LIBLDAP
  
***************
*** 613,621 ****
  /* Use replacement snprintf() functions. */
  #undef USE_REPL_SNPRINTF
  
! /* Define to build with (Open)SSL support. (--with-openssl) */
  #undef USE_SSL
  
  /* Define to select SysV-style semaphores. */
  #undef USE_SYSV_SEMAPHORES
  
--- 619,633 ----
  /* Use replacement snprintf() functions. */
  #undef USE_REPL_SNPRINTF
  
! /* Define to build with SSL support (select either OpenSSL or GnuTLS) */
  #undef USE_SSL
  
+ /* Define to build with GnuTLS (SSL) support. (--with-gnutls) */
+ #undef USE_SSL_GNUTLS
+ 
+ /* Define to build with (Open)SSL support. (--with-openssl) */
+ #undef USE_SSL_OPENSSL
+ 
  /* Define to select SysV-style semaphores. */
  #undef USE_SYSV_SEMAPHORES
  
