[httpd] add mod_proxy fixes from upstream (r1366693, r1365604)

jorton jorton at fedoraproject.org
Mon Aug 6 08:59:13 UTC 2012


commit 8c0c115fd2814c56ab56da3780d650a9fcb55920
Author: Joe Orton <jorton at redhat.com>
Date:   Mon Aug 6 09:59:05 2012 +0100

    add mod_proxy fixes from upstream (r1366693, r1365604)

 httpd-2.4.2-r1365604.patch |   15 +++
 httpd-2.4.2-r1366693.patch |  252 ++++++++++++++++++++++++++++++++++++++++++++
 httpd.spec                 |    9 ++-
 3 files changed, 275 insertions(+), 1 deletions(-)
---
diff --git a/httpd-2.4.2-r1365604.patch b/httpd-2.4.2-r1365604.patch
new file mode 100644
index 0000000..d7b962f
--- /dev/null
+++ b/httpd-2.4.2-r1365604.patch
@@ -0,0 +1,15 @@
+# ./pullrev.sh 1365604
+
+http://svn.apache.org/viewvc?view=revision&revision=1365604
+
+--- httpd-2.4.2/modules/proxy/proxy_util.c
++++ httpd-2.4.2/modules/proxy/proxy_util.c
+@@ -852,7 +852,7 @@
+             (balancer = ap_proxy_get_balancer(r->pool, sconf, real, 1))) {
+             int n, l3 = 0;
+             proxy_worker **worker = (proxy_worker **)balancer->workers->elts;
+-            const char *urlpart = ap_strchr_c(real, '/');
++            const char *urlpart = ap_strchr_c(real + sizeof(BALANCER_PREFIX) - 1, '/');
+             if (urlpart) {
+                 if (!urlpart[1])
+                     urlpart = NULL;
diff --git a/httpd-2.4.2-r1366693.patch b/httpd-2.4.2-r1366693.patch
new file mode 100644
index 0000000..674decf
--- /dev/null
+++ b/httpd-2.4.2-r1366693.patch
@@ -0,0 +1,252 @@
+# ./pullrev.sh 1366693
+
+http://svn.apache.org/viewvc?view=revision&revision=1366693
+
+--- httpd-2.4.2/modules/proxy/mod_proxy_connect.c
++++ httpd-2.4.2/modules/proxy/mod_proxy_connect.c
+@@ -205,7 +205,7 @@
+     conn_rec *backconn;
+ 
+     apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc);
+-    apr_status_t err, rv;
++    apr_status_t rv;
+     apr_size_t nbytes;
+     char buffer[HUGE_STRING_LEN];
+     apr_socket_t *client_socket = ap_get_conn_socket(c);
+@@ -216,7 +216,7 @@
+     const apr_pollfd_t *signalled;
+     apr_int32_t pollcnt, pi;
+     apr_int16_t pollevent;
+-    apr_sockaddr_t *uri_addr, *connect_addr;
++    apr_sockaddr_t *nexthop;
+ 
+     apr_uri_t uri;
+     const char *connectname;
+@@ -246,37 +246,32 @@
+     ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01019)
+                   "connecting %s to %s:%d", url, uri.hostname, uri.port);
+ 
+-    /* do a DNS lookup for the destination host */
+-    err = apr_sockaddr_info_get(&uri_addr, uri.hostname, APR_UNSPEC, uri.port,
+-                                0, p);
+-    if (APR_SUCCESS != err) {
++    /* Determine host/port of next hop; from request URI or of a proxy. */
++    connectname = proxyname ? proxyname : uri.hostname;
++    connectport = proxyname ? proxyport : uri.port;
++
++    /* Do a DNS lookup for the next hop */
++    rv = apr_sockaddr_info_get(&nexthop, connectname, APR_UNSPEC, 
++                               connectport, 0, p);
++    if (rv != APR_SUCCESS) {
++        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO()
++                      "failed to resolve hostname '%s'", connectname);
+         return ap_proxyerror(r, HTTP_BAD_GATEWAY,
+                              apr_pstrcat(p, "DNS lookup failure for: ",
+-                                         uri.hostname, NULL));
++                                         connectname, NULL));
+     }
+ 
+-    /* are we connecting directly, or via a proxy? */
+-    if (proxyname) {
+-        connectname = proxyname;
+-        connectport = proxyport;
+-        err = apr_sockaddr_info_get(&connect_addr, proxyname, APR_UNSPEC,
+-                                    proxyport, 0, p);
++    /* Check ProxyBlock directive on the hostname/address.  */
++    if (ap_proxy_checkproxyblock2(r, conf, uri.hostname, 
++                                 proxyname ? NULL : nexthop) != OK) {
++        return ap_proxyerror(r, HTTP_FORBIDDEN,
++                             "Connect to remote machine blocked");
+     }
+-    else {
+-        connectname = uri.hostname;
+-        connectport = uri.port;
+-        connect_addr = uri_addr;
+-    }
++
+     ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
+                   "connecting to remote proxy %s on port %d",
+                   connectname, connectport);
+ 
+-    /* check if ProxyBlock directive on this host */
+-    if (OK != ap_proxy_checkproxyblock(r, conf, uri_addr)) {
+-        return ap_proxyerror(r, HTTP_FORBIDDEN,
+-                             "Connect to remote machine blocked");
+-    }
+-
+     /* Check if it is an allowed port */
+     if(!allowed_port(c_conf, uri.port)) {
+               return ap_proxyerror(r, HTTP_FORBIDDEN,
+@@ -289,15 +284,6 @@
+      * We have determined who to connect to. Now make the connection.
+      */
+ 
+-    /* get all the possible IP addresses for the destname and loop through them
+-     * until we get a successful connection
+-     */
+-    if (APR_SUCCESS != err) {
+-        return ap_proxyerror(r, HTTP_BAD_GATEWAY,
+-                             apr_pstrcat(p, "DNS lookup failure for: ",
+-                                         connectname, NULL));
+-    }
+-
+     /*
+      * At this point we have a list of one or more IP addresses of
+      * the machine to connect to. If configured, reorder this
+@@ -308,7 +294,7 @@
+      * For now we do nothing, ie we get DNS round robin.
+      * XXX FIXME
+      */
+-    failed = ap_proxy_connect_to_backend(&sock, "CONNECT", connect_addr,
++    failed = ap_proxy_connect_to_backend(&sock, "CONNECT", nexthop,
+                                          connectname, conf, r);
+ 
+     /* handle a permanent error from the above loop */
+@@ -355,7 +341,7 @@
+         /* peer reset */
+         ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01021)
+                       "an error occurred creating a new connection "
+-                      "to %pI (%s)", connect_addr, connectname);
++                      "to %pI (%s)", nexthop, connectname);
+         apr_socket_close(sock);
+         return HTTP_INTERNAL_SERVER_ERROR;
+     }
+@@ -370,7 +356,7 @@
+ 
+     ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
+                   "connection complete to %pI (%s)",
+-                  connect_addr, connectname);
++                  nexthop, connectname);
+     apr_table_setn(r->notes, "proxy-source-port", apr_psprintf(r->pool, "%hu",
+                    backconn->local_addr->port));
+ 
+--- httpd-2.4.2/modules/proxy/proxy_util.c
++++ httpd-2.4.2/modules/proxy/proxy_util.c
+@@ -759,48 +759,63 @@
+     return host != NULL && ap_strstr_c(host, This->name) != NULL;
+ }
+ 
+-/* checks whether a host in uri_addr matches proxyblock */
++/* Backwards-compatible interface. */
+ PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf,
+                              apr_sockaddr_t *uri_addr)
+ {
++    return ap_proxy_checkproxyblock2(r, conf, uri_addr->hostname, uri_addr);
++}
++
++#define MAX_IP_STR_LEN (46)
++
++PROXY_DECLARE(int) ap_proxy_checkproxyblock2(request_rec *r, proxy_server_conf *conf,
++                                             const char *hostname, apr_sockaddr_t *addr)
++{
+     int j;
+-    apr_sockaddr_t * src_uri_addr = uri_addr;
++
+     /* XXX FIXME: conf->noproxies->elts is part of an opaque structure */
+     for (j = 0; j < conf->noproxies->nelts; j++) {
+         struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts;
+-        struct apr_sockaddr_t *conf_addr = npent[j].addr;
+-        uri_addr = src_uri_addr;
++        struct apr_sockaddr_t *conf_addr;
++
+         ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
+                       "checking remote machine [%s] against [%s]",
+-                      uri_addr->hostname, npent[j].name);
+-        if (ap_strstr_c(uri_addr->hostname, npent[j].name)
+-            || npent[j].name[0] == '*') {
++                      hostname, npent[j].name);
++        if (ap_strstr_c(hostname, npent[j].name) || npent[j].name[0] == '*') {
+             ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(00916)
+                           "connect to remote machine %s blocked: name %s "
+-                          "matched", uri_addr->hostname, npent[j].name);
++                          "matched", hostname, npent[j].name);
+             return HTTP_FORBIDDEN;
+         }
+-        while (conf_addr) {
+-            uri_addr = src_uri_addr;
+-            while (uri_addr) {
+-                char *conf_ip;
+-                char *uri_ip;
+-                apr_sockaddr_ip_get(&conf_ip, conf_addr);
+-                apr_sockaddr_ip_get(&uri_ip, uri_addr);
++
++        /* No IP address checks if no IP address was passed in,
++         * i.e. the forward address proxy case, where this server does
++         * not resolve the hostname.  */
++        if (!addr)
++            continue;
++
++        for (conf_addr = npent[j].addr; conf_addr; conf_addr = conf_addr->next) {
++            char caddr[MAX_IP_STR_LEN], uaddr[MAX_IP_STR_LEN];
++            apr_sockaddr_t *uri_addr;
++
++            if (apr_sockaddr_ip_getbuf(caddr, sizeof caddr, conf_addr))
++                continue;
++
++            for (uri_addr = addr; uri_addr; uri_addr = uri_addr->next) {
++                if (apr_sockaddr_ip_getbuf(uaddr, sizeof uaddr, uri_addr))
++                    continue;
+                 ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
+-                              "ProxyBlock comparing %s and %s", conf_ip,
+-                              uri_ip);
+-                if (!apr_strnatcasecmp(conf_ip, uri_ip)) {
++                              "ProxyBlock comparing %s and %s", caddr, uaddr);
++                if (!strcmp(caddr, uaddr)) {
+                     ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(00917)
+-                                 "connect to remote machine %s blocked: "
+-                                 "IP %s matched", uri_addr->hostname, conf_ip);
++                                  "connect to remote machine %s blocked: "
++                                  "IP %s matched", hostname, caddr);
+                     return HTTP_FORBIDDEN;
+                 }
+-                uri_addr = uri_addr->next;
+             }
+-            conf_addr = conf_addr->next;
+         }
+     }
++
+     return OK;
+ }
+ 
+@@ -2128,7 +2143,8 @@
+         }
+     }
+     /* check if ProxyBlock directive on this host */
+-    if (OK != ap_proxy_checkproxyblock(r, conf, conn->addr)) {
++    if (OK != ap_proxy_checkproxyblock2(r, conf, uri->hostname, 
++                                       proxyname ? NULL : conn->addr)) {
+         return ap_proxyerror(r, HTTP_FORBIDDEN,
+                              "Connect to remote machine blocked");
+     }
+--- httpd-2.4.2/modules/proxy/mod_proxy.h
++++ httpd-2.4.2/modules/proxy/mod_proxy.h
+@@ -534,6 +534,18 @@
+                                            char **passwordp, char **hostp, apr_port_t *port);
+ PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *message);
+ PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf, apr_sockaddr_t *uri_addr);
++
++/** Test whether the hostname/address of the request are blocked by the ProxyBlock
++ * configuration.
++ * @param r         request
++ * @param conf      server configuration
++ * @param hostname  hostname from request URI
++ * @param addr      resolved address of hostname, or NULL if not known
++ * @return OK on success, or else an errro
++ */
++PROXY_DECLARE(int) ap_proxy_checkproxyblock2(request_rec *r, proxy_server_conf *conf, 
++                                             const char *hostname, apr_sockaddr_t *addr);
++
+ PROXY_DECLARE(int) ap_proxy_pre_http_request(conn_rec *c, request_rec *r);
+ /* DEPRECATED (will be replaced with ap_proxy_connect_backend */
+ PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr_socket_t **, const char *, apr_sockaddr_t *, const char *, proxy_server_conf *, request_rec *);
+--- httpd-2.4.2/modules/proxy/mod_proxy_ftp.c
++++ httpd-2.4.2/modules/proxy/mod_proxy_ftp.c
+@@ -1143,7 +1143,7 @@
+     }
+ 
+     /* check if ProxyBlock directive on this host */
+-    if (OK != ap_proxy_checkproxyblock(r, conf, connect_addr)) {
++    if (OK != ap_proxy_checkproxyblock2(r, conf, connectname, connect_addr)) {
+         return ap_proxyerror(r, HTTP_FORBIDDEN,
+                              "Connect to remote machine blocked");
+     }
diff --git a/httpd.spec b/httpd.spec
index 2a8e017..1a12469 100644
--- a/httpd.spec
+++ b/httpd.spec
@@ -8,7 +8,7 @@
 Summary: Apache HTTP Server
 Name: httpd
 Version: 2.4.2
-Release: 22%{?dist}
+Release: 23%{?dist}
 URL: http://httpd.apache.org/
 Source0: http://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2
 Source1: index.html
@@ -54,6 +54,8 @@ Patch42: httpd-2.4.2-r1326980+.patch
 Patch43: httpd-2.4.2-r1332643+.patch
 Patch44: httpd-2.4.2-r1346905.patch
 Patch45: httpd-2.4.2-r1357685.patch
+Patch46: httpd-2.4.2-r1366693.patch
+Patch47: httpd-2.4.2-r1365604.patch
 License: ASL 2.0
 Group: System Environment/Daemons
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
@@ -167,6 +169,8 @@ authentication to the Apache HTTP Server.
 %patch43 -p1 -b .r1332643+
 %patch44 -p1 -b .r1346905
 %patch45 -p1 -b .r1357685
+%patch46 -p1 -b .r1366693
+%patch47 -p1 -b .r1365604
 
 # Patch in vendor/release string
 sed "s/@RELEASE@/%{vstring}/" < %{PATCH20} | patch -p1
@@ -581,6 +585,9 @@ rm -rf $RPM_BUILD_ROOT
 %{_sysconfdir}/rpm/macros.httpd
 
 %changelog
+* Mon Aug  6 2012 Joe Orton <jorton at redhat.com> - 2.4.2-23
+- add mod_proxy fixes from upstream (r1366693, r1365604)
+
 * Thu Jul 19 2012 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.4.2-22
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
 


More information about the scm-commits mailing list