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]

Reply via email to