Hi Tatsuo, On Wed, Feb 03, 2010 at 06:44:50PM +0900, Tatsuo Ishii wrote: > Here is the header of my pool_ssl.c: > > * $Header: /cvsroot/pgpool/pgpool-II/pool_ssl.c,v 1.3 2010/01/31 > 13:28:00 t-ishii Exp $ > > The file size is 5879 bytes. If these are same as yours, then the
I get the same. strange!
> problem must be with my patch program:-< In this can you send me
> patched pool_ssl.c?
Attached is the updated pool_ssl.c as well as the output of cvs diff
-u after applying the patch. interdiff doesn't show me any differences
between the patches, though.
sean
/* -*-pgsql-c-*- */
/*
* $Header: /cvsroot/pgpool/pgpool-II/pool_ssl.c,v 1.3 2010/01/31 13:28:00 t-ishii Exp $
*
* pgpool: a language independent connection pool server for PostgreSQL
* written by Tatsuo Ishii
*
* Copyright (c) 2003-2010 PgPool Global Development Group
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby
* granted, provided that the above copyright notice appear in all
* copies and that both that copyright notice and this permission
* notice appear in supporting documentation, and that the name of the
* author not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior
* permission. The author makes no representations about the
* suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* pool_ssl.c: ssl negotiation functions
*
*/
#include <string.h>
#include "config.h"
#include "pool.h"
#ifdef USE_SSL
#define SSL_RETURN_VOID_IF(cond, msg) \
do { \
if ( (cond) ) { \
perror_ssl( (msg) ); \
return; \
} \
} while (0);
#define SSL_RETURN_ERROR_IF(cond, msg) \
do { \
if ( (cond) ) { \
perror_ssl( (msg) ); \
return -1; \
} \
} while (0);
#include <arpa/inet.h> /* for htonl() */
/* Major/minor codes to negotiate SSL prior to startup packet */
#define NEGOTIATE_SSL_CODE ( 1234<<16 | 5679 )
/* enum flag for differentiating server->client vs client->server SSL */
enum ssl_conn_type { ssl_conn_clientserver, ssl_conn_serverclient };
/* perform per-connection ssl initialization. returns nonzero on error */
static int init_ssl_ctx(POOL_CONNECTION *cp, enum ssl_conn_type conntype);
/* OpenSSL error message */
static void perror_ssl(const char *context);
/* attempt to negotiate a secure connection */
void pool_ssl_negotiate_clientserver(POOL_CONNECTION *cp) {
int ssl_packet[2] = { htonl(sizeof(int)*2), htonl(NEGOTIATE_SSL_CODE) };
char server_response;
cp->ssl_active = -1;
if ( (!pool_config->ssl) || init_ssl_ctx(cp, ssl_conn_clientserver))
return;
pool_debug("pool_ssl: sending client->server SSL request");
pool_write_and_flush(cp, ssl_packet, sizeof(int)*2);
pool_read(cp, &server_response, 1);
pool_debug("pool_ssl: client->server SSL response: %c", server_response);
switch (server_response) {
case 'S':
SSL_set_fd(cp->ssl, cp->fd);
SSL_RETURN_VOID_IF( (SSL_connect(cp->ssl) < 0),
"SSL_connect");
cp->ssl_active = 1;
break;
case 'N':
pool_error("pool_ssl: server doesn't want to talk SSL");
break;
default:
pool_error("pool_ssl: unhandled response: %c", server_response);
break;
}
}
/* attempt to negotiate a secure connection */
void pool_ssl_negotiate_serverclient(POOL_CONNECTION *cp) {
cp->ssl_active = -1;
if ( (!pool_config->ssl) || init_ssl_ctx(cp, ssl_conn_serverclient)) {
/* write back an "SSL reject" response before returning */
pool_write_and_flush(cp, "N", 1);
} else {
/* write back an "SSL accept" response */
pool_write_and_flush(cp, "S", 1);
SSL_set_fd(cp->ssl, cp->fd);
SSL_RETURN_VOID_IF( (SSL_accept(cp->ssl) < 0), "SSL_accept");
cp->ssl_active = 1;
}
}
void pool_ssl_close(POOL_CONNECTION *cp) {
if (cp->ssl) {
SSL_shutdown(cp->ssl);
SSL_free(cp->ssl);
}
if (cp->ssl_ctx)
SSL_CTX_free(cp->ssl_ctx);
}
int pool_ssl_read(POOL_CONNECTION *cp, void *buf, int size) {
return SSL_read(cp->ssl, buf, size);
}
int pool_ssl_write(POOL_CONNECTION *cp, const void *buf, int size) {
return SSL_write(cp->ssl, buf, size);
}
static int init_ssl_ctx(POOL_CONNECTION *cp, enum ssl_conn_type conntype) {
int error = 0;
char *cacert = NULL, *cacert_dir = NULL;
/* initialize SSL members */
cp->ssl_ctx = SSL_CTX_new(TLSv1_method());
SSL_RETURN_ERROR_IF( (! cp->ssl_ctx), "SSL_CTX_new" );
if ( conntype == ssl_conn_serverclient) {
error = SSL_CTX_use_certificate_file(cp->ssl_ctx,
pool_config->ssl_cert,
SSL_FILETYPE_PEM);
SSL_RETURN_ERROR_IF( (error <= 0), "Loading SSL certificate");
error = SSL_CTX_use_PrivateKey_file(cp->ssl_ctx,
pool_config->ssl_key,
SSL_FILETYPE_PEM);
SSL_RETURN_ERROR_IF( (error <= 0), "Loading SSL private key");
} else {
/* set extra verification if ssl_ca_cert or ssl_ca_cert_dir are set */
if (strlen(pool_config->ssl_ca_cert))
cacert = pool_config->ssl_ca_cert;
if (strlen(pool_config->ssl_ca_cert_dir))
cacert_dir = pool_config->ssl_ca_cert_dir;
if ( cacert || cacert_dir ) {
error = (!SSL_CTX_load_verify_locations(cp->ssl_ctx,
cacert,
cacert_dir));
SSL_RETURN_ERROR_IF(error, "SSL verification setup");
SSL_CTX_set_verify(cp->ssl_ctx, SSL_VERIFY_PEER, NULL);
}
}
cp->ssl = SSL_new(cp->ssl_ctx);
SSL_RETURN_ERROR_IF( (! cp->ssl), "SSL_new");
return 0;
}
static void perror_ssl(const char *context) {
unsigned long err;
static const char *no_err_reason = "no SSL error reported";
const char *reason;
err = ERR_get_error();
if (! err) {
reason = no_err_reason;
} else {
reason = ERR_reason_error_string(err);
}
if (reason != NULL) {
pool_error("pool_ssl: %s: %s", context, reason);
} else {
pool_error("pool_ssl: %s: Unknown SSL error %lu", context, err);
}
}
#else /* USE_SSL: wrap / no-op ssl functionality if it's not available */
void pool_ssl_negotiate_serverclient(POOL_CONNECTION *cp) {
pool_debug("pool_ssl: SSL requested but SSL support is not available");
pool_write_and_flush(cp, "N", 1);
cp->ssl_active = -1;
}
void pool_ssl_negotiate_clientserver(POOL_CONNECTION *cp) {
pool_debug("pool_ssl: SSL requested but SSL support is not available");
cp->ssl_active = -1;
}
void pool_ssl_close(POOL_CONNECTION *cp) { return; }
int pool_ssl_read(POOL_CONNECTION *cp, void *buf, int size) {
pool_error("pool_ssl: SSL i/o called but SSL support is not available");
notice_backend_error(cp->db_node_id);
child_exit(1);
return -1; /* never reached */
}
int pool_ssl_write(POOL_CONNECTION *cp, const void *buf, int size) {
pool_error("pool_ssl: SSL i/o called but SSL support is not available");
notice_backend_error(cp->db_node_id);
child_exit(1);
return -1; /* never reached */
}
#endif /* USE_SSL */
Index: pool_ssl.c
===================================================================
RCS file: /cvsroot/pgpool/pgpool-II/pool_ssl.c,v
retrieving revision 1.3
diff -u -r1.3 pool_ssl.c
--- pool_ssl.c 31 Jan 2010 13:28:00 -0000 1.3
+++ pool_ssl.c 3 Feb 2010 10:04:50 -0000
@@ -29,6 +29,22 @@
#ifdef USE_SSL
+#define SSL_RETURN_VOID_IF(cond, msg) \
+ do { \
+ if ( (cond) ) { \
+ perror_ssl( (msg) ); \
+ return; \
+ } \
+ } while (0);
+
+#define SSL_RETURN_ERROR_IF(cond, msg) \
+ do { \
+ if ( (cond) ) { \
+ perror_ssl( (msg) ); \
+ return -1; \
+ } \
+ } while (0);
+
#include <arpa/inet.h> /* for htonl() */
/* Major/minor codes to negotiate SSL prior to startup packet */
@@ -40,6 +56,9 @@
/* perform per-connection ssl initialization. returns nonzero on error */
static int init_ssl_ctx(POOL_CONNECTION *cp, enum ssl_conn_type conntype);
+/* OpenSSL error message */
+static void perror_ssl(const char *context);
+
/* attempt to negotiate a secure connection */
void pool_ssl_negotiate_clientserver(POOL_CONNECTION *cp) {
int ssl_packet[2] = { htonl(sizeof(int)*2), htonl(NEGOTIATE_SSL_CODE) };
@@ -58,11 +77,9 @@
switch (server_response) {
case 'S':
SSL_set_fd(cp->ssl, cp->fd);
- if (SSL_connect(cp->ssl) < 0) {
- pool_error("pool_ssl: SSL_connect failed: %ld", ERR_get_error());
- } else {
- cp->ssl_active = 1;
- }
+ SSL_RETURN_VOID_IF( (SSL_connect(cp->ssl) < 0),
+ "SSL_connect");
+ cp->ssl_active = 1;
break;
case 'N':
pool_error("pool_ssl: server doesn't want to talk SSL");
@@ -87,11 +104,8 @@
pool_write_and_flush(cp, "S", 1);
SSL_set_fd(cp->ssl, cp->fd);
- if (SSL_accept(cp->ssl) < 0) {
- pool_error("pool_ssl: SSL_accept failed: %ld", ERR_get_error());
- } else {
- cp->ssl_active = 1;
- }
+ SSL_RETURN_VOID_IF( (SSL_accept(cp->ssl) < 0), "SSL_accept");
+ cp->ssl_active = 1;
}
}
@@ -119,25 +133,18 @@
/* initialize SSL members */
cp->ssl_ctx = SSL_CTX_new(TLSv1_method());
- if (! cp->ssl_ctx) {
- pool_error("pool_ssl: SSL_CTX_new failed: %ld", ERR_get_error());
- error = -1;
- }
+ SSL_RETURN_ERROR_IF( (! cp->ssl_ctx), "SSL_CTX_new" );
if ( conntype == ssl_conn_serverclient) {
- if ( (!error) && SSL_CTX_use_certificate_file(cp->ssl_ctx,
- pool_config->ssl_cert,
- SSL_FILETYPE_PEM) <= 0) {
- pool_error("pool_ssl: SSL cert failure: %ld", ERR_get_error());
- error = -1;
- }
-
- if ( (!error) && SSL_CTX_use_PrivateKey_file(cp->ssl_ctx,
- pool_config->ssl_key,
- SSL_FILETYPE_PEM) <= 0) {
- pool_error("pool_ssl: SSL key failure: %ld", ERR_get_error());
- error = -1;
- }
+ error = SSL_CTX_use_certificate_file(cp->ssl_ctx,
+ pool_config->ssl_cert,
+ SSL_FILETYPE_PEM);
+ SSL_RETURN_ERROR_IF( (error <= 0), "Loading SSL certificate");
+
+ error = SSL_CTX_use_PrivateKey_file(cp->ssl_ctx,
+ pool_config->ssl_key,
+ SSL_FILETYPE_PEM);
+ SSL_RETURN_ERROR_IF( (error <= 0), "Loading SSL private key");
} else {
/* set extra verification if ssl_ca_cert or ssl_ca_cert_dir are set */
if (strlen(pool_config->ssl_ca_cert))
@@ -145,26 +152,38 @@
if (strlen(pool_config->ssl_ca_cert_dir))
cacert_dir = pool_config->ssl_ca_cert_dir;
- if ( (!error) && (cacert || cacert_dir) ) {
- if (! SSL_CTX_load_verify_locations(cp->ssl_ctx, cacert, cacert_dir)) {
- pool_error("pool_ssl: SSL CA load error: %ld", ERR_get_error());
- error = -1;
- } else {
- SSL_CTX_set_verify(cp->ssl_ctx, SSL_VERIFY_PEER, NULL);
- }
+ if ( cacert || cacert_dir ) {
+ error = (!SSL_CTX_load_verify_locations(cp->ssl_ctx,
+ cacert,
+ cacert_dir));
+ SSL_RETURN_ERROR_IF(error, "SSL verification setup");
+ SSL_CTX_set_verify(cp->ssl_ctx, SSL_VERIFY_PEER, NULL);
}
-
}
- if (! error) {
- cp->ssl = SSL_new(cp->ssl_ctx);
- if (! cp->ssl) {
- pool_error("pool_ssl: SSL_new failed: %ld", ERR_get_error());
- error = -1;
- }
+ cp->ssl = SSL_new(cp->ssl_ctx);
+ SSL_RETURN_ERROR_IF( (! cp->ssl), "SSL_new");
+
+ return 0;
+}
+
+static void perror_ssl(const char *context) {
+ unsigned long err;
+ static const char *no_err_reason = "no SSL error reported";
+ const char *reason;
+
+ err = ERR_get_error();
+ if (! err) {
+ reason = no_err_reason;
+ } else {
+ reason = ERR_reason_error_string(err);
}
- return error;
+ if (reason != NULL) {
+ pool_error("pool_ssl: %s: %s", context, reason);
+ } else {
+ pool_error("pool_ssl: %s: Unknown SSL error %lu", context, err);
+ }
}
#else /* USE_SSL: wrap / no-op ssl functionality if it's not available */
signature.asc
Description: Digital signature
_______________________________________________ Pgpool-hackers mailing list [email protected] http://pgfoundry.org/mailman/listinfo/pgpool-hackers
