Author: kgiusti
Date: Fri Aug 10 18:15:25 2012
New Revision: 1371799
URL: http://svn.apache.org/viewvc?rev=1371799&view=rev
Log:
checkpoint - mailbox ssl worked.
Added:
qpid/proton/branches/driver_abstraction/examples/mailbox/ssl-setup.sh
(with props)
Modified:
qpid/proton/branches/driver_abstraction/examples/mailbox/README.txt
qpid/proton/branches/driver_abstraction/examples/mailbox/fetch
qpid/proton/branches/driver_abstraction/examples/mailbox/post
qpid/proton/branches/driver_abstraction/proton-c/src/driver.c
qpid/proton/branches/driver_abstraction/proton-c/src/driver_impl.h
qpid/proton/branches/driver_abstraction/proton-c/src/drivers/openssl.c
Modified: qpid/proton/branches/driver_abstraction/examples/mailbox/README.txt
URL:
http://svn.apache.org/viewvc/qpid/proton/branches/driver_abstraction/examples/mailbox/README.txt?rev=1371799&r1=1371798&r2=1371799&view=diff
==============================================================================
--- qpid/proton/branches/driver_abstraction/examples/mailbox/README.txt
(original)
+++ qpid/proton/branches/driver_abstraction/examples/mailbox/README.txt Fri Aug
10 18:15:25 2012
@@ -39,3 +39,27 @@ To run the example:
use the --help option for additional details.
Once you are done running the example, you may stop the server application.
+
+
+Optional - using SSL to encrypt the data connections between the server and
the clients:
+
+ The Proton driver library has support for SSL/TLS [1]. The mailbox
example can be
+ configured to use SSL to encypt the connections between the server and the
post/fetch
+ clients.
+
+ Use the ssl-setup.sh script to create the trusted certificates database,
and an
+ identifying certificate for the server.
+
+ Once ssl-setup.sh has created all the necessary certificates, you supply
the server
+ with these parameters:
+
+ $ server --ssl-cert-file ./server-certificate.pem --ssl-key-file
./server-private-key.pem --require-encryption --ssl-cert-db ./trusted_db
--ssl-key-pw "trustno1"
+
+ And give the fetch/post clients the path to the database containing the
trusted
+ certificates:
+
+ $ post -m myMailbox --ssl-cert-db ./trusted_db "Here is a message"
+
+
+[1] At the time of this writing SSL/TLS is implemented using OpenSSL, and is
only
+available on those platforms that support the OpenSSL libraries.
Modified: qpid/proton/branches/driver_abstraction/examples/mailbox/fetch
URL:
http://svn.apache.org/viewvc/qpid/proton/branches/driver_abstraction/examples/mailbox/fetch?rev=1371799&r1=1371798&r2=1371799&view=diff
==============================================================================
--- qpid/proton/branches/driver_abstraction/examples/mailbox/fetch (original)
+++ qpid/proton/branches/driver_abstraction/examples/mailbox/fetch Fri Aug 10
18:15:25 2012
@@ -123,6 +123,10 @@ class FetchClient(object):
d = _next
+ def closed(self):
+ return self.cxtr == None or pn_connector_closed(self.cxtr)
+
+
def enableLogging(self):
self.logging = True
@@ -155,6 +159,9 @@ def main():
# wait until we authenticate with the server
while pn_sasl_state(receiver.sasl) not in (PN_SASL_PASS, PN_SASL_FAIL):
receiver.wait()
+ if receiver.closed():
+ receiver.log("connection failed")
+ return -1;
if pn_sasl_state(receiver.sasl) == PN_SASL_FAIL:
print("Error: Authentication failure")
@@ -163,6 +170,9 @@ def main():
# wait until the server has opened the connection
while not (pn_link_state(receiver.link) & PN_REMOTE_ACTIVE):
receiver.wait()
+ if receiver.closed():
+ receiver.log("connection failed")
+ return -1;
# check if the server recognizes the mailbox, fail if it does not
if pn_remote_source(receiver.link) != options.mailbox:
@@ -176,7 +186,7 @@ def main():
# main loop: continue fetching messages until 'count' messages have been
# retrieved
- while pn_credit(receiver.link) > 0: # while all msgs have not arrived
+ while pn_credit(receiver.link) > 0 and not receiver.closed(): # while
all msgs have not arrived
if pn_queued(receiver.link) == 0: # wait for some to arrive
receiver.wait()
@@ -198,7 +208,7 @@ def main():
receiver.settle()
# block until any leftover deliveries are settled
- while pn_unsettled(receiver.link) > 0:
+ while pn_unsettled(receiver.link) > 0 and not receiver.closed():
receiver.wait()
receiver.settle()
Modified: qpid/proton/branches/driver_abstraction/examples/mailbox/post
URL:
http://svn.apache.org/viewvc/qpid/proton/branches/driver_abstraction/examples/mailbox/post?rev=1371799&r1=1371798&r2=1371799&view=diff
==============================================================================
--- qpid/proton/branches/driver_abstraction/examples/mailbox/post (original)
+++ qpid/proton/branches/driver_abstraction/examples/mailbox/post Fri Aug 10
18:15:25 2012
@@ -72,6 +72,7 @@ class PostClient(object):
self.logging = False
self.ca_database = ca_database
+
def setup(self):
""" Setup and configure the connection to the server.
"""
@@ -143,6 +144,10 @@ class PostClient(object):
d = _next
+ def closed(self):
+ return self.cxtr == None or pn_connector_closed(self.cxtr)
+
+
def enableLogging(self):
self.logging = True
@@ -175,7 +180,11 @@ def main():
# wait until we authenticate with the server
while pn_sasl_state(sender.sasl) not in (PN_SASL_PASS, PN_SASL_FAIL):
+ print("sasl wait...");
sender.wait()
+ if sender.closed():
+ sender.log("connection failed")
+ return -1;
if pn_sasl_state(sender.sasl) == PN_SASL_FAIL:
print("Error: Authentication failure")
@@ -185,12 +194,12 @@ def main():
pendingSends = list(options.messages)
while pendingSends:
- # wait until the server grands us some send credit
+ # wait until the server grants us some send credit
if pn_credit(sender.link) == 0:
sender.log("wait for credit")
sender.wait()
- while pn_credit(sender.link) > 0:
+ while pn_credit(sender.link) > 0 and not sender.closed():
msg = pendingSends.pop(0)
sender.log("sending %s" % msg)
d = pn_delivery(sender.link, "post-delivery-%s" %
len(pendingSends))
@@ -205,7 +214,7 @@ def main():
sender.settle()
# done sending, now block until any pending deliveries are settled
- while pn_unsettled(sender.link) > 0:
+ while pn_unsettled(sender.link) > 0 and not sender.closed():
sender.wait()
sender.settle()
Added: qpid/proton/branches/driver_abstraction/examples/mailbox/ssl-setup.sh
URL:
http://svn.apache.org/viewvc/qpid/proton/branches/driver_abstraction/examples/mailbox/ssl-setup.sh?rev=1371799&view=auto
==============================================================================
--- qpid/proton/branches/driver_abstraction/examples/mailbox/ssl-setup.sh
(added)
+++ qpid/proton/branches/driver_abstraction/examples/mailbox/ssl-setup.sh Fri
Aug 10 18:15:25 2012
@@ -0,0 +1,30 @@
+#/bin/bash
+#
+#
+set -x
+
+# Step 0: create a password file
+
+echo "trustno1" > ./password.txt
+
+# Step 1: Create a self-signed certificate that identifies the CA
+
+openssl req -x509 -newkey rsa:2048 -keyout ca-private-key.pem -passout
file:./password.txt -out ca-certificate.pem -days 999 -subj "/O=Trust Me,
Inc/CN=127.0.0.1"
+
+# Step 2: Create a certificate signing request for the server
+
+openssl req -newkey rsa:2048 -keyout server-private-key.pem -passout
file:./password.txt -out server-request.pem -subj "/O=Soft Serve/CN=127.0.0.1"
+
+# Step 3: Use the "CA" to create a certificate for the server from the request:
+
+openssl x509 -req -in server-request.pem -CA ca-certificate.pem -CAkey
ca-private-key.pem -CAcreateserial -passin file:./password.txt -days 999 -out
server-certificate.pem
+
+# Step 4: create a certificate database to hold the "trusted" CA certificate
+
+mkdir ./trusted_db
+rm -f ./trusted_db/*
+mv ca-certificate.pem ./trusted_db
+c_rehash ./trusted_db
+
+
+
Propchange:
qpid/proton/branches/driver_abstraction/examples/mailbox/ssl-setup.sh
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
qpid/proton/branches/driver_abstraction/examples/mailbox/ssl-setup.sh
------------------------------------------------------------------------------
svn:executable = *
Modified: qpid/proton/branches/driver_abstraction/proton-c/src/driver.c
URL:
http://svn.apache.org/viewvc/qpid/proton/branches/driver_abstraction/proton-c/src/driver.c?rev=1371799&r1=1371798&r2=1371799&view=diff
==============================================================================
--- qpid/proton/branches/driver_abstraction/proton-c/src/driver.c (original)
+++ qpid/proton/branches/driver_abstraction/proton-c/src/driver.c Fri Aug 10
18:15:25 2012
@@ -398,7 +398,7 @@ static void pn_connector_consume(pn_conn
memmove(ctor->input, ctor->input + n, ctor->input_size);
}
-static void pn_connector_process_input(pn_connector_t *ctor)
+void pn_connector_process_input(pn_connector_t *ctor)
{
while (!ctor->input_done && (ctor->input_size > 0 || ctor->input_eos)) {
ssize_t n = ctor->process_input(ctor);
@@ -499,7 +499,7 @@ static size_t pn_connector_available(pn_
return PN_CONNECTOR_IO_BUF_SIZE - ctor->output_size;
}
-static void pn_connector_process_output(pn_connector_t *ctor)
+void pn_connector_process_output(pn_connector_t *ctor)
{
while (!ctor->output_done && pn_connector_available(ctor) > 0) {
ssize_t n = ctor->process_output(ctor);
@@ -597,7 +597,13 @@ void pn_connector_process(pn_connector_t
c->pending_tick = false;
}
- c->io_handler(c);
+ int rc;
+ rc = c->io_handler(c);
+ if (rc) {
+ fprintf(stderr, "I/O Failure: %d\n", rc);
+ pn_connector_close(c);
+ return;
+ }
if (c->output_size == 0 && c->input_done && c->output_done) {
if (c->trace & (PN_TRACE_FRM | PN_TRACE_RAW | PN_TRACE_DRV)) {
Modified: qpid/proton/branches/driver_abstraction/proton-c/src/driver_impl.h
URL:
http://svn.apache.org/viewvc/qpid/proton/branches/driver_abstraction/proton-c/src/driver_impl.h?rev=1371799&r1=1371798&r2=1371799&view=diff
==============================================================================
--- qpid/proton/branches/driver_abstraction/proton-c/src/driver_impl.h
(original)
+++ qpid/proton/branches/driver_abstraction/proton-c/src/driver_impl.h Fri Aug
10 18:15:25 2012
@@ -111,6 +111,8 @@ void pn_connector_impl_destroy( struct p
void pn_driver_impl_wait(struct pn_driver_t *, int timeout_ms);
int pn_io_handler(pn_connector_t *);
int pn_null_io_handler(pn_connector_t *);
+void pn_connector_process_output(pn_connector_t *);
+void pn_connector_process_input(pn_connector_t *);
#endif /* driver.h */
Modified: qpid/proton/branches/driver_abstraction/proton-c/src/drivers/openssl.c
URL:
http://svn.apache.org/viewvc/qpid/proton/branches/driver_abstraction/proton-c/src/drivers/openssl.c?rev=1371799&r1=1371798&r2=1371799&view=diff
==============================================================================
--- qpid/proton/branches/driver_abstraction/proton-c/src/drivers/openssl.c
(original)
+++ qpid/proton/branches/driver_abstraction/proton-c/src/drivers/openssl.c Fri
Aug 10 18:15:25 2012
@@ -78,6 +78,55 @@ static int start_clear_connected( pn_con
static int start_ssl_shutdown( pn_connector_t *c );
static int handle_ssl_shutdown( pn_connector_t *c );
+
+#if 1
+static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
+{
+ fprintf(stderr, "VERIFY_CALLBACK: pre-verify-ok=%d\n", preverify_ok);
+
+ char buf[256];
+ X509 *err_cert;
+ int err, depth;
+
+ err_cert = X509_STORE_CTX_get_current_cert(ctx);
+ err = X509_STORE_CTX_get_error(ctx);
+ depth = X509_STORE_CTX_get_error_depth(ctx);
+
+ /*
+ * Retrieve the pointer to the SSL of the connection currently
treated
+ * and the application specific data stored into the SSL object.
+ */
+
+ X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
+
+ /*
+ * Catch a too long certificate chain. The depth limit set using
+ * SSL_CTX_set_verify_depth() is by purpose set to "limit+1" so
+ * that whenever the "depth>verify_depth" condition is met, we
+ * have violated the limit and want to log this error condition.
+ * We must do it here, because the CHAIN_TOO_LONG error would not
+ * be found explicitly; only errors introduced by cutting off the
+ * additional certificates would be logged.
+ */
+ if (!preverify_ok) {
+ printf("verify error:num=%d:%s:depth=%d:%s\n", err,
+ X509_verify_cert_error_string(err), depth, buf);
+ }
+
+ /*
+ * At this point, err contains the last verification error. We can
use
+ * it for something special
+ */
+ if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT))
+ {
+ X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf,
256);
+ printf("issuer= %s\n", buf);
+ }
+
+ return 1;
+}
+#endif
+
/** Public API - visible to application code */
int pn_listener_ssl_server_init(pn_listener_t *listener,
@@ -97,6 +146,7 @@ int pn_listener_ssl_server_init(pn_liste
if (!ssl_initialized) {
ssl_initialized = 1;
SSL_library_init();
+ SSL_load_error_strings();
}
impl->ctx = SSL_CTX_new(SSLv23_server_method());
@@ -147,6 +197,9 @@ int pn_listener_ssl_allow_unsecured_clie
int pn_connector_ssl_client_init(pn_connector_t *connector,
const char *certificate_db)
{
+ if (connector->listener)
+ return -1; // not for listener-based connectors
+
connector->ssl = calloc(1, sizeof(pn_connector_ssl_impl_t));
if (!connector->ssl) {
perror("calloc()");
@@ -159,6 +212,7 @@ int pn_connector_ssl_client_init(pn_conn
if (!ssl_initialized) {
ssl_initialized = 1;
SSL_library_init();
+ SSL_load_error_strings();
}
impl->ctx = SSL_CTX_new(SSLv23_client_method());
@@ -174,7 +228,8 @@ int pn_connector_ssl_client_init(pn_conn
/* Force servers to authenticate */
SSL_CTX_set_verify( connector->ssl->ctx,
SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
- 0 /*?verify callback?*/ );
+ verify_callback /*?verify callback?*/ );
+ //0 /*?verify callback?*/ );
#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
SSL_CTX_set_verify_depth(connector->ssl->ctx, 1);
@@ -253,7 +308,8 @@ int pn_connector_ssl_authenticate_client
SSL_set_verify( impl->ssl,
SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
- 0 /*?verify callback?*/);
+ verify_callback /*?verify callback?*/);
+ //0 /*?verify callback?*/ );
return 0;
}
@@ -388,6 +444,7 @@ static int configure_ca_database(SSL_CTX
file = certificate_db;
}
+ fprintf(stderr, "load verify locations: file=%s dir=%s\n", file, dir);
if (SSL_CTX_load_verify_locations( ctx, file, dir ) != 1) {
fprintf(stderr, "SSL_CTX_load_verify_locations( %s ) failed\n",
certificate_db);
return -1;
@@ -488,6 +545,7 @@ static int handle_check_for_ssl( pn_conn
*/
static int start_ssl_connect(pn_connector_t *client)
{
+ fprintf(stderr, "start_ssl_connect()\n");
pn_connector_ssl_impl_t *impl = client->ssl;
if (!impl) return -1;
@@ -509,6 +567,7 @@ static int start_ssl_connect(pn_connecto
int handle_ssl_connect( pn_connector_t *client )
{
+ fprintf(stderr, "handle_ssl_connect()\n");
pn_connector_ssl_impl_t *impl = client->ssl;
if (!impl) return -1;
@@ -519,7 +578,7 @@ int handle_ssl_connect( pn_connector_t *
return start_ssl_connection_up( client );
case SSL_ERROR_WANT_READ:
- printf(" need read...\n");
+ //printf(" need read...\n");
client->status |= PN_SEL_RD;
break;
case SSL_ERROR_WANT_WRITE:
@@ -527,7 +586,8 @@ int handle_ssl_connect( pn_connector_t *
client->status |= PN_SEL_WR;
break;
default:
- fprintf(stderr, "SSL_connect() failure");
+ fprintf(stderr, "SSL_connect() failure: %d\n",
SSL_get_error(impl->ssl, rc));
+ ERR_print_errors_fp(stderr);
return -1;
}
@@ -546,9 +606,11 @@ static int start_ssl_accept(pn_connector
{
pn_connector_ssl_impl_t *impl = client->ssl;
if (!impl) return -1;
+ pn_listener_ssl_impl_t *parent = client->listener->ssl;
+ if (!parent) return -1;
impl->sbio = BIO_new_socket(client->fd, BIO_NOCLOSE);
- impl->ssl = SSL_new(impl->ctx);
+ impl->ssl = SSL_new(parent->ctx);
SSL_set_bio(impl->ssl, impl->sbio, impl->sbio);
return handle_ssl_accept(client);
@@ -566,7 +628,7 @@ static int handle_ssl_accept(pn_connecto
return start_ssl_connection_up( client );
case SSL_ERROR_WANT_READ:
- printf(" need read...\n");
+ //printf(" need read...\n");
client->status |= PN_SEL_RD;
break;
case SSL_ERROR_WANT_WRITE:
@@ -574,7 +636,8 @@ static int handle_ssl_accept(pn_connecto
client->status |= PN_SEL_WR;
break;
default:
- fprintf(stderr, "SSL_accept() failure\n");
+ fprintf(stderr, "SSL_accept() failure: %d\n", SSL_get_error(impl->ssl,
rc));
+ ERR_print_errors_fp(stderr);
return -1;
}
client->io_handler = handle_ssl_accept;
@@ -607,7 +670,7 @@ int handle_ssl_connection_up( pn_connect
pn_connector_ssl_impl_t *impl = c->ssl;
assert(impl);
- printf("handle_ssl_connection_up\n");
+ printf("handle_ssl_connection_up OUT=%d\n", (int)c->output_size);
c->status &= ~(PN_SEL_RD | PN_SEL_WR);
@@ -628,7 +691,7 @@ int handle_ssl_connection_up( pn_connect
} else if (ssl_err == SSL_ERROR_WANT_WRITE) {
printf("need write\n");
read_blocked = 1;
- write_blocked = 1;
+ write_blocked = 1; // don't bother writing
need_write = 1;
} else {
if (ssl_err == SSL_ERROR_ZERO_RETURN) {
@@ -642,15 +705,13 @@ int handle_ssl_connection_up( pn_connect
}
}
- // we need to re-call SSL_read when the receive buffer is drained (do
not need to wait for I/O!)
- if (!read_blocked && SSL_pending(impl->ssl) &&
PN_CONNECTOR_IO_BUF_SIZE == c->input_size) {
- printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!! >>>>> READ STALLED <<<<<<
!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
- impl->read_stalled = true;
- }
+ pn_connector_process_input(c);
+ pn_connector_process_output(c);
if (!write_blocked && c->output_size > 0) {
rc = SSL_write( impl->ssl, c->output, c->output_size );
+ printf("write %d possible bytes: actual = %d\n",
(int)c->output_size, rc);
ssl_err = SSL_get_error( impl->ssl, rc );
if (ssl_err == SSL_ERROR_NONE) {
c->output_size -= rc;
@@ -664,7 +725,7 @@ int handle_ssl_connection_up( pn_connect
} else if (ssl_err == SSL_ERROR_WANT_READ) {
printf("need read\n");
read_blocked = 1;
- write_blocked = 1;
+ write_blocked = 1; // don't bother reading
need_read = 1;
} else {
if (ssl_err == SSL_ERROR_ZERO_RETURN)
@@ -683,6 +744,12 @@ int handle_ssl_connection_up( pn_connect
if (need_read) c->status |= PN_SEL_RD;
if (need_write) c->status |= PN_SEL_WR;
+ // we need to re-call SSL_read when the receive buffer is drained (do not
need to wait for I/O!)
+ if (!read_blocked && SSL_pending(impl->ssl) && PN_CONNECTOR_IO_BUF_SIZE ==
c->input_size) {
+ printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!! >>>>> READ STALLED <<<<<<
!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
+ impl->read_stalled = true;
+ }
+
return 0;
}
@@ -722,7 +789,7 @@ static int handle_ssl_shutdown( pn_conne
switch (SSL_get_error( impl->ssl, rc )) {
case SSL_ERROR_WANT_READ:
- printf(" need read...\n");
+ //printf(" need read...\n");
c->status |= PN_SEL_RD;
break;
case SSL_ERROR_WANT_WRITE:
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]