You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Lubomir Rintel <lk...@v3.sk> on 2014/03/11 15:00:39 UTC

[PATCH 56152 4/4] mod_proxy: Share NoProxy parameter parsing and evaluation with ProxyBlock

From: Lubomir Rintel <lu...@gooddata.com>

They do the same task now, so we can remove some duplicate code. They do the
same thing except that ProxyBlock does certain things better -- they support
masked network addresses, thus we can now block subnets.
---
 docs/manual/mod/mod_proxy.xml | 14 +++++++-------
 modules/proxy/mod_proxy.c     | 27 ++-------------------------
 modules/proxy/mod_proxy.h     |  5 -----
 modules/proxy/proxy_util.c    | 35 ++---------------------------------
 4 files changed, 11 insertions(+), 70 deletions(-)

diff --git a/docs/manual/mod/mod_proxy.xml b/docs/manual/mod/mod_proxy.xml
index d0adb3a..38bedee 100644
--- a/docs/manual/mod/mod_proxy.xml
+++ b/docs/manual/mod/mod_proxy.xml
@@ -1509,8 +1509,8 @@ will rewrite a cookie with backend path <code>/</code> (or
 <usage>
     <p>The <directive>ProxyBlock</directive> directive can be used to
     block FTP or HTTP access to certain hosts via the proxy, based on
-    a full or partial hostname match, or, if applicable, an IP address
-    comparison.</p>
+    a host name or a domain name match, or, if applicable, an IP host or
+    network address comparison.</p>
 
     <p>Each of the arguments to the <directive>ProxyBlock</directive>
     directive can be either <code>*</code> or a alphanumeric string.
@@ -1522,11 +1522,11 @@ will rewrite a cookie with backend path <code>/</code> (or
     <module>mod_proxy</module> will deny access to all FTP or HTTP
     sites.</p>
 
-    <p>Otherwise, for any request for an HTTP or FTP resource via the
-    proxy, <module>mod_proxy</module> will check the hostname of the
-    request URI against each specified string.  If a partial string
-    match is found, access is denied.  If no matches against hostnames
-    are found, and a remote (forward) proxy is configured using
+    <p>Otherwise, the matching same as one used with
+    <directive>NoProxy</directive> is conducted to check the hostname of
+    the request URI against each specified string.  If a match is found,
+    access is denied.  If no matches against hostnames are found, and a
+    remote (forward) proxy is configured using
     <directive>ProxyRemote</directive> or
     <directive>ProxyRemoteMatch</directive>, access is allowed.  If no
     remote (forward) proxy is configured, the IP address of the
diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
index bd3bf82..707067c 100644
--- a/modules/proxy/mod_proxy.c
+++ b/modules/proxy/mod_proxy.c
@@ -1202,7 +1202,7 @@ static void * create_proxy_config(apr_pool_t *p, server_rec *s)
     ps->sec_proxy = apr_array_make(p, 10, sizeof(ap_conf_vector_t *));
     ps->proxies = apr_array_make(p, 10, sizeof(struct proxy_remote));
     ps->aliases = apr_array_make(p, 10, sizeof(struct proxy_alias));
-    ps->noproxies = apr_array_make(p, 10, sizeof(struct noproxy_entry));
+    ps->noproxies = apr_array_make(p, 10, sizeof(struct exclude_entry));
     ps->dirconn = apr_array_make(p, 10, sizeof(struct exclude_entry));
     ps->workers = apr_array_make(p, 10, sizeof(proxy_worker));
     ps->balancers = apr_array_make(p, 10, sizeof(proxy_balancer));
@@ -1783,31 +1783,8 @@ static const char *
     server_rec *s = parms->server;
     proxy_server_conf *conf =
     ap_get_module_config(s->module_config, &proxy_module);
-    struct noproxy_entry *new;
-    struct noproxy_entry *list = (struct noproxy_entry *) conf->noproxies->elts;
-    struct apr_sockaddr_t *addr;
-    int found = 0;
-    int i;
 
-    /* Don't duplicate entries */
-    for (i = 0; i < conf->noproxies->nelts; i++) {
-        if (strcasecmp(arg, list[i].name) == 0) { /* ignore case for host names */
-            found = 1;
-            break;
-        }
-    }
-
-    if (!found) {
-        new = apr_array_push(conf->noproxies);
-        new->name = arg;
-        if (APR_SUCCESS == apr_sockaddr_info_get(&addr, new->name, APR_UNSPEC, 0, 0, parms->pool)) {
-            new->addr = addr;
-        }
-        else {
-            new->addr = NULL;
-        }
-    }
-    return NULL;
+    return add_exclude_list(parms, arg, conf->noproxies);
 }
 
 
diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h
index 392c4d0..1ffb9ce 100644
--- a/modules/proxy/mod_proxy.h
+++ b/modules/proxy/mod_proxy.h
@@ -122,11 +122,6 @@ struct exclude_entry {
     int (*matcher) (struct exclude_entry * This, request_rec *r);
 };
 
-struct noproxy_entry {
-    const char *name;
-    struct apr_sockaddr_t *addr;
-};
-
 typedef struct {
     apr_array_header_t *proxies;
     apr_array_header_t *sec_proxy;
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
index 22b6ea1..bdb01ca 100644
--- a/modules/proxy/proxy_util.c
+++ b/modules/proxy/proxy_util.c
@@ -783,8 +783,6 @@ static int proxy_match_word(struct exclude_entry *This, request_rec *r)
     return host != NULL && ap_strstr_c(host, This->name) != NULL;
 }
 
-#define MAX_IP_STR_LEN (46)
-
 PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf,
                                             const char *hostname, apr_sockaddr_t *addr)
 {
@@ -792,45 +790,16 @@ PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *c
 
     /* 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;
-
+        struct exclude_entry *npent = (struct exclude_entry *) conf->noproxies->elts;
         ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                       "checking remote machine [%s] against [%s]",
                       hostname, npent[j].name);
-        if (ap_strstr_c(hostname, npent[j].name) || npent[j].name[0] == '*') {
+        if (npent[j].matcher(&npent[j], r) || npent[j].name[0] == '*') {
             ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(00916)
                           "connect to remote machine %s blocked: name %s "
                           "matched", hostname, npent[j].name);
             return HTTP_FORBIDDEN;
         }
-
-        /* 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", 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", hostname, caddr);
-                    return HTTP_FORBIDDEN;
-                }
-            }
-        }
     }
 
     return OK;
-- 
1.8.3.1