You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ji...@apache.org on 2010/02/15 20:54:42 UTC

svn commit: r910322 - in /httpd/httpd/branches/2.2.x: CHANGES STATUS docs/manual/mod/mod_proxy.xml docs/manual/mod/mod_proxy_connect.xml docs/manual/mod/mod_proxy_http.xml include/ap_mmn.h modules/proxy/mod_proxy.h modules/proxy/proxy_util.c

Author: jim
Date: Mon Feb 15 19:54:41 2010
New Revision: 910322

URL: http://svn.apache.org/viewvc?rev=910322&view=rev
Log: (empty)

Modified:
    httpd/httpd/branches/2.2.x/CHANGES
    httpd/httpd/branches/2.2.x/STATUS
    httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy.xml
    httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_connect.xml
    httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_http.xml
    httpd/httpd/branches/2.2.x/include/ap_mmn.h
    httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h
    httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c

Modified: httpd/httpd/branches/2.2.x/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/CHANGES?rev=910322&r1=910321&r2=910322&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/CHANGES [utf-8] (original)
+++ httpd/httpd/branches/2.2.x/CHANGES [utf-8] Mon Feb 15 19:54:41 2010
@@ -9,6 +9,10 @@
      access control is still vulnerable, unless using OpenSSL >= 0.9.8l.
      [Joe Orton, Ruediger Pluem, Hartmut Keil <Hartmut.Keil adnovum.ch>]
 
+  *) mod_proxy, mod_proxy_http: Support remote https proxies
+     by using HTTP CONNECT.
+     PR 19188.  [Philippe Dutrueux <lilas evidian.com>, Rainer Jung]
+
   *) worker: Don't report server has reached MaxClients until it has.
      Add message when server gets within MinSpareThreads of MaxClients.
      PR 46996.  [Dan Poirier]

Modified: httpd/httpd/branches/2.2.x/STATUS
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/STATUS?rev=910322&r1=910321&r2=910322&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/STATUS (original)
+++ httpd/httpd/branches/2.2.x/STATUS Mon Feb 15 19:54:41 2010
@@ -87,17 +87,6 @@
 PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
   [ start all new proposals below, under PATCHES PROPOSED. ]
 
-  * mod_proxy: Allow https to a remote forward proxy by issuing an HTTP
-    CONNECT request. This adds a CONNECT client (sending a connect request).
-    It is not the same as mod_proxy_connect, which is a CONNECT server
-    (responding to connect requests).
-    PR: https://issues.apache.org/bugzilla/show_bug.cgi?id=19188
-    Trunk patches: http://svn.apache.org/viewvc?rev=909323&view=rev
-                   http://svn.apache.org/viewvc?rev=910079&view=rev
-                   http://svn.apache.org/viewvc?rev=910081&view=rev
-                   http://svn.apache.org/viewvc?rev=910124&view=rev
-    2.2.x patch: http://people.apache.org/~rjung/patches/bz19188-proxyremote-https-v2.patch
-    +1: rjung, minfrin, jim
 
 
 PATCHES PROPOSED TO BACKPORT FROM TRUNK:

Modified: httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy.xml?rev=910322&r1=910321&r2=910322&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy.xml (original)
+++ httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy.xml Mon Feb 15 19:54:41 2010
@@ -475,8 +475,9 @@
     </example>
 
     <p><var>scheme</var> is effectively the protocol that should be used to
-    communicate with the remote server; only <code>http</code> is supported by
-    this module.</p>
+    communicate with the remote server; only <code>http</code> and <code>https</code>
+    are supported by this module. When using <code>https</code>, the requests
+    are forwarded through the remote proxy using the HTTP CONNECT method.</p>
 
     <example><title>Example</title>
       ProxyRemote http://goodguys.example.com/ http://mirrorguys.example.com:8000<br />

Modified: httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_connect.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_connect.xml?rev=910322&r1=910321&r2=910322&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_connect.xml (original)
+++ httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_connect.xml Mon Feb 15 19:54:41 2010
@@ -39,6 +39,11 @@
     requests, <module>mod_proxy</module> and
     <module>mod_proxy_connect</module> have to be present in the server.</p>
 
+    <p>CONNECT is also used, when the server needs to send an HTTPS request
+    through a forward proxy. In this case the server acts as a CONNECT client.
+    This functionality is part of <module>mod_proxy</module> and
+    <module>mod_proxy_connect</module> is not needed in this case.</p>
+
     <note type="warning"><title>Warning</title>
       <p>Do not enable proxying until you have <a
       href="mod_proxy.html#access">secured your server</a>. Open proxy

Modified: httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_http.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_http.xml?rev=910322&r1=910321&r2=910322&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_http.xml (original)
+++ httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_http.xml Mon Feb 15 19:54:41 2010
@@ -32,7 +32,7 @@
 <summary>
     <p>This module <em>requires</em> the service of <module
     >mod_proxy</module>. It provides the features used for
-    proxying HTTP requests. <module>mod_proxy_http</module>
+    proxying HTTP and HTTPS requests. <module>mod_proxy_http</module>
     supports HTTP/0.9, HTTP/1.0 and HTTP/1.1. It does <em>not</em>
     provide any caching abilities. If you want to set up a caching
     proxy, you might want to use the additional service of the

Modified: httpd/httpd/branches/2.2.x/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/include/ap_mmn.h?rev=910322&r1=910321&r2=910322&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/include/ap_mmn.h (original)
+++ httpd/httpd/branches/2.2.x/include/ap_mmn.h Mon Feb 15 19:54:41 2010
@@ -138,6 +138,7 @@
  * 20051115.22 (2.2.12) Add ap_escape_html2 API, with additional option
  * 20051115.23 (2.2.12) Add ap_open_piped_log_ex API, with cmdtype option,
  *                      and conditional cmdtype member of piped_log struct
+ * 20051115.24 (2.2.15) Add forward member to proxy_conn_rec
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503232UL /* "AP22" */
@@ -145,7 +146,7 @@
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20051115
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 23                    /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 24                    /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a

Modified: httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h?rev=910322&r1=910321&r2=910322&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h (original)
+++ httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h Mon Feb 15 19:54:41 2010
@@ -247,6 +247,7 @@
                              * which the backend currently answers. */
     int          need_flush;/* Flag to decide whether we need to flush the
                              * filter chain or not */
+    void         *forward;  /* opaque forward proxy data */
 } proxy_conn_rec;
 
 typedef struct {

Modified: httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c?rev=910322&r1=910321&r2=910322&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c (original)
+++ httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c Mon Feb 15 19:54:41 2010
@@ -29,6 +29,18 @@
 #define apr_socket_create apr_socket_create_ex
 #endif
 
+/*
+ * Opaque structure containing target server info when
+ * using a forward proxy.
+ * Up to now only used in combination with HTTP CONNECT.
+ */
+typedef struct {
+    int          use_http_connect; /* Use SSL Tunneling via HTTP CONNECT */
+    const char   *target_host;     /* Target hostname */
+    apr_port_t   target_port;      /* Target port */
+    const char   *proxy_auth;      /* Proxy authorization */
+} forward_info;
+
 /* Global balancer counter */
 int PROXY_DECLARE_DATA proxy_lb_workers = 0;
 static int lb_workers_limit = 0;
@@ -2085,6 +2097,34 @@
         if (proxyname) {
             conn->hostname = apr_pstrdup(conn->pool, proxyname);
             conn->port = proxyport;
+            /*
+             * If we have a forward proxy and the protocol is HTTPS,
+             * then we need to prepend a HTTP CONNECT request before
+             * sending our actual HTTPS requests.
+             * Save our real backend data for using it later during HTTP CONNECT.
+             */
+            if (conn->is_ssl) {
+                const char *proxy_auth;
+
+                forward_info *forward = apr_pcalloc(conn->pool, sizeof(forward_info));
+                conn->forward = forward;
+                forward->use_http_connect = 1;
+                forward->target_host = apr_pstrdup(conn->pool, uri->hostname);
+                forward->target_port = uri->port;
+                /* Do we want to pass Proxy-Authorization along?
+                 * If we haven't used it, then YES
+                 * If we have used it then MAYBE: RFC2616 says we MAY propagate it.
+                 * So let's make it configurable by env.
+                 * The logic here is the same used in mod_proxy_http.
+                 */
+                proxy_auth = apr_table_get(r->headers_in, "Proxy-Authorization");
+                if (proxy_auth != NULL &&
+                    proxy_auth[0] != '\0' &&
+                    r->user == NULL && /* we haven't yet authenticated */
+                    apr_table_get(r->subprocess_env, "Proxy-Chain-Auth")) {
+                    forward->proxy_auth = apr_pstrdup(conn->pool, proxy_auth);
+                }
+            }
         }
         else {
             conn->hostname = apr_pstrdup(conn->pool, uri->hostname);
@@ -2224,6 +2264,102 @@
 }
 #endif /* USE_ALTERNATE_IS_CONNECTED */
 
+
+/*
+ * Send a HTTP CONNECT request to a forward proxy.
+ * The proxy is given by "backend", the target server
+ * is contained in the "forward" member of "backend".
+ */
+static apr_status_t send_http_connect(proxy_conn_rec *backend,
+                                      server_rec *s)
+{
+    int status;
+    apr_size_t nbytes;
+    apr_size_t left;
+    int complete = 0;
+    char buffer[HUGE_STRING_LEN];
+    char drain_buffer[HUGE_STRING_LEN];
+    forward_info *forward = (forward_info *)backend->forward;
+    int len = 0;
+
+    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+                 "proxy: CONNECT: sending the CONNECT request for %s:%d "
+                 "to the remote proxy %pI (%s)",
+                 forward->target_host, forward->target_port,
+                 backend->addr, backend->hostname);
+    /* Create the CONNECT request */
+    nbytes = apr_snprintf(buffer, sizeof(buffer),
+                          "CONNECT %s:%d HTTP/1.0" CRLF,
+                          forward->target_host, forward->target_port);
+    /* Add proxy authorization from the initial request if necessary */
+    if (forward->proxy_auth != NULL) {
+        nbytes += apr_snprintf(buffer + nbytes, sizeof(buffer) - nbytes,
+                               "Proxy-Authorization: %s" CRLF,
+                               forward->proxy_auth);
+    }
+    /* Set a reasonable agent and send everything */
+    nbytes += apr_snprintf(buffer + nbytes, sizeof(buffer) - nbytes,
+                           "Proxy-agent: %s" CRLF CRLF,
+                           ap_get_server_banner());
+    apr_socket_send(backend->sock, buffer, &nbytes);
+
+    /* Receive the whole CONNECT response */
+    left = sizeof(buffer) - 1;
+    /* Read until we find the end of the headers or run out of buffer */
+    do {
+        nbytes = left;
+        status = apr_socket_recv(backend->sock, buffer + len, &nbytes);
+        len += nbytes;
+        left -= nbytes;
+        buffer[len] = '\0';
+        if (strstr(buffer + len - nbytes, "\r\n\r\n") != NULL) {
+            complete = 1;
+            break;
+        }
+    } while (status == APR_SUCCESS && left > 0);
+    /* Drain what's left */
+    if (!complete) {
+        nbytes = sizeof(drain_buffer) - 1;
+        while (status == APR_SUCCESS && nbytes) {
+            status = apr_socket_recv(backend->sock, drain_buffer, &nbytes);
+            buffer[nbytes] = '\0';
+            nbytes = sizeof(drain_buffer) - 1;
+            if (strstr(drain_buffer, "\r\n\r\n") != NULL) {
+                complete = 1;
+                break;
+            }
+        }
+    }
+
+    /* Check for HTTP_OK response status */
+    if (status == APR_SUCCESS) {
+        int major, minor;
+        /* Only scan for three character status code */
+        char code_str[4];
+
+        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+                     "send_http_connect: response from the forward proxy: %s",
+                     buffer);
+
+        /* Extract the returned code */
+        if (sscanf(buffer, "HTTP/%u.%u %3s", &major, &minor, code_str) == 3) {
+            status = atoi(code_str);
+            if (status == HTTP_OK) {
+                status = APR_SUCCESS;
+            }
+            else {
+                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+                             "send_http_connect: the forward proxy returned code is '%s'",
+                             code_str);
+            status = APR_INCOMPLETE;
+            }
+        }
+    }
+
+    return(status);
+}
+
+
 PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
                                             proxy_conn_rec *conn,
                                             proxy_worker *worker,
@@ -2336,7 +2472,33 @@
              apr_socket_timeout_set(newsock, s->timeout);
         }
 
-        conn->sock   = newsock;
+        conn->sock = newsock;
+
+        if (conn->forward) {
+            forward_info *forward = (forward_info *)conn->forward;
+            /*
+             * For HTTP CONNECT we need to prepend CONNECT request before
+             * sending our actual HTTPS requests.
+             */
+            if (forward->use_http_connect) {
+                rv = send_http_connect(conn, s);
+                /* If an error occurred, loop round and try again */
+                if (rv != APR_SUCCESS) {
+                    conn->sock = NULL;
+                    apr_socket_close(newsock);
+                    loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR;
+                    ap_log_error(APLOG_MARK, loglevel, rv, s,
+                                 "proxy: %s: attempt to connect to %s:%d "
+                                 "via http CONNECT through %pI (%s) failed",
+                                 proxy_function,
+                                 forward->target_host, forward->target_port,
+                                 backend_addr, worker->hostname);
+                    backend_addr = backend_addr->next;
+                    continue;
+                }
+            }
+        }
+
         connected    = 1;
     }
     /*
@@ -2516,4 +2678,3 @@
     }
     return rv;
 }
-



Re: svn commit: r910322 - in /httpd/httpd/branches/2.2.x: CHANGES STATUS docs/manual/mod/mod_proxy.xml docs/manual/mod/mod_proxy_connect.xml docs/manual/mod/mod_proxy_http.xml include/ap_mmn.h modules/proxy/mod_proxy.h modules/proxy/proxy_util.c

Posted by André Malo <nd...@perlig.de>.
* jim@apache.org wrote: 


> Author: jim
> Date: Mon Feb 15 19:54:41 2010
> New Revision: 910322
>
> URL: http://svn.apache.org/viewvc?rev=910322&view=rev
> Log: (empty)

'nough said ;)

nd