chuck 97/01/05 01:06:11
Modified: src/modules/proxy mod_proxy.c mod_proxy.h proxy_connect.c
proxy_ftp.c proxy_http.c
Log:
Add ProxyBlock directive w/IP address caching. Add IP address caching to
NoCache directive as well. ProxyBlock works with all handlers; NoCache now
also works with FTP for anonymous logins. Still more code cleanup.
Revision Changes Path
1.8 +40 -1 apache/src/modules/proxy/mod_proxy.c
Index: mod_proxy.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/mod_proxy.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -C3 -r1.7 -r1.8
*** mod_proxy.c 1997/01/01 18:19:59 1.7
--- mod_proxy.c 1997/01/05 09:06:05 1.8
***************
*** 256,261 ****
--- 256,262 ----
ps->proxies = make_array(p, 10, sizeof(struct proxy_remote));
ps->aliases = make_array(p, 10, sizeof(struct proxy_alias));
+ ps->noproxies = make_array(p, 10, sizeof(struct noproxy_entry));
ps->nocaches = make_array(p, 10, sizeof(struct nocache_entry));
ps->req = 0;
***************
*** 327,332 ****
--- 328,364 ----
}
static const char *
+ set_proxy_exclude(cmd_parms *parms, void *dummy, char *arg)
+ {
+ server_rec *s = parms->server;
+ proxy_server_conf *conf =
+ get_module_config (s->module_config, &proxy_module);
+ struct noproxy_entry *new;
+ struct noproxy_entry *list=(struct noproxy_entry*)conf->noproxies->elts;
+ int found = 0;
+ int i;
+
+ /* Don't duplicate entries */
+ for (i=0; i < conf->noproxies->nelts; i++)
+ {
+ if (strcmp(arg, list[i].name) == 0)
+ found = 1;
+ }
+
+ if (!found)
+ {
+ new = push_array (conf->noproxies);
+ new->name = arg;
+ /* Don't do name lookups on things that aren't dotted */
+ if (strchr(arg, '.') != NULL)
+ proxy_host2addr(new->name, &new->addr);
+ else
+ new->addr.s_addr = 0;
+ }
+ return NULL;
+ }
+
+ static const char *
set_proxy_req(cmd_parms *parms, void *dummy, int flag)
{
proxy_server_conf *psf =
***************
*** 455,460 ****
--- 487,497 ----
{
new = push_array (conf->nocaches);
new->name = arg;
+ /* Don't do name lookups on things that aren't dotted */
+ if (strchr(arg, '.') != NULL)
+ proxy_host2addr(new->name, &new->addr);
+ else
+ new->addr.s_addr= 0;
}
return NULL;
}
***************
*** 471,476 ****
--- 508,515 ----
"a scheme, partial URL or '*' and a proxy server"},
{ "ProxyPass", add_pass, NULL, RSRC_CONF, TAKE2,
"a virtual path and a URL"},
+ { "ProxyBlock", set_proxy_exclude, NULL, RSRC_CONF, ITERATE,
+ "A list of names, hosts or domains to which the proxy will not connect"
},
{ "CacheRoot", set_cache_root, NULL, RSRC_CONF, TAKE1,
"The directory to store cache files"},
{ "CacheSize", set_cache_size, NULL, RSRC_CONF, TAKE1,
***************
*** 488,494 ****
{ "CacheDirLength", set_cache_dirlength, NULL, RSRC_CONF, TAKE1,
"The number of characters in subdirectory names" },
{ "NoCache", set_cache_exclude, NULL, RSRC_CONF, ITERATE,
! "A list of hosts or domains for which caching is *not* provided" },
{ NULL }
};
--- 527,533 ----
{ "CacheDirLength", set_cache_dirlength, NULL, RSRC_CONF, TAKE1,
"The number of characters in subdirectory names" },
{ "NoCache", set_cache_exclude, NULL, RSRC_CONF, ITERATE,
! "A list of names, hosts or domains for which caching is *not* provided"
},
{ NULL }
};
1.7 +11 -8 apache/src/modules/proxy/mod_proxy.h
Index: mod_proxy.h
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/mod_proxy.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -C3 -r1.6 -r1.7
*** mod_proxy.h 1997/01/01 18:20:00 1.6
--- mod_proxy.h 1997/01/05 09:06:05 1.7
***************
*** 84,100 ****
2. Add gopher & WAIS
! 3. NoProxy directive for excluding sites to proxy
! 4. Use protocol handler struct a la Apache module handlers (Dirk van Gulik)
!
! 5. Use a cache expiry database for more efficient GC (Jeremy Wohl)
!
! 6. Handle multiple IPs for doconnect()
! 7. Bulletproof GC against SIGALRM
! 8. Make HTTPS and SNEWS ports configurable from a list
Chuck Murcko <[EMAIL PROTECTED]> 1 Oct 96
--- 84,96 ----
2. Add gopher & WAIS
! 3. Use protocol handler struct a la Apache module handlers (Dirk van Gulik)
! 4. Use a cache expiry database for more efficient GC (Jeremy Wohl)
! 5. Handle multiple IPs for doconnect()
! 6. Bulletproof GC against SIGALRM
Chuck Murcko <[EMAIL PROTECTED]> 1 Oct 96
***************
*** 157,164 ****
--- 153,166 ----
char *fake;
};
+ struct noproxy_entry {
+ char *name;
+ struct in_addr addr;
+ };
+
struct nocache_entry {
char *name;
+ struct in_addr addr;
};
#define DEFAULT_CACHE_SPACE 5
***************
*** 184,189 ****
--- 186,192 ----
struct cache_conf cache; /* cache configuration */
array_header *proxies;
array_header *aliases;
+ array_header *noproxies;
array_header *nocaches;
int req; /* true if proxy requests are enabled */
} proxy_server_conf;
1.5 +27 -6 apache/src/modules/proxy/proxy_connect.c
Index: proxy_connect.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_connect.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C3 -r1.4 -r1.5
*** proxy_connect.c 1997/01/01 18:20:02 1.4
--- proxy_connect.c 1997/01/05 09:06:06 1.5
***************
*** 87,92 ****
--- 87,93 ----
proxy_connect_handler(request_rec *r, struct cache_req *c, char *url)
{
struct sockaddr_in server;
+ struct in_addr destaddr;
const char *host, *err;
char *p;
int port, sock;
***************
*** 94,99 ****
--- 95,105 ----
int nbytes, i;
fd_set fds;
+ void *sconf = r->server->module_config;
+ proxy_server_conf *conf =
+ (proxy_server_conf *)get_module_config(sconf, &proxy_module);
+ struct noproxy_entry *npent=(struct noproxy_entry
*)conf->noproxies->elts;
+
memset(&server, '\0', sizeof(server));
server.sin_family=AF_INET;
***************
*** 101,113 ****
host = url;
p = strchr(url, ':');
! if (p==NULL) port = DEFAULT_HTTPS_PORT;
else
{
port = atoi(p+1);
*p='\0';
}
switch (port)
{
case DEFAULT_HTTPS_PORT:
--- 107,129 ----
host = url;
p = strchr(url, ':');
! if (p==NULL)
! port = DEFAULT_HTTPS_PORT;
else
{
port = atoi(p+1);
*p='\0';
}
+ /* check if ProxyBlock directive on this host */
+ inet_aton(host, &destaddr);
+ for (i=0; i < conf->noproxies->nelts; i++)
+ {
+ if ((npent[i].name != NULL && strstr(host, npent[i].name) != NULL)
+ || destaddr.s_addr == npent[i].addr.s_addr || npent[i].name[0] ==
'*')
+ return proxyerror(r, "Connect to remote machine blocked");
+ }
+
switch (port)
{
case DEFAULT_HTTPS_PORT:
***************
*** 121,127 ****
server.sin_port = htons(port);
err = proxy_host2addr(host, &server.sin_addr);
! if (err != NULL) return proxyerror(r, err); /* give up */
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == -1)
--- 137,144 ----
server.sin_port = htons(port);
err = proxy_host2addr(host, &server.sin_addr);
! if (err != NULL)
! return proxyerror(r, err); /* give up */
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == -1)
***************
*** 164,171 ****
Explain0("sock was set");
if((nbytes=read(sock,buffer,HUGE_STRING_LEN))!=0)
{
! if(nbytes==-1) break;
! if(write(r->connection->client->fd, buffer,
nbytes)==EOF)break;
Explain1("Wrote %d bytes to client", nbytes);
}
else break;
--- 181,190 ----
Explain0("sock was set");
if((nbytes=read(sock,buffer,HUGE_STRING_LEN))!=0)
{
! if (nbytes==-1)
! break;
! if (write(r->connection->client->fd, buffer, nbytes)==EOF)
! break;
Explain1("Wrote %d bytes to client", nbytes);
}
else break;
***************
*** 176,183 ****
if((nbytes=read(r->connection->client->fd,buffer,
HUGE_STRING_LEN))!=0)
{
! if(nbytes==-1) break;
! if(write(sock,buffer,nbytes)==EOF) break;
Explain1("Wrote %d bytes to server", nbytes);
}
else break;
--- 195,204 ----
if((nbytes=read(r->connection->client->fd,buffer,
HUGE_STRING_LEN))!=0)
{
! if (nbytes==-1)
! break;
! if (write(sock,buffer,nbytes)==EOF)
! break;
Explain1("Wrote %d bytes to server", nbytes);
}
else break;
1.6 +47 -19 apache/src/modules/proxy/proxy_ftp.c
Index: proxy_ftp.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_ftp.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -C3 -r1.5 -r1.6
*** proxy_ftp.c 1997/01/01 18:20:02 1.5
--- proxy_ftp.c 1997/01/05 09:06:06 1.6
***************
*** 110,120 ****
proxy_ftp_canon(request_rec *r, char *url)
{
char *user, *password, *host, *path, *parms, *p, sport[7];
const char *err;
int port;
port = DEFAULT_FTP_PORT;
! err = proxy_canon_netloc(r->pool, &url, &user, &password, &host, &port);
if (err) return BAD_REQUEST;
if (user != NULL && !ftp_check_string(user)) return BAD_REQUEST;
if (password != NULL && !ftp_check_string(password)) return BAD_REQUEST;
--- 110,121 ----
proxy_ftp_canon(request_rec *r, char *url)
{
char *user, *password, *host, *path, *parms, *p, sport[7];
+ pool *pool=r->pool;
const char *err;
int port;
port = DEFAULT_FTP_PORT;
! err = proxy_canon_netloc(pool, &url, &user, &password, &host, &port);
if (err) return BAD_REQUEST;
if (user != NULL && !ftp_check_string(user)) return BAD_REQUEST;
if (password != NULL && !ftp_check_string(password)) return BAD_REQUEST;
***************
*** 129,140 ****
if (p != NULL)
{
*(p++) = '\0';
! parms = proxy_canonenc(r->pool, p, strlen(p), enc_parm, r->proxyreq);
if (parms == NULL) return BAD_REQUEST;
} else
parms = "";
! path = proxy_canonenc(r->pool, url, strlen(url), enc_path, r->proxyreq);
if (path == NULL) return BAD_REQUEST;
if (!ftp_check_string(path)) return BAD_REQUEST;
--- 130,141 ----
if (p != NULL)
{
*(p++) = '\0';
! parms = proxy_canonenc(pool, p, strlen(p), enc_parm, r->proxyreq);
if (parms == NULL) return BAD_REQUEST;
} else
parms = "";
! path = proxy_canonenc(pool, url, strlen(url), enc_path, r->proxyreq);
if (path == NULL) return BAD_REQUEST;
if (!ftp_check_string(path)) return BAD_REQUEST;
***************
*** 142,156 ****
{
if (p != NULL)
{
! p = proxy_canonenc(r->pool, r->args, strlen(r->args), enc_parm, 1);
if (p == NULL) return BAD_REQUEST;
! parms = pstrcat(r->pool, parms, "?", p, NULL);
}
else
{
! p = proxy_canonenc(r->pool, r->args, strlen(r->args), enc_path, 1);
if (p == NULL) return BAD_REQUEST;
! path = pstrcat(r->pool, path, "?", p, NULL);
}
r->args = NULL;
}
--- 143,157 ----
{
if (p != NULL)
{
! p = proxy_canonenc(pool, r->args, strlen(r->args), enc_parm, 1);
if (p == NULL) return BAD_REQUEST;
! parms = pstrcat(pool, parms, "?", p, NULL);
}
else
{
! p = proxy_canonenc(pool, r->args, strlen(r->args), enc_path, 1);
if (p == NULL) return BAD_REQUEST;
! path = pstrcat(pool, path, "?", p, NULL);
}
r->args = NULL;
}
***************
*** 160,166 ****
if (port != DEFAULT_FTP_PORT) sprintf(sport, ":%d", port);
else sport[0] = '\0';
! r->filename = pstrcat(r->pool, "proxy:ftp://", (user != NULL) ? user :
"",
(password != NULL) ? ":" : "",
(password != NULL) ? password : "",
(user != NULL) ? "@" : "", host, sport, "/", path,
--- 161,167 ----
if (port != DEFAULT_FTP_PORT) sprintf(sport, ":%d", port);
else sport[0] = '\0';
! r->filename = pstrcat(pool, "proxy:ftp://", (user != NULL) ? user : "",
(password != NULL) ? ":" : "",
(password != NULL) ? password : "",
(user != NULL) ? "@" : "", host, sport, "/", path,
***************
*** 333,342 ****
{
char *host, *path, *p, *user, *password, *parms;
const char *err;
! int port, userlen, passlen, i, len, sock, dsock, rc, nocache;
int csd = 0;
struct sockaddr_in server;
struct hdr_entry *hdr;
array_header *resp_hdrs;
BUFF *f, *cache;
BUFF *data = NULL;
--- 334,345 ----
{
char *host, *path, *p, *user, *password, *parms;
const char *err;
! int port, userlen, i, len, sock, dsock, rc, nocache;
! int passlen = 0;
int csd = 0;
struct sockaddr_in server;
struct hdr_entry *hdr;
+ struct in_addr destaddr;
array_header *resp_hdrs;
BUFF *f, *cache;
BUFF *data = NULL;
***************
*** 344,349 ****
--- 347,358 ----
const int one=1;
const long int zero=0L;
+ void *sconf = r->server->module_config;
+ proxy_server_conf *conf =
+ (proxy_server_conf *)get_module_config(sconf, &proxy_module);
+ struct noproxy_entry *npent=(struct noproxy_entry
*)conf->noproxies->elts;
+ struct nocache_entry *ncent=(struct nocache_entry
*)conf->nocaches->elts;
+
/* stuff for PASV mode */
unsigned int presult, h0, h1, h2, h3, p0, p1;
unsigned int paddr;
***************
*** 353,376 ****
char pasv[64];
char *pstr;
- /* This appears to fix a bug(?) that generates an "Address family not
- supported by protocol" error in proxy_doconnect() later (along with
- making sure server.sin_family = AF_INET - cdm) */
- memset(&server, 0, sizeof(struct sockaddr_in));
-
/* we only support GET and HEAD */
if (r->method_number != M_GET) return NOT_IMPLEMENTED;
- host = pstrdup(r->pool, url+6);
/* We break the URL into host, port, path-search */
port = DEFAULT_FTP_PORT;
path = strchr(host, '/');
! if (path == NULL) path = "";
! else *(path++) = '\0';
user = password = NULL;
nocache = 0;
- passlen=0; /* not actually needed, but it shuts the compiler up */
p = strchr(host, '@');
if (p != NULL)
{
--- 362,383 ----
char pasv[64];
char *pstr;
/* we only support GET and HEAD */
+
if (r->method_number != M_GET) return NOT_IMPLEMENTED;
/* We break the URL into host, port, path-search */
+
+ host = pstrdup(pool, url + 6);
port = DEFAULT_FTP_PORT;
path = strchr(host, '/');
! if (path == NULL)
! path = "";
! else
! *(path++) = '\0';
user = password = NULL;
nocache = 0;
p = strchr(host, '@');
if (p != NULL)
{
***************
*** 400,406 ****
if (p != NULL)
{
*(p++) = '\0';
! port = atoi(p);
}
Explain2("FTP: connect to %s:%d",host,port);
--- 407,423 ----
if (p != NULL)
{
*(p++) = '\0';
! if (isdigit(*p))
! port = atoi(p);
! }
!
! /* check if ProxyBlock directive on this host */
! inet_aton(host, &destaddr);
! for (i=0; i < conf->noproxies->nelts; i++)
! {
! if ((npent[i].name != NULL && strstr(host, npent[i].name) != NULL)
! || destaddr.s_addr == npent[i].addr.s_addr || npent[i].name[0] ==
'*')
! return proxyerror(r, "Connect to remote machine blocked");
}
Explain2("FTP: connect to %s:%d",host,port);
***************
*** 408,413 ****
--- 425,431 ----
parms = strchr(path, ';');
if (parms != NULL) *(parms++) = '\0';
+ memset(&server, 0, sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(port);
err = proxy_host2addr(host, &server.sin_addr);
***************
*** 752,758 ****
--- 770,786 ----
proxy_add_header(resp_hdrs, "Content-Type", "text/plain", HDR_REP);
}
}
+
+ /* check if NoCache directive on this host */
+ for (i=0; i < conf->nocaches->nelts; i++)
+ {
+ if ((ncent[i].name != NULL && strstr(host, ncent[i].name) != NULL)
+ || destaddr.s_addr == ncent[i].addr.s_addr || ncent[i].name[0] ==
'*')
+ nocache = 1;
+ }
+
i = proxy_cache_update(c, resp_hdrs, "FTP", nocache);
+
if (i != DECLINED)
{
pclosef(pool, dsock);
1.11 +14 -3 apache/src/modules/proxy/proxy_http.c
Index: proxy_http.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_http.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -C3 -r1.10 -r1.11
*** proxy_http.c 1997/01/01 18:20:02 1.10
--- proxy_http.c 1997/01/05 09:06:07 1.11
***************
*** 147,152 ****
--- 147,153 ----
array_header *reqhdrs_arr, *resp_hdrs;
table_entry *reqhdrs;
struct sockaddr_in server;
+ struct in_addr destaddr;
BUFF *f, *cache;
struct hdr_entry *hdr;
char buffer[HUGE_STRING_LEN], inprotocol[9], outprotocol[9];
***************
*** 158,164 ****
void *sconf = r->server->module_config;
proxy_server_conf *conf =
(proxy_server_conf *)get_module_config(sconf, &proxy_module);
! struct nocache_entry *ent=(struct nocache_entry *)conf->nocaches->elts;
int nocache = 0;
memset(&server, '\0', sizeof(server));
--- 159,166 ----
void *sconf = r->server->module_config;
proxy_server_conf *conf =
(proxy_server_conf *)get_module_config(sconf, &proxy_module);
! struct noproxy_entry *npent=(struct noproxy_entry
*)conf->noproxies->elts;
! struct nocache_entry *ncent=(struct nocache_entry
*)conf->nocaches->elts;
int nocache = 0;
memset(&server, '\0', sizeof(server));
***************
*** 193,198 ****
--- 195,209 ----
}
}
+ /* check if ProxyBlock directive on this host */
+ inet_aton(desthost, &destaddr);
+ for (i=0; i < conf->noproxies->nelts; i++)
+ {
+ if ((npent[i].name != NULL && strstr(desthost, npent[i].name) !=
NULL)
+ || destaddr.s_addr == npent[i].addr.s_addr || npent[i].name[0] == '*')
+ return proxyerror(r, "Connect to remote machine blocked");
+ }
+
if (proxyhost != NULL)
{
url = r->uri; /* restore original URL */
***************
*** 323,330 ****
/* check if NoCache directive on this host */
for (i=0; i < conf->nocaches->nelts; i++)
{
! if ((ent[i].name != NULL && strstr(desthost, ent[i].name) != NULL)
! || ent[i].name[0] == '*')
nocache = 1;
}
--- 334,341 ----
/* check if NoCache directive on this host */
for (i=0; i < conf->nocaches->nelts; i++)
{
! if ((ncent[i].name != NULL && strstr(desthost, ncent[i].name) !=
NULL)
! || destaddr.s_addr == ncent[i].addr.s_addr || ncent[i].name[0] == '*')
nocache = 1;
}