[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#307298: apache2-common: mod_proxy_connect bypasses mod_ssl at tunnel setup



Package: apache2-common
Version: 2.0.54-2
Severity: normal
Tags: patch

Currently it is not possible to successfully issue an HTTP CONNECT
request to apache2 with mod_ssl; mod_proxy_connect talks directly to
the client socket and bypasses mod_ssl.

Further discussion of this bug is at:
http://issues.apache.org/bugzilla/show_bug.cgi?id=29744

I have included a patch by Brad Boyer (see above discussion) which
fixes this problem for me.

-- System Information:
Debian Release: 3.1
  APT prefers testing
  APT policy: (990, 'testing'), (500, 'unstable'), (1, 'experimental')
Architecture: i386 (i586)
Kernel: Linux 2.6.11.7-grsec
Locale: LANG=en_US, LC_CTYPE=en_US (charmap=ISO-8859-1)

Versions of packages apache2-common depends on:
ii  apache2-utils               2.0.54-2     utility programs for webservers
ii  debconf                     1.4.30.13    Debian configuration management sy
ii  debianutils                 2.8.4        Miscellaneous utilities specific t
ii  libc6                       2.3.2.ds1-21 GNU C Library: Shared libraries an
ii  libdb4.2                    4.2.52-18    Berkeley v4.2 Database Libraries [
ii  libexpat1                   1.95.8-3     XML parsing C library - runtime li
ii  libgcc1                     1:3.4.3-12   GCC support library
ii  libmagic1                   4.12-1       File type determination library us
ii  mime-support                3.28-1       MIME files 'mime.types' & 'mailcap
ii  net-tools                   1.60-10      The NET-3 networking toolkit
ii  openssl                     0.9.7e-3     Secure Socket Layer (SSL) binary a
ii  ssl-cert                    1.0-11       Simple debconf wrapper for openssl

-- no debconf information
--- build-tree.orig/apache2/modules/proxy/proxy_connect.c	2004-02-09 12:53:19.000000000 -0800
+++ build-tree/apache2/modules/proxy/proxy_connect.c	2004-10-20 16:09:26.000000000 -0700
@@ -83,10 +83,14 @@
 {
     apr_pool_t *p = r->pool;
     apr_socket_t *sock;
+    conn_rec *c = r->connection;
+    conn_rec *backconn;
+    apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc);
+
     apr_status_t err, rv;
     apr_size_t i, o, nbytes;
     char buffer[HUGE_STRING_LEN];
-    apr_socket_t *client_socket = ap_get_module_config(r->connection->conn_config, &core_module);
+    apr_socket_t *client_socket = ap_get_module_config(c->conn_config, &core_module);
     int failed;
     apr_pollfd_t *pollfd;
     apr_int32_t pollcnt;
@@ -211,7 +215,23 @@
      * We add the NULL filter to the stack to do this...
      */
     r->output_filters = NULL;
-    r->connection->output_filters = NULL;
+
+    backconn = ap_run_create_connection(c->pool, r->server, sock,
+					c->id, c->sbh, c->bucket_alloc);
+    if(!backconn) {
+	/* peer reset */
+	ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+		     "proxy: an error occurred creating a new connection "
+		     "to %pI (%s)", connect_addr, connectname);
+	apr_socket_close(sock);
+	return HTTP_INTERNAL_SERVER_ERROR;
+    }
+    ap_proxy_ssl_disable(backconn);
+    ap_run_pre_connection(backconn, sock);
+
+    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+		 "proxy: connection complete to %pI (%s)",
+		 connect_addr, connectname);
 
 
     /* If we are connecting through a remote proxy, we need to pass
@@ -222,12 +242,12 @@
 	 */
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
 		     "proxy: CONNECT: sending the CONNECT request to the remote proxy");
-        nbytes = apr_snprintf(buffer, sizeof(buffer),
+
+	ap_fprintf(backconn->output_filters, bb,
 			      "CONNECT %s HTTP/1.0" CRLF, r->uri);
-        apr_send(sock, buffer, &nbytes);
-        nbytes = apr_snprintf(buffer, sizeof(buffer),
-			      "Proxy-agent: %s" CRLF CRLF, ap_get_server_version());
-        apr_send(sock, buffer, &nbytes);
+	ap_fprintf(backconn->output_filters, bb,
+		   "Proxy-agent: %s" CRLF CRLF, ap_get_server_version());
+	ap_fflush(backconn->output_filters, bb);
     }
     else {
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
@@ -235,11 +255,12 @@
         nbytes = apr_snprintf(buffer, sizeof(buffer),
 			      "HTTP/1.0 200 Connection Established" CRLF);
         ap_xlate_proto_to_ascii(buffer, nbytes);
-        apr_send(client_socket, buffer, &nbytes);
+        ap_fwrite(c->output_filters, bb, buffer, nbytes);
         nbytes = apr_snprintf(buffer, sizeof(buffer),
 			      "Proxy-agent: %s" CRLF CRLF, ap_get_server_version());
         ap_xlate_proto_to_ascii(buffer, nbytes);
-        apr_send(client_socket, buffer, &nbytes);
+        ap_fwrite(c->output_filters, bb, buffer, nbytes);
+	ap_fflush(c->output_filters, bb);
 #if 0
         /* This is safer code, but it doesn't work yet.  I'm leaving it 
          * here so that I can fix it later.
@@ -293,23 +314,13 @@
 /*		ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                              "proxy: CONNECT: sock was set");*/
                 nbytes = sizeof(buffer);
-                if (apr_recv(sock, buffer, &nbytes) == APR_SUCCESS) {
-                    o = 0;
-                    i = nbytes;
-                    while(i > 0)
-                    {
-                        nbytes = i;
-    /* This is just plain wrong.  No module should ever write directly
-     * to the client.  For now, this works, but this is high on my list of
-     * things to fix.  The correct line is:
-     * if ((nbytes = ap_rwrite(buffer + o, nbytes, r)) < 0)
-     * rbb
-     */
-                        if (apr_send(client_socket, buffer + o, &nbytes) != APR_SUCCESS)
-			    break;
-                        o += nbytes;
-                        i -= nbytes;
-                    }
+		apr_brigade_cleanup(bb);
+                if (ap_get_brigade(backconn->input_filters, bb,
+				   AP_MODE_READBYTES, APR_NONBLOCK_READ,
+				   nbytes) == APR_SUCCESS) {
+		    if (ap_pass_brigade(c->output_filters, bb) != APR_SUCCESS)
+			break;
+		    ap_fflush(c->output_filters, bb);
                 }
                 else
                     break;
@@ -323,17 +334,13 @@
 /*		ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                              "proxy: CONNECT: client was set");*/
                 nbytes = sizeof(buffer);
-                if (apr_recv(client_socket, buffer, &nbytes) == APR_SUCCESS) {
-                    o = 0;
-                    i = nbytes;
-                    while(i > 0)
-                    {
-			nbytes = i;
-			if (apr_send(sock, buffer + o, &nbytes) != APR_SUCCESS)
-			    break;
-                        o += nbytes;
-                        i -= nbytes;
-                    }
+		apr_brigade_cleanup(bb);
+                if (ap_get_brigade(c->input_filters, bb, AP_MODE_READBYTES,
+				   APR_NONBLOCK_READ, nbytes) == APR_SUCCESS) {
+		    if (ap_pass_brigade(backconn->output_filters, bb)
+			!= APR_SUCCESS)
+			break;
+		    ap_fflush(backconn->output_filters, bb);
                 }
                 else
                     break;

Reply to: