1 const char filters_rcs[] = "$Id: filters.c,v 1.1 2001/05/13 21:57:06 administrator Exp $";
2 /*********************************************************************
4 * File : $Source: /home/administrator/cvs/ijb/filters.c,v $
6 * Purpose : Declares functions to parse/crunch headers and pages.
7 * Functions declared include:
8 * `acl_addr', `add_stats', `block_acl', `block_imageurl',
9 * `block_url', `cookie_url', `domaincmp', `dsplit',
10 * `filter_popups', `forward_url',
11 * `ij_untrusted_url', `intercept_url', `re_process_buffer',
12 * `show_proxy_args', and `trust_url'
14 * Copyright : Written by and Copyright (C) 2001 the SourceForge
15 * IJBSWA team. http://ijbswa.sourceforge.net
17 * Based on the Internet Junkbuster originally written
18 * by and Copyright (C) 1997 Anonymous Coders and
19 * Junkbusters Corporation. http://www.junkbusters.com
21 * This program is free software; you can redistribute it
22 * and/or modify it under the terms of the GNU General
23 * Public License as published by the Free Software
24 * Foundation; either version 2 of the License, or (at
25 * your option) any later version.
27 * This program is distributed in the hope that it will
28 * be useful, but WITHOUT ANY WARRANTY; without even the
29 * implied warranty of MERCHANTABILITY or FITNESS FOR A
30 * PARTICULAR PURPOSE. See the GNU General Public
31 * License for more details.
33 * The GNU General Public License should be included with
34 * this file. If not, you can view it at
35 * http://www.gnu.org/copyleft/gpl.html
36 * or write to the Free Software Foundation, Inc., 59
37 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
42 *********************************************************************/
48 #include <sys/types.h>
55 #include <netinet/in.h>
68 #include "jbsockets.h"
70 #include "jbsockets.h"
76 const char filters_h_rcs[] = FILTERS_H_VERSION;
78 /* Fix a problem with Solaris. There should be no effect on other
80 * Solaris's isspace() is a macro which uses it's argument directly
81 * as an array index. Therefore we need to make sure that high-bit
82 * characters generate +ve values, and ideally we also want to make
83 * the argument match the declared parameter type of "int".
85 #define ijb_isdigit(__X) isdigit((int)(unsigned char)(__X))
88 static const char CBLOCK[] =
90 "HTTP/1.0 403 Request for blocked URL\n"
91 #else /* ifndef AMIGA */
92 "HTTP/1.0 202 Request for blocked URL\n"
93 #endif /* ndef AMIGA */
95 "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\n"
96 "Expires: Thu Jul 31, 1997 07:42:22 pm GMT\n"
97 "Content-Type: text/html\n\n"
100 "<title>Internet Junkbuster: Request for blocked URL</title>\n"
106 "<p align=center>Your request for <b>%s%s</b><br>\n"
107 "was blocked because it matches the following pattern "
108 "in the blockfile: <b>%s</b>\n</p>"
110 "<p align=center><a href=\"http://" FORCE_PREFIX
111 "%s%s\">Go there anyway.</a></p>"
112 #endif /* def FORCE_LOAD */
117 static const char CTRUST[] =
119 "HTTP/1.0 403 Request for untrusted URL\n"
120 #else /* ifndef AMIGA */
121 "HTTP/1.0 202 Request for untrusted URL\n"
122 #endif /* ndef AMIGA */
124 "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\n"
125 "Expires: Thu Jul 31, 1997 07:42:22 pm GMT\n"
126 "Content-Type: text/html\n\n"
129 "<title>Internet Junkbuster: Request for untrusted URL</title>\n"
133 "<a href=http://internet.junkbuster.com/ij-untrusted-url?%s+%s+%s>"
139 #endif /* def TRUST_FILES */
143 /*********************************************************************
145 * Function : block_acl
147 * Description : Block this request?
148 * Decide yes or no based on ACL file.
151 * 1 : src = Address the browser/user agent is requesting.
152 * 2 : dst = The proxy or gateway address this is going to.
153 * 3 : csp = Current client state (buffers, headers, etc...)
155 * Returns : 0 = FALSE (don't block) and 1 = TRUE (do block)
157 *********************************************************************/
158 int block_acl(struct access_control_addr *src, struct access_control_addr *dst, struct client_state *csp)
160 struct file_list *fl;
161 struct access_control_list *a, *acl;
162 struct access_control_addr s[1], d[1];
164 /* if not using an access control list, then permit the connection */
165 if (((fl = csp->alist) == NULL) || ((acl = fl->f) == NULL))
170 /* search the list */
171 for (a = acl->next ; a ; a = a->next)
176 s->addr &= a->src->mask;
177 d->addr &= a->dst->mask;
179 if ((s->addr == a->src->addr)
180 && (d->addr == a->dst->addr)
181 && ((s->port == a->src->port)
183 || (a->src->port == 0))
184 && ((d->port == a->dst->port)
186 || (a->dst->port == 0)))
188 if (a->action == ACL_PERMIT)
204 /*********************************************************************
206 * Function : acl_addr
208 * Description : Called from `load_aclfile'. FIXME: I can't say more.
211 * 1 : aspec = (what?)
214 * Returns : 0 => Ok, everything else is an error.
216 *********************************************************************/
217 int acl_addr(char *aspec, struct access_control_addr *aca)
219 int i, masklength, port;
225 if ((p = strchr(aspec, '/')))
229 if (ijb_isdigit(*p) == 0)
233 masklength = atoi(p);
236 if ((masklength < 0) || (masklength > 32))
241 if ((p = strchr(aspec, ':')))
245 if (ijb_isdigit(*p) == 0)
254 aca->addr = ntohl(resolve_hostname_to_ip(aspec));
258 log_error(LOG_LEVEL_ERROR, "can't resolve address for %s", aspec);
262 /* build the netmask */
264 for (i=1; i <= masklength ; i++)
266 aca->mask |= (1 << (32 - i));
269 /* now mask off the host portion of the ip address
270 * (i.e. save on the network portion of the address).
272 aca->addr = aca->addr & aca->mask;
277 #endif /* def ACL_FILES */
280 /*********************************************************************
282 * Function : block_url
284 * Description : Called from `chat'. Check to see if we need to block this.
287 * 1 : http = http_request request to "check" for blocked
288 * 2 : csp = Current client state (buffers, headers, etc...)
290 * Returns : NULL => unblocked, else string to HTML block description.
292 *********************************************************************/
293 char *block_url(struct http_request *http, struct client_state *csp)
295 struct file_list *fl;
296 struct block_spec *b;
297 struct url_spec url[1];
301 if (((fl = csp->blist) == NULL) || ((b = fl->f) == NULL))
306 *url = dsplit(http->host);
308 /* if splitting the domain fails, punt */
309 if (url->dbuf == NULL) return(NULL);
311 for (b = b->next; b ; b = b->next)
313 if ((b->url->port == 0) || (b->url->port == http->port))
315 if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
317 if ((b->url->path == NULL) ||
319 (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
321 (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
328 if (b->reject == 0) return(NULL);
331 n += strlen(http->hostport);
332 n += strlen(http->path);
333 n += strlen(b->url->spec);
335 n += strlen(http->hostport);
336 n += strlen(http->path);
337 #endif /* def FORCE_LOAD */
339 p = (char *)malloc(n);
342 sprintf(p, CBLOCK, http->hostport, http->path, b->url->spec, http->hostport, http->path);
344 sprintf(p, CBLOCK, http->hostport, http->path, b->url->spec);
345 #endif /* def FORCE_LOAD */
359 #if defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
360 /*********************************************************************
362 * Function : block_imageurl
364 * Description : Given a URL which is blocked, decide whether to
365 * send the "blocked" image or HTML.
368 * 1 : http = URL to check.
369 * 2 : csp = Current client state (buffers, headers, etc...)
371 * Returns : True (nonzero) if URL is in image list, false (0)
374 *********************************************************************/
375 int block_imageurl(struct http_request *http, struct client_state *csp)
377 #ifdef DETECT_MSIE_IMAGES
378 if ((csp->accept_types
379 & (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_IMAGE|ACCEPT_TYPE_MSIE_HTML))
380 == (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_IMAGE))
384 else if ((csp->accept_types
385 & (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_IMAGE|ACCEPT_TYPE_MSIE_HTML))
386 == (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_HTML))
392 #if defined(USE_IMAGE_LIST)
393 return block_imageurl_using_imagelist(http, csp);
395 /* Don't know - assume HTML */
399 #endif /* defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
402 #ifdef USE_IMAGE_LIST
403 /*********************************************************************
405 * Function : block_imageurl
407 * Description : Test if a URL is in the imagelist.
410 * 1 : http = URL to check.
411 * 2 : csp = Current client state (buffers, headers, etc...)
413 * Returns : True (nonzero) if URL is in image list, false (0)
416 *********************************************************************/
417 int block_imageurl_using_imagelist(struct http_request *http, struct client_state *csp)
419 struct file_list *fl;
420 struct block_spec *b;
421 struct url_spec url[1];
423 if (((fl = csp->ilist) == NULL) || ((b = fl->f) == NULL))
428 *url = dsplit(http->host);
430 /* if splitting the domain fails, punt */
431 if (url->dbuf == NULL) return(0);
433 for (b = b->next; b ; b = b->next)
436 if ((b->url->port == 0) || (b->url->port == http->port))
438 /* port matches, check domain */
439 if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
441 /* domain matches, check path */
442 if ((b->url->path == NULL) ||
444 (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
446 (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
454 if (b->reject == 0) return(0);
466 #endif /* def USE_IMAGE_LIST */
470 /*********************************************************************
472 * Function : re_process_buffer
474 * Description : Apply all jobs from the joblist (aka. Perl regexp's) to
475 * the text buffer that's been accumulated in csp->iob->buf.
476 * Then, write the modified buffer out to the client
477 * (Maybe this should happen from jcc.c via flush_socket
478 * for better readability).
481 * 1 : csp = Current client state (buffers, headers, etc...)
485 *********************************************************************/
486 void re_process_buffer(struct client_state *csp)
489 int size = csp->iob->eod - csp->iob->cur;
490 char *old=csp->iob->cur, *new = NULL;
491 pcrs_job *job, *joblist;
493 struct file_list *fl;
494 struct re_filterfile_spec *b;
496 /* Sanity first ;-) */
497 if (size <= 0) return;
499 if ( ( NULL == (fl = csp->rlist) ) || ( NULL == (b = fl->f) ) )
501 log_error(LOG_LEVEL_ERROR, "Unable to get current state of regexp filtering.");
505 joblist = b->joblist;
508 log_error(LOG_LEVEL_REF, "re_filtering %s%s (size %d) ...",
509 csp->http->hostport, csp->http->path, size);
511 /* Apply all jobs from the joblist */
512 for (job = joblist; NULL != job; job = job->next)
514 hits += pcrs_exec_substitution(job, old, size, &new, &size);
515 if (old != csp->iob->cur) free(old);
519 log_error(LOG_LEVEL_REF, " produced %d hits (new size %d).", hits, size);
521 if (write_socket(csp->cfd, old, size) != size)
523 log_error(LOG_LEVEL_ERROR, "write to client failed.");
526 /* fwiw, reset the iob */
532 #endif /* def PCRS */
536 /*********************************************************************
538 * Function : trust_url
540 * Description : Should we "trust" this URL? See "trustfile" line in config.
543 * 1 : http = http_request request for requested URL
544 * 2 : csp = Current client state (buffers, headers, etc...)
546 * Returns : NULL => trusted, else string to HTML "untrusted" description.
548 *********************************************************************/
549 char *trust_url(struct http_request *http, struct client_state *csp)
551 struct file_list *fl;
552 struct block_spec *b;
553 struct url_spec url[1], **tl, *t;
555 char *hostport, *path, *refer;
556 struct http_request rhttp[1];
559 if (((fl = csp->tlist) == NULL) || ((b = fl->f) == NULL))
564 *url = dsplit(http->host);
566 /* if splitting the domain fails, punt */
567 if (url->dbuf == NULL) return(NULL);
569 memset(rhttp, '\0', sizeof(*rhttp));
571 for (b = b->next; b ; b = b->next)
573 if ((b->url->port == 0) || (b->url->port == http->port))
575 if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
577 if ((b->url->path == NULL) ||
579 (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
581 (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
588 if (b->reject == 0) return(NULL);
590 hostport = url_encode(http->hostport);
591 path = url_encode(http->path);
595 refer = url_encode(csp->referrer);
599 refer = url_encode("undefined");
603 n += strlen(hostport);
607 p = (char *)malloc(n);
609 sprintf(p, CTRUST, hostport, path, refer);
624 if ((csp->referrer == NULL)|| (strlen(csp->referrer) <= 9))
626 /* no referrer was supplied */
627 goto trust_url_not_trusted;
630 /* forge a URL from the referrer so we can use
631 * convert_url() to parse it into its components.
635 p = strsav(p, "GET ");
636 p = strsav(p, csp->referrer + 9); /* skip over "Referer: " */
637 p = strsav(p, " HTTP/1.0");
639 parse_http_request(p, rhttp, csp);
641 if (rhttp->cmd == NULL)
644 goto trust_url_not_trusted;
649 *url = dsplit(rhttp->host);
651 /* if splitting the domain fails, punt */
652 if (url->dbuf == NULL) goto trust_url_not_trusted;
654 for (tl = trust_list; (t = *tl) ; tl++)
656 if ((t->port == 0) || (t->port == rhttp->port))
658 if ((t->domain[0] == '\0') || domaincmp(t, url) == 0)
660 if ((t->path == NULL) ||
662 (regexec(t->preg, rhttp->path, 0, NULL, 0) == 0)
664 (strncmp(t->path, rhttp->path, t->pathlen) == 0)
668 /* if the URL's referrer is from a trusted referrer, then
669 * add the target spec to the trustfile as an unblocked
670 * domain and return NULL (which means it's OK).
678 if ((fp = fopen(trustfile, "a")))
683 h = strsav(h, http->hostport);
689 /* since this path points into a user's home space
690 * be sure to include this spec in the trustfile.
692 if ((p = strchr(p, '/')))
695 h = strsav(h, http->path);
700 free_http_request(rhttp);
702 fprintf(fp, "%s\n", h);
712 trust_url_not_trusted:
713 free_http_request(rhttp);
715 hostport = url_encode(http->hostport);
716 path = url_encode(http->path);
720 refer = url_encode(csp->referrer);
724 refer = url_encode("undefined");
728 n += strlen(hostport);
732 p = (char *)malloc(n);
733 sprintf(p, CTRUST, hostport, path, refer);
742 #endif /* def TRUST_FILES */
745 /*********************************************************************
747 * Function : intercept_url
749 * Description : checks the URL `basename' against a list of URLs to
750 * snarf. If it matches, it calls the associated function
751 * which returns an HTML page to send back to the client.
752 * Right now, we snarf:
753 * "show-proxy-args", and
754 * "ij-untrusted-url" (optional w/TRUST_FILES)
757 * 1 : http = http_request request, check `basename's of blocklist
758 * 2 : csp = Current client state (buffers, headers, etc...)
760 * Returns : NULL for no recognized URLs, or an HTML description page.
762 *********************************************************************/
763 char *intercept_url(struct http_request *http, struct client_state *csp)
766 const struct interceptors *v;
768 basename = strrchr(http->path, '/');
770 if (basename == NULL) return(NULL);
772 basename ++; /* first char past the last slash */
776 for (v = intercept_patterns; v->str; v++)
778 if (strncmp(basename, v->str, v->len) == 0)
780 return((v->interceptor)(http, csp));
790 /*********************************************************************
792 * Function : cookie_url
794 * Description : Accept this cookie, or no? See "cookiefile" setting.
797 * 1 : http = http_request request for blocked URLs
798 * 2 : csp = Current client state (buffers, headers, etc...)
800 * Returns : NULL => accept, cookie_spec pointer to crunch.
802 *********************************************************************/
803 struct cookie_spec *cookie_url(struct http_request *http, struct client_state *csp)
805 struct file_list *fl;
806 struct cookie_spec *b;
807 struct url_spec url[1];
809 if (((fl = csp->clist) == NULL) || ((b = fl->f) == NULL))
814 *url = dsplit(http->host);
816 /* if splitting the domain fails, punt */
817 if (url->dbuf == NULL) return(NULL);
819 for (b = b->next; NULL != b; b = b->next)
821 if ((b->url->port == 0) || (b->url->port == http->port))
823 if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
825 if ((b->url->path == NULL) ||
827 (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
829 (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
848 /*********************************************************************
850 * Function : forward_url
852 * Description : Should we forward this to another proxy?
855 * 1 : http = http_request request for current URL
856 * 2 : csp = Current client state (buffers, headers, etc...)
858 * Returns : Return gw_default for no forward match,
859 * else a gateway pointer to a specific forwarding proxy.
861 *********************************************************************/
862 const struct gateway *forward_url(struct http_request *http, struct client_state *csp)
864 struct file_list *fl;
865 struct forward_spec *b;
866 struct url_spec url[1];
868 if (((fl = csp->flist) == NULL) || ((b = fl->f) == NULL))
873 *url = dsplit(http->host);
875 /* if splitting the domain fails, punt */
876 if (url->dbuf == NULL) return(gw_default);
878 for (b = b->next; b ; b = b->next)
880 if ((b->url->port == 0) || (b->url->port == http->port))
882 if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
884 if ((b->url->path == NULL) ||
886 (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
888 (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
907 /*********************************************************************
911 * Description : Takes a domain and returns a pointer to a url_spec
912 * structure populated with dbuf, dcnt and dvec. The
913 * other fields in the structure that is returned are zero.
916 * 1 : domain = a URL address
918 * Returns : url_spec structure populated with dbuf, dcnt and dvec.
920 *********************************************************************/
921 struct url_spec dsplit(char *domain)
923 struct url_spec ret[1];
928 memset(ret, '\0', sizeof(*ret));
930 if ((p = strrchr(domain, '.')))
938 ret->dbuf = strdup(domain);
940 /* map to lower case */
941 for (p = ret->dbuf; *p ; p++) *p = tolower(*p);
943 /* split the domain name into components */
944 ret->dcnt = ssplit(ret->dbuf, ".", v, SZ(v), 1, 1);
948 memset(ret, '\0', sizeof(ret));
952 /* save a copy of the pointers in dvec */
953 size = ret->dcnt * sizeof(*ret->dvec);
955 if ((ret->dvec = (char **)malloc(size)))
957 memcpy(ret->dvec, v, size);
965 /*********************************************************************
967 * Function : domaincmp
969 * Description : Compare domain names.
970 * domaincmp("a.b.c" , "a.b.c") => 0 (MATCH)
971 * domaincmp("a*.b.c", "a.b.c") => 0 (MATCH)
972 * domaincmp("b.c" , "a.b.c") => 0 (MATCH)
973 * domaincmp("" , "a.b.c") => 0 (MATCH)
976 * 1 : pattern = a domain that may contain a '*' as a wildcard.
977 * 2 : fqdn = domain name against which the patterns are compared.
979 * Returns : 0 => domains are equivalent, else no match.
981 *********************************************************************/
982 int domaincmp(struct url_spec *pattern, struct url_spec *fqdn)
984 char **pv, **fv; /* vectors */
985 int pn, fn; /* counters */
986 char *p, *f; /* chars */
994 while ((pn > 0) && (fn > 0))
999 while (*p && *f && (*p == tolower(*f)))
1004 if ((*p != tolower(*f)) && (*p != '*')) return(1);
1007 if (pn > 0) return(1);
1014 /* intercept functions */
1016 /*********************************************************************
1018 * Function : show_proxy_args
1020 * Description : This "crunch"es "http:/any.thing/show-proxy-args" and
1021 * returns a web page describing the current status of IJB.
1024 * 1 : http = ignored
1025 * 2 : csp = Current client state (buffers, headers, etc...)
1027 * Returns : A string that contains the current status of IJB.
1029 *********************************************************************/
1030 char *show_proxy_args(struct http_request *http, struct client_state *csp)
1034 #ifdef SPLIT_PROXY_ARGS
1038 const char * filename = NULL;
1039 const char * file_description = NULL;
1040 char * query_string = strrchr(http->path, '?');
1041 char which_file = '\0';
1044 if (query_string != NULL)
1046 /* first char past the last '?' (maybe '\0')*/
1047 which_file = query_string[1];
1054 filename = csp->blist->filename;
1055 file_description = "Block List";
1061 filename = csp->clist->filename;
1062 file_description = "Cookie List";
1068 filename = csp->flist->filename;
1069 file_description = "Forward List";
1077 filename = csp->alist->filename;
1078 file_description = "Access Control List";
1081 #endif /* def ACL_FILES */
1083 #ifdef USE_IMAGE_LIST
1087 filename = csp->ilist->filename;
1088 file_description = "Image List";
1091 #endif /* def USE_IMAGE_LIST */
1097 filename = csp->plist->filename;
1098 file_description = "Popup list";
1101 #endif /* def KILLPOPUPS */
1107 filename = csp->rlist->filename;
1108 file_description = "RE Filter List";
1111 #endif /* def PCRS */
1117 filename = csp->tlist->filename;
1118 file_description = "Trust List";
1121 #endif /* def TRUST_FILES */
1126 /* Display specified file */
1127 /* FIXME: Add HTTP headers so this isn't cached */
1130 "Server: IJ/" VERSION "\n"
1131 "Content-type: text/html\n"
1132 "Pragma: no-cache\n"
1133 "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\n"
1134 "Expires: Thu Jul 31, 1997 07:42:22 pm GMT\n"
1139 "<title>Internet Junkbuster Proxy Status - ");
1140 s = strsav(s, file_description);
1144 "<body bgcolor=\"#f8f8f0\" link=\"#000078\" alink=\"#ff0022\" vlink=\"#787878\">\n"
1146 "<h1>" BANNER "\n");
1147 s = strsav(s, file_description);
1150 "<p><a href=\"show-proxy-args\">Back to proxy status</a></p>\n"
1152 s = strsav(s, file_description);
1155 "Contents of file "<code>");
1156 p = html_encode(filename);
1160 "</code>":<br>\n"
1164 if ((fp = fopen(filename, "r")) == NULL)
1166 s = strsav(s, "</pre><h1>ERROR OPENING FILE!</h1><pre>");
1170 while (fgets(buf, sizeof(buf), fp))
1172 p = html_encode(buf);
1177 s = strsav(s, "<br>");
1186 "<p><a href=\"show-proxy-args\">Back to proxy status</a></p>\n"
1188 "<small><small><p>\n"
1189 "Code and documentation of the " BANNER " Proxy"
1190 "<sup><small>TM</small></sup>\n"
1191 "<a href=\"http://www.junkbusters.com/ht/en/legal.html#copy\">\n" "Copyright</a>© 1997 Junkbusters Corporation\n"
1192 "<a href=\"http://www.junkbusters.com/ht/en/legal.html#marks\"><sup><small>TM</small></sup></a><br>\n"
1193 "Copying and distribution permitted under the"
1194 "<a href=\"http://www.gnu.org/copyleft/gpl.html\">\n"
1195 "<small>GNU</small></a> "
1196 "General Public License.\n"
1198 "<address><kbd>webmaster@junkbusters.com</kbd></address>"
1200 "</body></html>\n");
1203 #endif /* def SPLIT_PROXY_ARGS */
1205 s = strsav(s, proxy_args->header);
1206 s = strsav(s, proxy_args->invocation);
1209 #endif /* def STATISTICS */
1210 s = strsav(s, proxy_args->gateways);
1212 #ifdef SPLIT_PROXY_ARGS
1214 "<h2>The following files are in use:</h2>\n"
1215 "<p>(Click a filename to view it)</p>\n"
1220 s = strsav(s, "<li>Block List: <a href=\"show-proxy-args?block\"><code>");
1221 s = strsav(s, csp->blist->filename);
1222 s = strsav(s, "</code></a></li>\n");
1227 s = strsav(s, "<li>Cookie List: <a href=\"show-proxy-args?cookie\"><code>");
1228 s = strsav(s, csp->clist->filename);
1229 s = strsav(s, "</code></a></li>\n");
1234 s = strsav(s, "<li>Forward List: <a href=\"show-proxy-args?forward\"><code>");
1235 s = strsav(s, csp->flist->filename);
1236 s = strsav(s, "</code></a></li>\n");
1242 s = strsav(s, "<li>Access Control List: <a href=\"show-proxy-args?acl\"><code>");
1243 s = strsav(s, csp->alist->filename);
1244 s = strsav(s, "</code></a></li>\n");
1246 #endif /* def ACL_FILES */
1248 #ifdef USE_IMAGE_LIST
1251 s = strsav(s, "<li>Image List: <a href=\"show-proxy-args?image\"><code>");
1252 s = strsav(s, csp->ilist->filename);
1253 s = strsav(s, "</code></a></li>\n");
1255 #endif /* def USE_IMAGE_LIST */
1260 s = strsav(s, "<li>Popup List: <a href=\"show-proxy-args?popup\"><code>");
1261 s = strsav(s, csp->plist->filename);
1262 s = strsav(s, "</code></a></li>\n");
1264 #endif /* def KILLPOPUPS */
1269 s = strsav(s, "<li>RE Filter List: <a href=\"show-proxy-args?re\"><code>");
1270 s = strsav(s, csp->rlist->filename);
1271 s = strsav(s, "</code></a></li>\n");
1273 #endif /* def PCRS */
1278 s = strsav(s, "<li>Trust List: <a href=\"show-proxy-args?trust\"><code>");
1279 s = strsav(s, csp->tlist->filename);
1280 s = strsav(s, "</code></a></li>\n");
1282 #endif /* def TRUST_FILES */
1284 s = strsav(s, "</ul>");
1286 #else /* ifndef SPLIT_PROXY_ARGS */
1289 s = strsav(s, csp->blist->proxy_args);
1294 s = strsav(s, csp->clist->proxy_args);
1299 s = strsav(s, csp->flist->proxy_args);
1305 s = strsav(s, csp->alist->proxy_args);
1307 #endif /* def ACL_FILES */
1309 #ifdef USE_IMAGE_LIST
1312 s = strsav(s, csp->ilist->proxy_args);
1314 #endif /* def USE_IMAGE_LIST */
1319 s = strsav(s, csp->plist->proxy_args);
1321 #endif /* def KILLPOPUPS */
1326 s = strsav(s, csp->rlist->proxy_args);
1328 #endif /* def PCRS */
1333 s = strsav(s, csp->tlist->proxy_args);
1335 #endif /* def TRUST_FILES */
1337 #endif /* ndef SPLIT_PROXY_ARGS */
1339 s = strsav(s, proxy_args->trailer);
1347 /*********************************************************************
1349 * Function : ij_untrusted_url
1351 * Description : This "crunch"es "http:/any.thing/ij-untrusted-url" and
1352 * returns a web page describing why it was untrusted.
1355 * 1 : http = http_request request for crunched URL
1356 * 2 : csp = Current client state (buffers, headers, etc...)
1358 * Returns : A string that contains why this was untrusted.
1360 *********************************************************************/
1361 char *ij_untrusted_url(struct http_request *http, struct client_state *csp)
1364 char *hostport, *path, *refer, *p, *v[9];
1366 struct url_spec **tl, *t;
1369 static const char format[] =
1370 "HTTP/1.0 200 OK\r\n"
1371 "Pragma: no-cache\n"
1372 "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\n"
1373 "Expires: Thu Jul 31, 1997 07:42:22 pm GMT\n"
1374 "Content-Type: text/html\n\n"
1377 "<title>Internet Junkbuster: Request for untrusted URL</title>\n"
1383 "The " BANNER " Proxy "
1384 "<A href=\"" HOME_PAGE_URL "\">"
1385 "(" HOME_PAGE_URL ") </A>"
1386 "intercepted the request for %s%s\n"
1387 "because the URL is not trusted.\n"
1390 if ((n = ssplit(http->path, "?+", v, SZ(v), 0, 0)) == 4)
1392 hostport = url_decode(v[1]);
1393 path = url_decode(v[2]);
1394 refer = url_decode(v[3]);
1398 hostport = strdup("undefined_host");
1399 path = strdup("/undefined_path");
1400 refer = strdup("undefined");
1404 n += strlen(hostport);
1407 if ((p = (char *)malloc(n)))
1409 sprintf(p, format, hostport, path);
1412 strsav(p, "The referrer in this request was <strong>");
1414 strsav(p, "</strong><br>\n");
1420 p = strsav(p, "<h3>The following referrers are trusted</h3>\n");
1422 for (tl = trust_list; (t = *tl) ; tl++)
1424 sprintf(buf, "%s<br>\n", t->spec);
1428 if (trust_info->next)
1434 "You can learn more about what this means "
1435 "and what you may be able to do about it by "
1436 "reading the following documents:<br>\n"
1442 for (l = trust_info->next; l ; l = l->next)
1445 "<li> <a href=%s>%s</a><br>\n",
1450 p = strsav(p, "</ol>\n");
1453 p = strsav(p, "</body>\n" "</html>\n");
1458 #endif /* def TRUST_FILES */
1462 /*********************************************************************
1464 * Function : add_stats
1466 * Description : Statistics function of JB. Called by `show_proxy_args'.
1469 * 1 : s = string that holds the proxy args description page
1471 * Returns : A pointer to the descriptive status web page.
1473 *********************************************************************/
1474 char *add_stats(char *s)
1477 * Output details of the number of requests rejected and
1478 * accepted. This is switchable in the junkbuster config.
1479 * Does nothing if this option is not enabled.
1482 float perc_rej; /* Percentage of http requests rejected */
1484 int local_urls_read = urls_read;
1485 int local_urls_rejected = urls_rejected;
1488 * Need to alter the stats not to include the fetch of this
1491 * Can't do following thread safely! doh!
1494 * urls_rejected--; * This will be incremented subsequently *
1497 s = strsav(s,"<h2>Statistics for this " BANNER ":</h2>\n");
1499 if (local_urls_read == 0)
1502 s = strsav(s,"No activity so far!\n");
1508 perc_rej = (float)local_urls_rejected * 100.0F /
1509 (float)local_urls_read;
1512 "%d requests received, %d filtered "
1515 local_urls_rejected, perc_rej);
1517 s = strsav(s,out_str);
1522 #endif /* def STATISTICS */