commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mt...@apache.org
Subject svn commit: r1188562 - in /commons/sandbox/runtime/trunk/src/main/native: include/acr/ssl.h modules/openssl/api.c modules/openssl/netio.c
Date Tue, 25 Oct 2011 08:29:48 GMT
Author: mturk
Date: Tue Oct 25 08:29:47 2011
New Revision: 1188562

URL: http://svn.apache.org/viewvc?rev=1188562&view=rev
Log:
Implement SSL shutdown and add required API

Modified:
    commons/sandbox/runtime/trunk/src/main/native/include/acr/ssl.h
    commons/sandbox/runtime/trunk/src/main/native/modules/openssl/api.c
    commons/sandbox/runtime/trunk/src/main/native/modules/openssl/netio.c

Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr/ssl.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr/ssl.h?rev=1188562&r1=1188561&r2=1188562&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr/ssl.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr/ssl.h Tue Oct 25 08:29:47 2011
@@ -470,6 +470,7 @@ struct ssl_sd_t {
     int                     shutdown_type;
     int                     is_proxy;
     int                     disabled;
+    int                     aborted;
     int                     non_ssl_request;
 };
 

Modified: commons/sandbox/runtime/trunk/src/main/native/modules/openssl/api.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/modules/openssl/api.c?rev=1188562&r1=1188561&r2=1188562&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/modules/openssl/api.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/modules/openssl/api.c Tue Oct 25 08:29:47
2011
@@ -98,6 +98,9 @@ struct SSLAPIst {
     int                 (*fpBIO_printf)(BIO *, const char *, ...);
     int                 (*fpBIO_vprintf)(BIO *, const char *, va_list);
     int                 (*fpBIO_write)(BIO *, const void *, int);
+    void                (*fpBIO_set_flags)(BIO *, int);
+    int                 (*fpBIO_test_flags)(const BIO *, int);
+    void                (*fpBIO_clear_flags)(BIO *, int);
 
     /*** BIGNUM   ***/
     BIGNUM*             (*fpBN_new)(void);
@@ -208,6 +211,12 @@ struct SSLAPIst {
     int                 (*fpSSL_connect)(SSL *);
     void                (*fpSSL_set_verify_result)(SSL *, long);
     int                 (*fpSSL_set_fd)(SSL *, int);
+    void                (*fpSSL_set_shutdown)(SSL *, int);
+    int                 (*fpSSL_shutdown)(SSL *);
+    void                (*fpSSL_set_connect_state)(SSL *);
+    void                (*fpSSL_set_accept_state)(SSL *);
+    int                 (*fpSSL_do_handshake)(SSL *);
+
 
     
     CONST_SSL_METHOD*   (*fpSSLv3_method)(void);           /* SSLv3 */
@@ -356,6 +365,11 @@ ACR_JNI_EXPORT(jboolean, Native, ldopens
     LIBSSL_FPLOAD(SSL_connect);
     LIBSSL_FPLOAD(SSL_set_verify_result);
     LIBSSL_FPLOAD(SSL_set_fd);
+    LIBSSL_FPLOAD(SSL_set_shutdown);
+    LIBSSL_FPLOAD(SSL_shutdown);
+    LIBSSL_FPLOAD(SSL_set_connect_state);
+    LIBSSL_FPLOAD(SSL_set_accept_state);
+    LIBSSL_FPLOAD(SSL_do_handshake);
 
     LIBSSL_FPLOAD(SSLv3_method);
     LIBSSL_FPLOAD(SSLv3_server_method);
@@ -406,6 +420,9 @@ ACR_JNI_EXPORT(jboolean, Native, ldopens
     CRYPTO_FPLOAD(BIO_printf);
     CRYPTO_FPLOAD(BIO_vprintf);
     CRYPTO_FPLOAD(BIO_write);
+    CRYPTO_FPLOAD(BIO_set_flags);
+    CRYPTO_FPLOAD(BIO_test_flags);
+    CRYPTO_FPLOAD(BIO_clear_flags);
 
     /*** BIGNUM   ***/
     CRYPTO_FPLOAD(BN_new);
@@ -645,6 +662,21 @@ int BIO_write(BIO *b, const void *data, 
     return SSLAPI_CALL(BIO_write)(b, data, len);
 }
 
+void BIO_set_flags(BIO *b, int flags)
+{
+    SSLAPI_CALL(BIO_set_flags)(b, flags);
+}
+
+int  BIO_test_flags(const BIO *b, int flags)
+{
+    return SSLAPI_CALL(BIO_test_flags)(b, flags);
+}
+
+void BIO_clear_flags(BIO *b, int flags)
+{
+    SSLAPI_CALL(BIO_clear_flags)(b, flags);
+}
+
 BIGNUM *BN_new(void)
 {
     return SSLAPI_CALL(BN_new)();
@@ -1144,6 +1176,31 @@ int SSL_set_fd(SSL *s, int fd)
     return SSLAPI_CALL(SSL_set_fd)(s, fd);
 }
 
+void SSL_set_shutdown(SSL *ssl, int mode)
+{
+    SSLAPI_CALL(SSL_set_shutdown)(ssl, mode);
+}
+
+int SSL_shutdown(SSL *ssl)
+{
+    return SSLAPI_CALL(SSL_shutdown)(ssl);
+}
+
+void SSL_set_connect_state(SSL *s)
+{
+    SSLAPI_CALL(SSL_set_connect_state)(s);
+}
+
+void SSL_set_accept_state(SSL *s)
+{
+    SSLAPI_CALL(SSL_set_accept_state)(s);
+}
+
+int SSL_do_handshake(SSL *s)
+{
+    return SSLAPI_CALL(SSL_do_handshake)(s);
+}
+
 #define IMPLEMENT_SSLAPI_METHOD(name)                   \
 CONST_SSL_METHOD *name##_method(void) {                 \
     return (*SSLapi.fp##name##_method)();               \

Modified: commons/sandbox/runtime/trunk/src/main/native/modules/openssl/netio.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/modules/openssl/netio.c?rev=1188562&r1=1188561&r2=1188562&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/modules/openssl/netio.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/modules/openssl/netio.c Tue Oct 25 08:29:47
2011
@@ -28,6 +28,120 @@
 #error "Cannot compile this file without HAVE_OPENSSL defined"
 #endif
 
+static int SSL_smart_shutdown(SSL *ssl)
+{
+    int i;
+    int rc = 0;
+
+    /*
+     * Repeat the calls, because SSL_shutdown internally dispatches through a
+     * little state machine. Usually only one or two interation should be
+     * needed, so we restrict the total number of restrictions in order to
+     * avoid process hangs in case the client played bad with the socket
+     * connection and OpenSSL cannot recognize it.
+     */
+    for (i = 0; i < 4 /* max 2x pending + 2x data = 4 */; i++) {
+        if ((rc = SSL_shutdown(ssl)))
+            break;
+    }
+    return rc;
+}
+
+/*
+ *  Close the SSL part of the socket connection
+ *  (called immediately _before_ the socket is closed)
+ *  or called with
+ */
+static void SSL_io_shutdown(ssl_sd_t *ss, int abortive)
+{
+    SSL *ssl = ss->ssl;
+    int shutdown_type;
+
+    if (ssl == 0) {
+        /* Already shutdown */
+        return;
+    }
+
+    /*
+     * Now close the SSL layer of the connection. We've to take
+     * the TLSv1 standard into account here:
+     *
+     * | 7.2.1. Closure alerts
+     * |
+     * | The client and the server must share knowledge that the connection is
+     * | ending in order to avoid a truncation attack. Either party may
+     * | initiate the exchange of closing messages.
+     * |
+     * | close_notify
+     * |     This message notifies the recipient that the sender will not send
+     * |     any more messages on this connection. The session becomes
+     * |     unresumable if any connection is terminated without proper
+     * |     close_notify messages with level equal to warning.
+     * |
+     * | Either party may initiate a close by sending a close_notify alert.
+     * | Any data received after a closure alert is ignored.
+     * |
+     * | Each party is required to send a close_notify alert before closing
+     * | the write side of the connection. It is required that the other party
+     * | respond with a close_notify alert of its own and close down the
+     * | connection immediately, discarding any pending writes. It is not
+     * | required for the initiator of the close to wait for the responding
+     * | close_notify alert before closing the read side of the connection.
+     *
+     * This means we've to send a close notify message, but haven't to wait
+     * for the close notify of the client. Actually we cannot wait for the
+     * close notify of the client because some clients (including Netscape
+     * 4.x) don't send one, so we would hang.
+     */
+
+    /*
+     * exchange close notify messages, but allow the user
+     * to force the type of handshake via SetEnvIf directive
+     */
+    if (abortive) {
+        shutdown_type = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN;
+    }
+    else {
+        switch (ss->shutdown_type) {
+            case SSL_SHUTDOWN_TYPE_UNCLEAN:
+                /* perform no close notify handshake at all
+                 * (violates the SSL/TLS standard!)
+                 */
+                shutdown_type = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN;
+            break;
+            case SSL_SHUTDOWN_TYPE_ACCURATE:
+                /* send close notify and wait for clients close notify
+                 * (standard compliant, but usually causes connection hangs)
+                 */
+                shutdown_type = 0;
+            break;
+            default:
+                /*
+                 * case SSL_SHUTDOWN_TYPE_UNSET:
+                 * case SSL_SHUTDOWN_TYPE_STANDARD:
+                 */
+                /* send close notify, but don't wait for clients close notify
+                 * (standard compliant and safe, so it's the DEFAULT!)
+                 */
+                shutdown_type = SSL_RECEIVED_SHUTDOWN;
+            break;
+        }
+    }
+    SSL_set_shutdown(ssl, shutdown_type);
+    SSL_smart_shutdown(ssl);
+    /* deallocate the SSL connection */
+    if (ss->peer != 0) {
+        X509_free(ss->peer);
+        ss->peer = 0;
+    }
+    SSL_free(ssl);
+    ss->ssl = 0;
+    if (abortive) {
+        /* prevent any further I/O */
+        ss->aborted = 1;
+    }
+}
+
 ACR_NET_EXPORT(jlong, SSLSocketDescriptor, socket0)(JNI_STDARGS, jlong ssd,
                                                     jlong ctx)
 {
@@ -72,12 +186,7 @@ ACR_NET_EXPORT(jint, SSLSocketDescriptor
     if (ss == 0)
         return ACR_EBADF;
     if (AcrAtomic32Dec(&ss->refs) == 0) {
-        if (ss->ssl != 0) {
-            SSL_free(ss->ssl);
-        }
-        if (ss->peer != 0) {
-            X509_free(ss->peer);
-        }        
+        SSL_io_shutdown(ss, 1);
         AcrAtomic32Dec(&ss->sd->refs);
         AcrFree(ss);
     }



Mime
View raw message