httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r..@apache.org
Subject Final patch for a long time.
Date Tue, 15 Oct 2002 17:46:13 GMT

The recent conversations on this list have made me finally realize that I
have been here too long.  I need a project that is not the Apache web
server.  So, this is my good-bye.  I will be unsubscribing from the Apache
web server development lists in the next day or two.  I will still be
involved in APR development work, so I will still be reachable at
rbb@apache.org.

There are two projects that I started that have not been finished.  I
would hope that one of two things would happen to both of them.  Either
somebody else should pick them up and run with them, or they should be
removed from the server.

The first project is the Perchild MPM.  It basically works, but there are
bugs.  

The second is SSL upgrade.  I have the patches, they haven't been
committed yet.  I have attached them at the bottom of this message.  The
reason they haven't been committed, is that I don't have a client to test
them with, and I haven't had time to create one.  The responses are
correct I have checked them in plain text.  The place that bugs most
likely exist, is the actual upgrade code that does the handshake.  This is
an important feature, and I would really like to see it in 2.0.

It has been a lot of fun the last four years working on Apache, but I have
been here too long, and it isn't fun anymore.  It isn't worth doing if it
isn't fun.

Ryan
_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
550 Jean St
Oakland CA 94610
-------------------------------------------------------------------------------

? build.err
? build.log
? output.log
? sslupgrade.patch
? modules/new
? srclib/apr/APRVARS
? srclib/apr/build.err
? srclib/apr/build.log
? srclib/apr/newpoll2.tar.gz
? srclib/apr/i18n/unix/Makefile
? srclib/apr/test/build.err
? srclib/apr/test/build.log
? srclib/apr/test/garg
? srclib/apr/test/testall
Index: modules/ssl/mod_ssl.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/ssl/mod_ssl.c,v
retrieving revision 1.72
diff -u -d -b -w -r1.72 mod_ssl.c
--- modules/ssl/mod_ssl.c	14 Oct 2002 04:15:57 -0000	1.72
+++ modules/ssl/mod_ssl.c	15 Oct 2002 16:49:07 -0000
@@ -105,7 +105,7 @@
     /*
      * Per-server context configuration directives
      */
-    SSL_CMD_SRV(Engine, FLAG,
+    SSL_CMD_SRV(Engine, TAKE1,
                 "SSL switch for the protocol engine "
                 "(`on', `off')")
     SSL_CMD_ALL(CipherSuite, TAKE1,
@@ -274,7 +274,7 @@
     return 1;
 }
 
-static int ssl_hook_pre_connection(conn_rec *c, void *csd)
+int ssl_init_ssl_connection(conn_rec *c)
 {
     SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
     SSL *ssl;
@@ -283,40 +283,14 @@
     modssl_ctx_t *mctx;
 
     /*
-     * Immediately stop processing if SSL is disabled for this connection
+     * Seed the Pseudo Random Number Generator (PRNG)
      */
-    if (!(sc && (sc->enabled ||
-                 (sslconn && sslconn->is_proxy))))
-    {
-        return DECLINED;
-    }
+    ssl_rand_seed(c->base_server, c->pool, SSL_RSCTX_CONNECT, "");
 
-    /*
-     * Create SSL context
-     */
     if (!sslconn) {
         sslconn = ssl_init_connection_ctx(c);
     }
 
-    if (sslconn->disabled) {
-        return DECLINED;
-    }
-
-    /*
-     * Remember the connection information for
-     * later access inside callback functions
-     */
-
-    ap_log_error(APLOG_MARK, APLOG_INFO, 0, c->base_server,
-                 "Connection to child %ld established "
-                 "(server %s, client %s)", c->id, sc->vhost_id, 
-                 c->remote_ip ? c->remote_ip : "unknown");
-
-    /*
-     * Seed the Pseudo Random Number Generator (PRNG)
-     */
-    ssl_rand_seed(c->base_server, c->pool, SSL_RSCTX_CONNECT, "");
-
     mctx = sslconn->is_proxy ? sc->proxy : sc->server;
 
     /*
@@ -368,6 +342,44 @@
     return APR_SUCCESS;
 }
 
+static int ssl_hook_pre_connection(conn_rec *c, void *csd)
+{
+    SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
+    SSLConnRec *sslconn = myConnConfig(c);
+
+    /*
+     * Immediately stop processing if SSL is disabled for this connection
+     */
+    if (!(sc && (sc->enabled == TRUE ||
+                 (sslconn && sslconn->is_proxy))))
+    {
+        return DECLINED;
+    }
+
+    /*
+     * Create SSL context
+     */
+    if (!sslconn) {
+        sslconn = ssl_init_connection_ctx(c);
+    }
+
+    if (sslconn->disabled) {
+        return DECLINED;
+    }
+
+    /*
+     * Remember the connection information for
+     * later access inside callback functions
+     */
+
+    ap_log_error(APLOG_MARK, APLOG_INFO, 0, c->base_server,
+                 "Connection to child %ld established "
+                 "(server %s, client %s)", c->id, sc->vhost_id, 
+                 c->remote_ip ? c->remote_ip : "unknown");
+
+    return ssl_init_ssl_connection(c);
+}
+
 static apr_status_t ssl_abort(SSLFilterRec *filter, conn_rec *c)
 {
     SSLConnRec *sslconn = myConnConfig(c);
@@ -572,6 +584,15 @@
     return 443;
 }
 
+static void ssl_hook_Insert_Filter(request_rec *r)
+{
+    SSLSrvConfigRec *sc = mySrvConfig(r->server);
+
+    if (sc->enabled == UNSET) {
+        ap_add_output_filter("UPGRADE_FILTER", NULL, r, r->connection);
+    }
+}
+
 /*
  *  the module registration phase
  */
@@ -592,6 +613,8 @@
     ap_hook_access_checker(ssl_hook_Access,        NULL,NULL, APR_HOOK_MIDDLE);
     ap_hook_auth_checker  (ssl_hook_Auth,          NULL,NULL, APR_HOOK_MIDDLE);
     ap_hook_post_read_request(ssl_hook_ReadReq,    NULL,NULL, APR_HOOK_MIDDLE);
+    ap_hook_insert_filter (ssl_hook_Insert_Filter, NULL,NULL, APR_HOOK_MIDDLE);
+/*    ap_hook_handler       (ssl_hook_Upgrade,       NULL,NULL, APR_HOOK_MIDDLE); */
 
     ssl_var_register();
 
Index: modules/ssl/mod_ssl.h
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/ssl/mod_ssl.h,v
retrieving revision 1.121
diff -u -d -b -w -r1.121 mod_ssl.h
--- modules/ssl/mod_ssl.h	14 Oct 2002 04:15:58 -0000	1.121
+++ modules/ssl/mod_ssl.h	15 Oct 2002 16:49:07 -0000
@@ -549,7 +549,7 @@
 const char  *ssl_cmd_SSLPassPhraseDialog(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLCryptoDevice(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLRandomSeed(cmd_parms *, void *, const char *, const char *, const
char *);
-const char  *ssl_cmd_SSLEngine(cmd_parms *, void *, int);
+const char  *ssl_cmd_SSLEngine(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLCipherSuite(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLCertificateFile(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLCertificateKeyFile(cmd_parms *, void *, const char *);
@@ -601,6 +601,7 @@
 int          ssl_hook_Fixup(request_rec *);
 int          ssl_hook_ReadReq(request_rec *);
 int          ssl_hook_Handler(request_rec *);
+int          ssl_hook_Upgrade(request_rec *);
 
 /*  OpenSSL callbacks */
 RSA         *ssl_callback_TmpRSA(SSL *, int, int);
@@ -722,6 +723,8 @@
 char        *ssl_util_algotypestr(ssl_algo_t);
 char        *ssl_util_ptxtsub(apr_pool_t *, const char *, const char *, char *);
 void         ssl_util_thread_setup(apr_pool_t *);
+int          ssl_init_ssl_connection(conn_rec *c);
+
 
 #define APR_SHM_MAXSIZE (64 * 1024 * 1024)
 #endif /* __MOD_SSL_H__ */
Index: modules/ssl/ssl_engine_config.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/ssl/ssl_engine_config.c,v
retrieving revision 1.69
diff -u -d -b -w -r1.69 ssl_engine_config.c
--- modules/ssl/ssl_engine_config.c	14 Oct 2002 04:15:58 -0000	1.69
+++ modules/ssl/ssl_engine_config.c	15 Oct 2002 16:49:07 -0000
@@ -205,7 +205,7 @@
     SSLSrvConfigRec *sc = apr_palloc(p, sizeof(*sc));
 
     sc->mc                     = NULL;
-    sc->enabled                = UNSET;
+    sc->enabled                = FALSE;
     sc->proxy_enabled          = UNSET;
     sc->vhost_id               = NULL;  /* set during module init */
     sc->vhost_id_len           = 0;     /* set during module init */
@@ -581,13 +581,24 @@
     return NULL;
 }
 
-const char *ssl_cmd_SSLEngine(cmd_parms *cmd, void *dcfg, int flag)
+const char *ssl_cmd_SSLEngine(cmd_parms *cmd, void *dcfg, const char *arg)
 {
     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
-    sc->enabled = flag ? TRUE : FALSE;
-
+    if (!strcasecmp(arg, "On")) {
+        sc->enabled = TRUE;
     return NULL;
+    }
+    else if (!strcasecmp(arg, "Off")) {
+        sc->enabled = FALSE;
+        return NULL;
+    }
+    else if (!strcasecmp(arg, "Optional")) {
+        sc->enabled = UNSET;
+        return NULL;
+    }
+
+    return "Argument must be On, Off, or Optional";
 }
 
 const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd,
Index: modules/ssl/ssl_engine_init.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/ssl/ssl_engine_init.c,v
retrieving revision 1.104
diff -u -d -b -w -r1.104 ssl_engine_init.c
--- modules/ssl/ssl_engine_init.c	14 Oct 2002 04:15:58 -0000	1.104
+++ modules/ssl/ssl_engine_init.c	15 Oct 2002 16:49:07 -0000
@@ -247,11 +247,13 @@
         sc->vhost_id = ssl_util_vhostid(p, s);
         sc->vhost_id_len = strlen(sc->vhost_id);
 
+#if 0
+       /* If sc->enabled is UNSET, then SSL is optional on this vhost  */
         /* Fix up stuff that may not have been set */
         if (sc->enabled == UNSET) {
             sc->enabled = FALSE;
         }
-
+#endif
         if (sc->proxy_enabled == UNSET) {
             sc->proxy_enabled = FALSE;
         }
@@ -981,6 +983,9 @@
                               apr_pool_t *ptemp,
                               SSLSrvConfigRec *sc)
 {
+    /* A bit of a hack, but initialize the server if SSL is optional or
+     * not.
+     */
     if (sc->enabled) {
         ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
                      "Configuring server for SSL protocol");
@@ -1009,7 +1014,7 @@
     for (s = base_server; s; s = s->next) {
         sc = mySrvConfig(s);
 
-        if (sc->enabled && (s->port == DEFAULT_HTTP_PORT)) {
+        if ((sc->enabled == TRUE) && (s->port == DEFAULT_HTTP_PORT)) {
             ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
                          base_server,
                          "Init: (%s) You configured HTTPS(%d) "
Index: modules/ssl/ssl_engine_io.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/ssl/ssl_engine_io.c,v
retrieving revision 1.81
diff -u -d -b -w -r1.81 ssl_engine_io.c
--- modules/ssl/ssl_engine_io.c	14 Oct 2002 04:15:58 -0000	1.81
+++ modules/ssl/ssl_engine_io.c	15 Oct 2002 16:49:07 -0000
@@ -577,6 +577,85 @@
     return APR_SUCCESS;
 }
 
+static apr_status_t ssl_io_filter_Upgrade(ap_filter_t *f,
+                                         apr_bucket_brigade *bb)
+
+{
+#define SWITCH_STATUS_LINE "101 Switching Protocols"
+#define UPGRADE_HEADER "Upgrade: TLS/1.0 HTTP/1.1"
+#define CONNECTION_HEADER "Conenction: Upgrade"
+    const char *upgrade;
+    const char *connection;
+    apr_bucket_brigade *upgradebb;
+    request_rec *r = f->r;
+    SSLConnRec *sslconn;
+    SSL *ssl;
+
+    /* Just remove the filter, if it doesn't work the first time, it won't
+     * work at all for this request.
+     */
+    ap_remove_output_filter(f);
+
+    /* No need to ensure that this is a server with optional SSL, the filter
+     * is only inserted if that is true.
+     */
+
+    upgrade = apr_table_get(r->headers_in, "Upgrade");
+    if (upgrade == NULL) {
+        return ap_pass_brigade(f->next, bb);
+    }
+    connection = apr_table_get(r->headers_in, "Connection");
+
+    apr_table_unset(r->headers_out, "Upgrade");
+
+    if (strcmp(connection, "Upgrade") || strcmp(upgrade, "TLS/1.0")) {
+        return ap_pass_brigade(f->next, bb);
+    }
+
+    if (r->method_number == M_OPTIONS) {
+        apr_bucket *b = NULL;
+        /* This is a mandatory SSL upgrade. */
+
+        upgradebb = apr_brigade_create(r->pool, f->c->bucket_alloc);
+
+        ap_fputstrs(f->next, upgradebb, SWITCH_STATUS_LINE, CRLF,
+                    UPGRADE_HEADER, CRLF, CONNECTION_HEADER, CRLF, CRLF, NULL);
+
+        b = apr_bucket_flush_create(f->c->bucket_alloc);
+        APR_BRIGADE_INSERT_TAIL(upgradebb, b);
+
+        ap_pass_brigade(f->next, upgradebb);
+    }
+    else {
+        /* This is optional, and should be configurable, for now don't bother
+         * doing anything.
+         */
+        return ap_pass_brigade(f->next, bb);
+    }
+
+    ssl_init_ssl_connection(f->c);
+
+    ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+                 "Awaiting re-negotiation handshake");
+
+    sslconn = myConnConfig(f->c);
+    ssl = sslconn->ssl;
+
+    SSL_set_state(ssl, SSL_ST_ACCEPT);
+    SSL_do_handshake(ssl);
+
+    if (SSL_get_state(ssl) != SSL_ST_OK) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+                     "Re-negotiation handshake failed: "
+                "Not accepted by client!?");
+
+        return AP_FILTER_ERROR;
+    }
+
+    return OK;
+
+}
+
 static apr_status_t ssl_io_filter_Output(ap_filter_t *f,
                                          apr_bucket_brigade *bb)
 {
@@ -943,6 +1022,11 @@
 
 void ssl_io_filter_register(apr_pool_t *p)
 {
+    /* This filter MUST be after the HTTP_HEADER filter, but it also must be
+     * a resource-level filter so it has the request_rec.
+     */
+    ap_register_output_filter ("UPGRADE_FILTER", ssl_io_filter_Upgrade, NULL, AP_FTYPE_PROTOCOL
+ 5);
+
     ap_register_input_filter  (ssl_io_filter, ssl_io_filter_Input,  NULL, AP_FTYPE_CONNECTION
+ 5);
     ap_register_output_filter (ssl_io_filter, ssl_io_filter_Output, NULL, AP_FTYPE_CONNECTION
+ 5);
     return;
Index: modules/ssl/ssl_engine_kernel.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/ssl/ssl_engine_kernel.c,v
retrieving revision 1.78
diff -u -d -b -w -r1.78 ssl_engine_kernel.c
--- modules/ssl/ssl_engine_kernel.c	14 Oct 2002 04:15:58 -0000	1.78
+++ modules/ssl/ssl_engine_kernel.c	15 Oct 2002 16:49:08 -0000
@@ -322,6 +322,16 @@
      * Support for SSLRequireSSL directive
      */
     if (dc->bSSLRequired && !ssl) {
+        if (sc->enabled == UNSET) {
+            /* This vhost was configured for optional SSL, just tell the
+             * client that we need to upgrade.
+             */
+            apr_table_setn(r->err_headers_out, "Upgrade", "TLS/1.0, HTTP/1.1");
+            apr_table_setn(r->err_headers_out, "Connection", "Upgrade");
+
+            return HTTP_UPGRADE_REQUIRED;
+        }
+
         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, 
                       "access to %s failed, reason: %s",
                       r->filename, "SSL connection required");
@@ -1109,6 +1119,10 @@
     STACK_OF(X509) *peer_certs;
     SSL *ssl;
     int i;
+
+    if (sc->enabled == UNSET) {
+        apr_table_setn(r->headers_out, "Upgrade", "TLS/1.0, HTTP/1.1");
+    }
 
     /*
      * Check to see if SSL is on
Index: modules/ssl/ssl_util.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/ssl/ssl_util.c,v
retrieving revision 1.35
diff -u -d -b -w -r1.35 ssl_util.c
--- modules/ssl/ssl_util.c	14 Oct 2002 04:15:58 -0000	1.35
+++ modules/ssl/ssl_util.c	15 Oct 2002 16:49:08 -0000
@@ -84,7 +84,7 @@
         port = s->port;
     else {
         sc = mySrvConfig(s);
-        if (sc->enabled)
+        if (sc->enabled == TRUE)
             port = DEFAULT_HTTPS_PORT;
         else
             port = DEFAULT_HTTP_PORT;



Mime
View raw message