1 const char filters_rcs[] = "$Id: filters.c,v 1.1.1.1 2001/05/15 13:58:52 oes Exp $";
2 /*********************************************************************
4 * File : $Source: /cvsroot/ijbswa/current/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', `url_permissions', `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.
41 * Revision 1.1.1.1 2001/05/15 13:58:52 oes
42 * Initial import of version 2.9.3 source tree
45 *********************************************************************/
51 #include <sys/types.h>
58 #include <netinet/in.h>
71 #include "jbsockets.h"
73 #include "jbsockets.h"
79 const char filters_h_rcs[] = FILTERS_H_VERSION;
81 /* Fix a problem with Solaris. There should be no effect on other
83 * Solaris's isspace() is a macro which uses it's argument directly
84 * as an array index. Therefore we need to make sure that high-bit
85 * characters generate +ve values, and ideally we also want to make
86 * the argument match the declared parameter type of "int".
88 #define ijb_isdigit(__X) isdigit((int)(unsigned char)(__X))
91 static const char CBLOCK[] =
93 "HTTP/1.0 403 Request for blocked URL\n"
94 #else /* ifndef AMIGA */
95 "HTTP/1.0 202 Request for blocked URL\n"
96 #endif /* ndef AMIGA */
98 "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\n"
99 "Expires: Thu Jul 31, 1997 07:42:22 pm GMT\n"
100 "Content-Type: text/html\n\n"
103 "<title>Internet Junkbuster: Request for blocked URL</title>\n"
109 "<p align=center>Your request for <b>%s%s</b><br>\n"
110 "was blocked because it matches the following pattern "
111 "in the blockfile: <b>%s</b>\n</p>"
113 "<p align=center><a href=\"http://" FORCE_PREFIX
114 "%s%s\">Go there anyway.</a></p>"
115 #endif /* def FORCE_LOAD */
120 static const char CTRUST[] =
122 "HTTP/1.0 403 Request for untrusted URL\n"
123 #else /* ifndef AMIGA */
124 "HTTP/1.0 202 Request for untrusted URL\n"
125 #endif /* ndef AMIGA */
127 "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\n"
128 "Expires: Thu Jul 31, 1997 07:42:22 pm GMT\n"
129 "Content-Type: text/html\n\n"
132 "<title>Internet Junkbuster: Request for untrusted URL</title>\n"
136 "<a href=http://internet.junkbuster.com/ij-untrusted-url?%s+%s+%s>"
142 #endif /* def TRUST_FILES */
146 /*********************************************************************
148 * Function : block_acl
150 * Description : Block this request?
151 * Decide yes or no based on ACL file.
154 * 1 : src = Address the browser/user agent is requesting.
155 * 2 : dst = The proxy or gateway address this is going to.
156 * 3 : csp = Current client state (buffers, headers, etc...)
158 * Returns : 0 = FALSE (don't block) and 1 = TRUE (do block)
160 *********************************************************************/
161 int block_acl(struct access_control_addr *src, struct access_control_addr *dst, struct client_state *csp)
163 struct file_list *fl;
164 struct access_control_list *a, *acl;
165 struct access_control_addr s[1], d[1];
167 /* if not using an access control list, then permit the connection */
168 if (((fl = csp->alist) == NULL) || ((acl = fl->f) == NULL))
173 /* search the list */
174 for (a = acl->next ; a ; a = a->next)
179 s->addr &= a->src->mask;
180 d->addr &= a->dst->mask;
182 if ((s->addr == a->src->addr)
183 && (d->addr == a->dst->addr)
184 && ((s->port == a->src->port)
186 || (a->src->port == 0))
187 && ((d->port == a->dst->port)
189 || (a->dst->port == 0)))
191 if (a->action == ACL_PERMIT)
207 /*********************************************************************
209 * Function : acl_addr
211 * Description : Called from `load_aclfile'. FIXME: I can't say more.
214 * 1 : aspec = (what?)
217 * Returns : 0 => Ok, everything else is an error.
219 *********************************************************************/
220 int acl_addr(char *aspec, struct access_control_addr *aca)
222 int i, masklength, port;
228 if ((p = strchr(aspec, '/')))
232 if (ijb_isdigit(*p) == 0)
236 masklength = atoi(p);
239 if ((masklength < 0) || (masklength > 32))
244 if ((p = strchr(aspec, ':')))
248 if (ijb_isdigit(*p) == 0)
257 aca->addr = ntohl(resolve_hostname_to_ip(aspec));
261 log_error(LOG_LEVEL_ERROR, "can't resolve address for %s", aspec);
265 /* build the netmask */
267 for (i=1; i <= masklength ; i++)
269 aca->mask |= (1 << (32 - i));
272 /* now mask off the host portion of the ip address
273 * (i.e. save on the network portion of the address).
275 aca->addr = aca->addr & aca->mask;
280 #endif /* def ACL_FILES */
283 /*********************************************************************
285 * Function : block_url
287 * Description : Called from `chat'. Check to see if we need to block this.
290 * 1 : http = http_request request to "check" for blocked
291 * 2 : csp = Current client state (buffers, headers, etc...)
293 * Returns : NULL => unblocked, else string to HTML block description.
295 *********************************************************************/
296 char *block_url(struct http_request *http, struct client_state *csp)
298 struct file_list *fl;
299 struct block_spec *b;
300 struct url_spec url[1];
304 if (((fl = csp->blist) == NULL) || ((b = fl->f) == NULL))
309 *url = dsplit(http->host);
311 /* if splitting the domain fails, punt */
312 if (url->dbuf == NULL) return(NULL);
314 for (b = b->next; b ; b = b->next)
316 if ((b->url->port == 0) || (b->url->port == http->port))
318 if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
320 if ((b->url->path == NULL) ||
322 (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
324 (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
331 if (b->reject == 0) return(NULL);
334 n += strlen(http->hostport);
335 n += strlen(http->path);
336 n += strlen(b->url->spec);
338 n += strlen(http->hostport);
339 n += strlen(http->path);
340 #endif /* def FORCE_LOAD */
342 p = (char *)malloc(n);
345 sprintf(p, CBLOCK, http->hostport, http->path, b->url->spec, http->hostport, http->path);
347 sprintf(p, CBLOCK, http->hostport, http->path, b->url->spec);
348 #endif /* def FORCE_LOAD */
362 #if defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
363 /*********************************************************************
365 * Function : block_imageurl
367 * Description : Given a URL which is blocked, decide whether to
368 * send the "blocked" image or HTML.
371 * 1 : http = URL to check.
372 * 2 : csp = Current client state (buffers, headers, etc...)
374 * Returns : True (nonzero) if URL is in image list, false (0)
377 *********************************************************************/
378 int block_imageurl(struct http_request *http, struct client_state *csp)
380 #ifdef DETECT_MSIE_IMAGES
381 if ((csp->accept_types
382 & (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_IMAGE|ACCEPT_TYPE_MSIE_HTML))
383 == (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_IMAGE))
387 else if ((csp->accept_types
388 & (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_IMAGE|ACCEPT_TYPE_MSIE_HTML))
389 == (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_HTML))
395 #if defined(USE_IMAGE_LIST)
396 return block_imageurl_using_imagelist(http, csp);
398 /* Don't know - assume HTML */
402 #endif /* defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
405 #ifdef USE_IMAGE_LIST
406 /*********************************************************************
408 * Function : block_imageurl
410 * Description : Test if a URL is in the imagelist.
413 * 1 : http = URL to check.
414 * 2 : csp = Current client state (buffers, headers, etc...)
416 * Returns : True (nonzero) if URL is in image list, false (0)
419 *********************************************************************/
420 int block_imageurl_using_imagelist(struct http_request *http, struct client_state *csp)
422 struct file_list *fl;
423 struct block_spec *b;
424 struct url_spec url[1];
426 if (((fl = csp->ilist) == NULL) || ((b = fl->f) == NULL))
431 *url = dsplit(http->host);
433 /* if splitting the domain fails, punt */
434 if (url->dbuf == NULL) return(0);
436 for (b = b->next; b ; b = b->next)
439 if ((b->url->port == 0) || (b->url->port == http->port))
441 /* port matches, check domain */
442 if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
444 /* domain matches, check path */
445 if ((b->url->path == NULL) ||
447 (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
449 (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
457 if (b->reject == 0) return(0);
469 #endif /* def USE_IMAGE_LIST */
473 /*********************************************************************
475 * Function : re_process_buffer
477 * Description : Apply all jobs from the joblist (aka. Perl regexp's) to
478 * the text buffer that's been accumulated in csp->iob->buf.
479 * Then, write the modified buffer out to the client
480 * (Maybe this should happen from jcc.c via flush_socket
481 * for better readability).
484 * 1 : csp = Current client state (buffers, headers, etc...)
488 *********************************************************************/
489 void re_process_buffer(struct client_state *csp)
492 int size = csp->iob->eod - csp->iob->cur;
493 char *old=csp->iob->cur, *new = NULL;
494 pcrs_job *job, *joblist;
496 struct file_list *fl;
497 struct re_filterfile_spec *b;
499 /* Sanity first ;-) */
505 if ( ( NULL == (fl = csp->rlist) ) || ( NULL == (b = fl->f) ) )
507 log_error(LOG_LEVEL_ERROR, "Unable to get current state of regexp filtering.");
511 joblist = b->joblist;
514 log_error(LOG_LEVEL_RE_FILTER, "re_filtering %s%s (size %d) ...",
515 csp->http->hostport, csp->http->path, size);
517 /* Apply all jobs from the joblist */
518 for (job = joblist; NULL != job; job = job->next)
520 hits += pcrs_exec_substitution(job, old, size, &new, &size);
521 if (old != csp->iob->cur) free(old);
525 log_error(LOG_LEVEL_RE_FILTER, " produced %d hits (new size %d).", hits, size);
527 if (write_socket(csp->cfd, old, size) != size)
529 log_error(LOG_LEVEL_ERROR, "write to client failed.");
532 /* fwiw, reset the iob */
538 #endif /* def PCRS */
542 /*********************************************************************
544 * Function : trust_url
546 * Description : Should we "trust" this URL? See "trustfile" line in config.
549 * 1 : http = http_request request for requested URL
550 * 2 : csp = Current client state (buffers, headers, etc...)
552 * Returns : NULL => trusted, else string to HTML "untrusted" description.
554 *********************************************************************/
555 char *trust_url(struct http_request *http, struct client_state *csp)
557 struct file_list *fl;
558 struct block_spec *b;
559 struct url_spec url[1], **tl, *t;
561 char *hostport, *path, *refer;
562 struct http_request rhttp[1];
565 if (((fl = csp->tlist) == NULL) || ((b = fl->f) == NULL))
570 *url = dsplit(http->host);
572 /* if splitting the domain fails, punt */
573 if (url->dbuf == NULL) return(NULL);
575 memset(rhttp, '\0', sizeof(*rhttp));
577 for (b = b->next; b ; b = b->next)
579 if ((b->url->port == 0) || (b->url->port == http->port))
581 if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
583 if ((b->url->path == NULL) ||
585 (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
587 (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
594 if (b->reject == 0) return(NULL);
596 hostport = url_encode(http->hostport);
597 path = url_encode(http->path);
601 refer = url_encode(csp->referrer);
605 refer = url_encode("undefined");
609 n += strlen(hostport);
613 p = (char *)malloc(n);
615 sprintf(p, CTRUST, hostport, path, refer);
630 if ((csp->referrer == NULL)|| (strlen(csp->referrer) <= 9))
632 /* no referrer was supplied */
633 goto trust_url_not_trusted;
636 /* forge a URL from the referrer so we can use
637 * convert_url() to parse it into its components.
641 p = strsav(p, "GET ");
642 p = strsav(p, csp->referrer + 9); /* skip over "Referer: " */
643 p = strsav(p, " HTTP/1.0");
645 parse_http_request(p, rhttp, csp);
647 if (rhttp->cmd == NULL)
650 goto trust_url_not_trusted;
655 *url = dsplit(rhttp->host);
657 /* if splitting the domain fails, punt */
658 if (url->dbuf == NULL) goto trust_url_not_trusted;
660 for (tl = trust_list; (t = *tl) ; tl++)
662 if ((t->port == 0) || (t->port == rhttp->port))
664 if ((t->domain[0] == '\0') || domaincmp(t, url) == 0)
666 if ((t->path == NULL) ||
668 (regexec(t->preg, rhttp->path, 0, NULL, 0) == 0)
670 (strncmp(t->path, rhttp->path, t->pathlen) == 0)
674 /* if the URL's referrer is from a trusted referrer, then
675 * add the target spec to the trustfile as an unblocked
676 * domain and return NULL (which means it's OK).
684 if ((fp = fopen(trustfile, "a")))
689 h = strsav(h, http->hostport);
695 /* since this path points into a user's home space
696 * be sure to include this spec in the trustfile.
698 if ((p = strchr(p, '/')))
701 h = strsav(h, http->path);
706 free_http_request(rhttp);
708 fprintf(fp, "%s\n", h);
718 trust_url_not_trusted:
719 free_http_request(rhttp);
721 hostport = url_encode(http->hostport);
722 path = url_encode(http->path);
726 refer = url_encode(csp->referrer);
730 refer = url_encode("undefined");
734 n += strlen(hostport);
738 p = (char *)malloc(n);
739 sprintf(p, CTRUST, hostport, path, refer);
748 #endif /* def TRUST_FILES */
751 /*********************************************************************
753 * Function : intercept_url
755 * Description : checks the URL `basename' against a list of URLs to
756 * snarf. If it matches, it calls the associated function
757 * which returns an HTML page to send back to the client.
758 * Right now, we snarf:
759 * "show-proxy-args", and
760 * "ij-untrusted-url" (optional w/TRUST_FILES)
763 * 1 : http = http_request request, check `basename's of blocklist
764 * 2 : csp = Current client state (buffers, headers, etc...)
766 * Returns : NULL for no recognized URLs, or an HTML description page.
768 *********************************************************************/
769 char *intercept_url(struct http_request *http, struct client_state *csp)
772 const struct interceptors *v;
774 basename = strrchr(http->path, '/');
776 if (basename == NULL) return(NULL);
778 basename ++; /* first char past the last slash */
782 for (v = intercept_patterns; v->str; v++)
784 if (strncmp(basename, v->str, v->len) == 0)
786 return((v->interceptor)(http, csp));
796 /*********************************************************************
798 * Function : url_permissions
800 * Description : Gets the permissions for this URL.
803 * 1 : http = http_request request for blocked URLs
804 * 2 : csp = Current client state (buffers, headers, etc...)
806 * Returns : permissions bitmask specifiying what this URL can do.
\r
807 * If not on list, will be default_permissions.
809 *********************************************************************/
810 int url_permissions(struct http_request *http, struct client_state *csp)
812 struct file_list *fl;
813 struct permissions_spec *b;
814 struct url_spec url[1];
816 if (((fl = csp->permissions_list) == NULL) || ((b = fl->f) == NULL))
818 return(default_permissions);
821 *url = dsplit(http->host);
823 /* if splitting the domain fails, punt */
824 if (url->dbuf == NULL)
\r
826 return(default_permissions);
\r
829 for (b = b->next; NULL != b; b = b->next)
831 if ((b->url->port == 0) || (b->url->port == http->port))
833 if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
835 if ((b->url->path == NULL) ||
837 (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
839 (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
845 return(b->permissions);
853 return(default_permissions);
858 /*********************************************************************
860 * Function : forward_url
862 * Description : Should we forward this to another proxy?
865 * 1 : http = http_request request for current URL
866 * 2 : csp = Current client state (buffers, headers, etc...)
868 * Returns : Return gw_default for no forward match,
869 * else a gateway pointer to a specific forwarding proxy.
871 *********************************************************************/
872 const struct gateway *forward_url(struct http_request *http, struct client_state *csp)
874 struct file_list *fl;
875 struct forward_spec *b;
876 struct url_spec url[1];
878 if (((fl = csp->flist) == NULL) || ((b = fl->f) == NULL))
883 *url = dsplit(http->host);
885 /* if splitting the domain fails, punt */
886 if (url->dbuf == NULL) return(gw_default);
888 for (b = b->next; b ; b = b->next)
890 if ((b->url->port == 0) || (b->url->port == http->port))
892 if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
894 if ((b->url->path == NULL) ||
896 (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
898 (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
917 /*********************************************************************
921 * Description : Takes a domain and returns a pointer to a url_spec
922 * structure populated with dbuf, dcnt and dvec. The
923 * other fields in the structure that is returned are zero.
926 * 1 : domain = a URL address
928 * Returns : url_spec structure populated with dbuf, dcnt and dvec.
930 *********************************************************************/
931 struct url_spec dsplit(char *domain)
933 struct url_spec ret[1];
938 memset(ret, '\0', sizeof(*ret));
940 if ((p = strrchr(domain, '.')))
948 ret->dbuf = strdup(domain);
950 /* map to lower case */
951 for (p = ret->dbuf; *p ; p++) *p = tolower(*p);
953 /* split the domain name into components */
954 ret->dcnt = ssplit(ret->dbuf, ".", v, SZ(v), 1, 1);
958 memset(ret, '\0', sizeof(ret));
962 /* save a copy of the pointers in dvec */
963 size = ret->dcnt * sizeof(*ret->dvec);
965 if ((ret->dvec = (char **)malloc(size)))
967 memcpy(ret->dvec, v, size);
975 /*********************************************************************
977 * Function : domaincmp
979 * Description : Compare domain names.
980 * domaincmp("a.b.c" , "a.b.c") => 0 (MATCH)
981 * domaincmp("a*.b.c", "a.b.c") => 0 (MATCH)
982 * domaincmp("b.c" , "a.b.c") => 0 (MATCH)
983 * domaincmp("" , "a.b.c") => 0 (MATCH)
986 * 1 : pattern = a domain that may contain a '*' as a wildcard.
987 * 2 : fqdn = domain name against which the patterns are compared.
989 * Returns : 0 => domains are equivalent, else no match.
991 *********************************************************************/
992 int domaincmp(struct url_spec *pattern, struct url_spec *fqdn)
994 char **pv, **fv; /* vectors */
995 int pn, fn; /* counters */
996 char *p, *f; /* chars */
1004 while ((pn > 0) && (fn > 0))
1009 while (*p && *f && (*p == tolower(*f)))
1014 if ((*p != tolower(*f)) && (*p != '*')) return(1);
1017 if (pn > 0) return(1);
1024 /* intercept functions */
1026 /*********************************************************************
1028 * Function : show_proxy_args
1030 * Description : This "crunch"es "http:/any.thing/show-proxy-args" and
1031 * returns a web page describing the current status of IJB.
1034 * 1 : http = ignored
1035 * 2 : csp = Current client state (buffers, headers, etc...)
1037 * Returns : A string that contains the current status of IJB.
1039 *********************************************************************/
1040 char *show_proxy_args(struct http_request *http, struct client_state *csp)
1044 #ifdef SPLIT_PROXY_ARGS
1048 const char * filename = NULL;
1049 const char * file_description = NULL;
1050 char * query_string = strrchr(http->path, '?');
1051 char which_file = '\0';
1054 if (query_string != NULL)
1056 /* first char past the last '?' (maybe '\0')*/
1057 which_file = query_string[1];
1064 filename = csp->blist->filename;
1065 file_description = "Block List";
1069 if (csp->permissions_list)
1071 filename = csp->permissions_list->filename;
1072 file_description = "Permissions List";
1078 filename = csp->flist->filename;
1079 file_description = "Forward List";
1087 filename = csp->alist->filename;
1088 file_description = "Access Control List";
1091 #endif /* def ACL_FILES */
1093 #ifdef USE_IMAGE_LIST
1097 filename = csp->ilist->filename;
1098 file_description = "Image List";
1101 #endif /* def USE_IMAGE_LIST */
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");
1225 if (csp->permissions_list)
1227 s = strsav(s, "<li>Permissions List: <a href=\"show-proxy-args?permit\"><code>");
1228 s = strsav(s, csp->permissions_list->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>RE Filter List: <a href=\"show-proxy-args?re\"><code>");
1261 s = strsav(s, csp->rlist->filename);
1262 s = strsav(s, "</code></a></li>\n");
1264 #endif /* def PCRS */
1269 s = strsav(s, "<li>Trust List: <a href=\"show-proxy-args?trust\"><code>");
1270 s = strsav(s, csp->tlist->filename);
1271 s = strsav(s, "</code></a></li>\n");
1273 #endif /* def TRUST_FILES */
1275 s = strsav(s, "</ul>");
1277 #else /* ifndef SPLIT_PROXY_ARGS */
1280 s = strsav(s, csp->blist->proxy_args);
1285 s = strsav(s, csp->clist->proxy_args);
1290 s = strsav(s, csp->flist->proxy_args);
1296 s = strsav(s, csp->alist->proxy_args);
1298 #endif /* def ACL_FILES */
1300 #ifdef USE_IMAGE_LIST
1303 s = strsav(s, csp->ilist->proxy_args);
1305 #endif /* def USE_IMAGE_LIST */
1310 s = strsav(s, csp->rlist->proxy_args);
1312 #endif /* def PCRS */
1317 s = strsav(s, csp->tlist->proxy_args);
1319 #endif /* def TRUST_FILES */
1321 #endif /* ndef SPLIT_PROXY_ARGS */
1323 s = strsav(s, proxy_args->trailer);
1331 /*********************************************************************
1333 * Function : ij_untrusted_url
1335 * Description : This "crunch"es "http:/any.thing/ij-untrusted-url" and
1336 * returns a web page describing why it was untrusted.
1339 * 1 : http = http_request request for crunched URL
1340 * 2 : csp = Current client state (buffers, headers, etc...)
1342 * Returns : A string that contains why this was untrusted.
1344 *********************************************************************/
1345 char *ij_untrusted_url(struct http_request *http, struct client_state *csp)
1348 char *hostport, *path, *refer, *p, *v[9];
1350 struct url_spec **tl, *t;
1353 static const char format[] =
1354 "HTTP/1.0 200 OK\r\n"
1355 "Pragma: no-cache\n"
1356 "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\n"
1357 "Expires: Thu Jul 31, 1997 07:42:22 pm GMT\n"
1358 "Content-Type: text/html\n\n"
1361 "<title>Internet Junkbuster: Request for untrusted URL</title>\n"
1367 "The " BANNER " Proxy "
1368 "<A href=\"" HOME_PAGE_URL "\">"
1369 "(" HOME_PAGE_URL ") </A>"
1370 "intercepted the request for %s%s\n"
1371 "because the URL is not trusted.\n"
1374 if ((n = ssplit(http->path, "?+", v, SZ(v), 0, 0)) == 4)
1376 hostport = url_decode(v[1]);
1377 path = url_decode(v[2]);
1378 refer = url_decode(v[3]);
1382 hostport = strdup("undefined_host");
1383 path = strdup("/undefined_path");
1384 refer = strdup("undefined");
1388 n += strlen(hostport);
1391 if ((p = (char *)malloc(n)))
1393 sprintf(p, format, hostport, path);
1396 strsav(p, "The referrer in this request was <strong>");
1398 strsav(p, "</strong><br>\n");
1404 p = strsav(p, "<h3>The following referrers are trusted</h3>\n");
1406 for (tl = trust_list; (t = *tl) ; tl++)
1408 sprintf(buf, "%s<br>\n", t->spec);
1412 if (trust_info->next)
1418 "You can learn more about what this means "
1419 "and what you may be able to do about it by "
1420 "reading the following documents:<br>\n"
1426 for (l = trust_info->next; l ; l = l->next)
1429 "<li> <a href=%s>%s</a><br>\n",
1434 p = strsav(p, "</ol>\n");
1437 p = strsav(p, "</body>\n" "</html>\n");
1442 #endif /* def TRUST_FILES */
1446 /*********************************************************************
1448 * Function : add_stats
1450 * Description : Statistics function of JB. Called by `show_proxy_args'.
1453 * 1 : s = string that holds the proxy args description page
1455 * Returns : A pointer to the descriptive status web page.
1457 *********************************************************************/
1458 char *add_stats(char *s)
1461 * Output details of the number of requests rejected and
1462 * accepted. This is switchable in the junkbuster config.
1463 * Does nothing if this option is not enabled.
1466 float perc_rej; /* Percentage of http requests rejected */
1468 int local_urls_read = urls_read;
1469 int local_urls_rejected = urls_rejected;
1472 * Need to alter the stats not to include the fetch of this
1475 * Can't do following thread safely! doh!
1478 * urls_rejected--; * This will be incremented subsequently *
1481 s = strsav(s,"<h2>Statistics for this " BANNER ":</h2>\n");
1483 if (local_urls_read == 0)
1486 s = strsav(s,"No activity so far!\n");
1492 perc_rej = (float)local_urls_rejected * 100.0F /
1493 (float)local_urls_read;
1496 "%d requests received, %d filtered "
1499 local_urls_rejected, perc_rej);
1501 s = strsav(s,out_str);
1506 #endif /* def STATISTICS */