You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apache-bugdb@apache.org by David Coffin <da...@srs.gov> on 2002/03/18 21:01:06 UTC
mod_proxy/10246: Add ProxyConnAllow directive
>Number: 10246
>Category: mod_proxy
>Synopsis: Add ProxyConnAllow directive
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: apache
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: apache
>Arrival-Date: Mon Mar 18 12:10:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator: david.coffin@srs.gov
>Release: 1.3.22
>Organization:
apache
>Environment:
SunOS xxxx 5.7 Generic_106541-12 sun4u sparc SUNW,Ultra-Enterprise
gcc
others also
>Description:
We want to maintain a list of allowable CONNECT sites via ProxyConnAllow directives - providing opposite functionality from that provided by ProxyBlock, only for the CONNECT (SSL, etc) protocol. If not set (default) or set to *, all CONNECT sessions are allowed.
We are filtering <EMBED> and other html tags after the proxy via other firewall software to keep from html/browser-based viruses, etc. However, filtering is not possible with SSL encrypted sessions via CONNECT through the proxy, in which case we cannot read/filter the content. Rather than turning SSL CONNECT sessions off (via AllowCONNECT directive), we would like to maintain a list of allowable sites, rather than a list of known bad sites (via ProxyBlock directive.) For that, we have devised the ProxyConnAllow directive with a few minor code additions, described below.
3 diff files are cut/pasted in suggested fix block, below
>How-To-Repeat:
>Fix:
*** mod_proxy-old.h Fri Oct 5 04:19:15 2001
--- mod_proxy.h Mon Mar 18 14:09:30 2002
***************
*** 170,175 ****
--- 170,180 ----
struct in_addr addr;
};
+ struct connallowproxy_entry {
+ char *name;
+ struct in_addr addr;
+ };
+
struct nocache_entry {
char *name;
struct in_addr addr;
***************
*** 209,214 ****
--- 214,220 ----
array_header *aliases;
array_header *raliases;
array_header *noproxies;
+ array_header *conallowproxies;
array_header *dirconn;
array_header *nocaches;
array_header *allowed_connect_ports;
*** mod_proxy-old.c Mon Sep 24 16:14:28 2001
--- mod_proxy.c Mon Mar 18 14:11:24 2002
***************
*** 413,418 ****
--- 413,419 ----
ps->aliases = ap_make_array(p, 10, sizeof(struct proxy_alias));
ps->raliases = ap_make_array(p, 10, sizeof(struct proxy_alias));
ps->noproxies = ap_make_array(p, 10, sizeof(struct noproxy_entry));
+ ps->conallowproxies = ap_make_array(p, 10, sizeof(struct connallowproxy_entry));
ps->dirconn = ap_make_array(p, 10, sizeof(struct dirconn_entry));
ps->nocaches = ap_make_array(p, 10, sizeof(struct nocache_entry));
ps->allowed_connect_ports = ap_make_array(p, 10, sizeof(int));
***************
*** 458,463 ****
--- 459,465 ----
ps->aliases = ap_append_arrays(p, base->aliases, overrides->aliases);
ps->raliases = ap_append_arrays(p, base->raliases, overrides->raliases);
ps->noproxies = ap_append_arrays(p, base->noproxies, overrides->noproxies);
+ ps->conallowproxies = ap_append_arrays(p, base->conallowproxies, overrides->conallowproxies);
ps->dirconn = ap_append_arrays(p, base->dirconn, overrides->dirconn);
ps->nocaches = ap_append_arrays(p, base->nocaches, overrides->nocaches);
ps->allowed_connect_ports = ap_append_arrays(p, base->allowed_connect_ports, overrides->allowed_connect_ports);
***************
*** 583,588 ****
--- 585,621 ----
return NULL;
}
+ static const char *
+ set_proxy_conn_allow(cmd_parms *parms, void *dummy, char *arg)
+ {
+ server_rec *s = parms->server;
+ proxy_server_conf *conf =
+ ap_get_module_config(s->module_config, &proxy_module);
+ struct connallowproxy_entry *new;
+ struct connallowproxy_entry *list = (struct connallowproxy_entry *) conf->conallowproxies->elts;
+ struct hostent hp;
+ int found = 0;
+ int i;
+
+ /* Don't duplicate entries */
+ for (i = 0; i < conf->conallowproxies->nelts; i++) {
+ if (strcasecmp(arg, list[i].name) == 0) /* ignore case for host names */
+ found = 1;
+ }
+
+ if (!found) {
+ new = ap_push_array(conf->conallowproxies);
+ new->name = arg;
+ /* Don't do name lookups on things that aren't dotted */
+ if (strchr(arg, '.') != NULL && ap_proxy_host2addr(new->name, &hp) == NULL)
+ /*@@@FIXME: This copies only the first of (possibly many) IP addrs */
+ memcpy(&new->addr, hp.h_addr, sizeof(struct in_addr));
+ else
+ new->addr.s_addr = 0;
+ }
+ return NULL;
+ }
+
/*
* Set the ports CONNECT can use
*/
***************
*** 901,906 ****
--- 934,941 ----
"a virtual path and a URL for reverse proxy behaviour"},
{"ProxyBlock", set_proxy_exclude, NULL, RSRC_CONF, ITERATE,
"A list of names, hosts or domains to which the proxy will not connect"},
+ {"ProxyConnAllow", set_proxy_conn_allow, NULL, RSRC_CONF, ITERATE,
+ "A list of names, hosts or domains to which the proxy will allow CONNECT"},
{"ProxyReceiveBufferSize", set_recv_buffer_size, NULL, RSRC_CONF, TAKE1,
"Receive buffer size for outgoing HTTP and FTP connections in bytes"},
{"NoProxy", set_proxy_dirconn, NULL, RSRC_CONF, ITERATE,
*** proxy_connect-old.c Fri Oct 5 04:19:16 2001
--- proxy_connect.c Mon Mar 18 14:28:32 2002
***************
*** 122,132 ****
--- 122,134 ----
char buffer[HUGE_STRING_LEN];
int nbytes, i, j;
fd_set fds;
+ int pcaTst;
void *sconf = r->server->module_config;
proxy_server_conf *conf =
(proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts;
+ struct connallowproxy_entry *capent = (struct connallowproxy_entry *) conf->conallowproxies->elts;
memset(&server, '\0', sizeof(server));
server.sin_family = AF_INET;
***************
*** 151,156 ****
--- 153,185 ----
"Connect to remote machine blocked");
}
+ /* check if ProxyConnAllow directive on this host */
+ destaddr.s_addr = ap_inet_addr(host);
+ pcaTst = 0; // 0 = fails to match
+ if (conf->conallowproxies->nelts == 0) {
+ // default, if no entries, allow all
+ // disallow all via AllowCONNECT directive
+ pcaTst = 1; // 1 = matched
+ }
+ else {
+ for (i = 0; i < conf->conallowproxies->nelts; i++) {
+ /* matches if first char of conf entry is *
+ or entry is contained in hostname
+ or address equals address of entry
+ */
+ if( capent[i].name[0] == '*'
+ || (capent[i].name != NULL && strstr(host, capent[i].name) != NULL)
+ || destaddr.s_addr == capent[i].addr.s_addr )
+ {
+ pcaTst = 1; // 1 = matched
+ break;
+ }
+ }
+ }
+ if( pcaTst == 0 )
+ return ap_proxyerror(r, HTTP_FORBIDDEN,
+ "Connect to remote machine blocked");
+
/* Check if it is an allowed port */
if (conf->allowed_connect_ports->nelts == 0) {
/* Default setting if not overridden by AllowCONNECT */
>Release-Note:
>Audit-Trail:
>Unformatted:
[In order for any reply to be added to the PR database, you need]
[to include <ap...@Apache.Org> in the Cc line and make sure the]
[subject line starts with the report component and number, with ]
[or without any 'Re:' prefixes (such as "general/1098:" or ]
["Re: general/1098:"). If the subject doesn't match this ]
[pattern, your message will be misfiled and ignored. The ]
["apbugs" address is not added to the Cc line of messages from ]
[the database automatically because of the potential for mail ]
[loops. If you do not include this Cc, your reply may be ig- ]
[nored unless you are responding to an explicit request from a ]
[developer. Reply only with text; DO NOT SEND ATTACHMENTS! ]