1 const char filters_rcs[] = "$Id: filters.c,v 1.2 2001/05/20 01:21:20 jongfoster 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.2 2001/05/20 01:21:20 jongfoster
42 * Version 2.9.4 checkin.
43 * - Merged popupfile and cookiefile, and added control over PCRS
44 * filtering, in new "permissionsfile".
45 * - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
46 * file error you now get a message box (in the Win32 GUI) rather
47 * than the program exiting with no explanation.
48 * - Made killpopup use the PCRS MIME-type checking and HTTP-header
50 * - Removed tabs from "config"
51 * - Moved duplicated url parsing code in "loaders.c" to a new funcition.
52 * - Bumped up version number.
54 * Revision 1.1.1.1 2001/05/15 13:58:52 oes
55 * Initial import of version 2.9.3 source tree
58 *********************************************************************/
64 #include <sys/types.h>
71 #include <netinet/in.h>
84 #include "jbsockets.h"
86 #include "jbsockets.h"
92 const char filters_h_rcs[] = FILTERS_H_VERSION;
94 /* Fix a problem with Solaris. There should be no effect on other
96 * Solaris's isspace() is a macro which uses it's argument directly
97 * as an array index. Therefore we need to make sure that high-bit
98 * characters generate +ve values, and ideally we also want to make
99 * the argument match the declared parameter type of "int".
101 #define ijb_isdigit(__X) isdigit((int)(unsigned char)(__X))
104 static const char CBLOCK[] =
106 "HTTP/1.0 403 Request for blocked URL\n"
107 #else /* ifndef AMIGA */
108 "HTTP/1.0 202 Request for blocked URL\n"
109 #endif /* ndef AMIGA */
111 "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\n"
112 "Expires: Thu Jul 31, 1997 07:42:22 pm GMT\n"
113 "Content-Type: text/html\n\n"
116 "<title>Internet Junkbuster: Request for blocked URL</title>\n"
122 "<p align=center>Your request for <b>%s%s</b><br>\n"
123 "was blocked because it matches the following pattern "
124 "in the blockfile: <b>%s</b>\n</p>"
126 "<p align=center><a href=\"http://" FORCE_PREFIX
127 "%s%s\">Go there anyway.</a></p>"
128 #endif /* def FORCE_LOAD */
133 static const char CTRUST[] =
135 "HTTP/1.0 403 Request for untrusted URL\n"
136 #else /* ifndef AMIGA */
137 "HTTP/1.0 202 Request for untrusted URL\n"
138 #endif /* ndef AMIGA */
140 "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\n"
141 "Expires: Thu Jul 31, 1997 07:42:22 pm GMT\n"
142 "Content-Type: text/html\n\n"
145 "<title>Internet Junkbuster: Request for untrusted URL</title>\n"
149 "<a href=http://internet.junkbuster.com/ij-untrusted-url?%s+%s+%s>"
155 #endif /* def TRUST_FILES */
159 /*********************************************************************
161 * Function : block_acl
163 * Description : Block this request?
164 * Decide yes or no based on ACL file.
167 * 1 : src = Address the browser/user agent is requesting.
168 * 2 : dst = The proxy or gateway address this is going to.
169 * 3 : csp = Current client state (buffers, headers, etc...)
171 * Returns : 0 = FALSE (don't block) and 1 = TRUE (do block)
173 *********************************************************************/
174 int block_acl(struct access_control_addr *src, struct access_control_addr *dst, struct client_state *csp)
176 struct file_list *fl;
177 struct access_control_list *a, *acl;
178 struct access_control_addr s[1], d[1];
180 /* if not using an access control list, then permit the connection */
181 if (((fl = csp->alist) == NULL) || ((acl = fl->f) == NULL))
186 /* search the list */
187 for (a = acl->next ; a ; a = a->next)
192 s->addr &= a->src->mask;
193 d->addr &= a->dst->mask;
195 if ((s->addr == a->src->addr)
196 && (d->addr == a->dst->addr)
197 && ((s->port == a->src->port)
199 || (a->src->port == 0))
200 && ((d->port == a->dst->port)
202 || (a->dst->port == 0)))
204 if (a->action == ACL_PERMIT)
220 /*********************************************************************
222 * Function : acl_addr
224 * Description : Called from `load_aclfile'. FIXME: I can't say more.
227 * 1 : aspec = (what?)
230 * Returns : 0 => Ok, everything else is an error.
232 *********************************************************************/
233 int acl_addr(char *aspec, struct access_control_addr *aca)
235 int i, masklength, port;
241 if ((p = strchr(aspec, '/')))
245 if (ijb_isdigit(*p) == 0)
249 masklength = atoi(p);
252 if ((masklength < 0) || (masklength > 32))
257 if ((p = strchr(aspec, ':')))
261 if (ijb_isdigit(*p) == 0)
270 aca->addr = ntohl(resolve_hostname_to_ip(aspec));
274 log_error(LOG_LEVEL_ERROR, "can't resolve address for %s", aspec);
278 /* build the netmask */
280 for (i=1; i <= masklength ; i++)
282 aca->mask |= (1 << (32 - i));
285 /* now mask off the host portion of the ip address
286 * (i.e. save on the network portion of the address).
288 aca->addr = aca->addr & aca->mask;
293 #endif /* def ACL_FILES */
296 /*********************************************************************
298 * Function : block_url
300 * Description : Called from `chat'. Check to see if we need to block this.
303 * 1 : http = http_request request to "check" for blocked
304 * 2 : csp = Current client state (buffers, headers, etc...)
306 * Returns : NULL => unblocked, else string to HTML block description.
308 *********************************************************************/
309 char *block_url(struct http_request *http, struct client_state *csp)
311 struct file_list *fl;
312 struct block_spec *b;
313 struct url_spec url[1];
317 if (((fl = csp->blist) == NULL) || ((b = fl->f) == NULL))
322 *url = dsplit(http->host);
324 /* if splitting the domain fails, punt */
325 if (url->dbuf == NULL) return(NULL);
327 for (b = b->next; b ; b = b->next)
329 if ((b->url->port == 0) || (b->url->port == http->port))
331 if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
333 if ((b->url->path == NULL) ||
335 (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
337 (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
344 if (b->reject == 0) return(NULL);
347 n += strlen(http->hostport);
348 n += strlen(http->path);
349 n += strlen(b->url->spec);
351 n += strlen(http->hostport);
352 n += strlen(http->path);
353 #endif /* def FORCE_LOAD */
355 p = (char *)malloc(n);
358 sprintf(p, CBLOCK, http->hostport, http->path, b->url->spec, http->hostport, http->path);
360 sprintf(p, CBLOCK, http->hostport, http->path, b->url->spec);
361 #endif /* def FORCE_LOAD */
375 #if defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
376 /*********************************************************************
378 * Function : block_imageurl
380 * Description : Given a URL which is blocked, decide whether to
381 * send the "blocked" image or HTML.
384 * 1 : http = URL to check.
385 * 2 : csp = Current client state (buffers, headers, etc...)
387 * Returns : True (nonzero) if URL is in image list, false (0)
390 *********************************************************************/
391 int block_imageurl(struct http_request *http, struct client_state *csp)
393 #ifdef DETECT_MSIE_IMAGES
394 if ((csp->accept_types
395 & (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_IMAGE|ACCEPT_TYPE_MSIE_HTML))
396 == (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_IMAGE))
400 else if ((csp->accept_types
401 & (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_IMAGE|ACCEPT_TYPE_MSIE_HTML))
402 == (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_HTML))
408 #if defined(USE_IMAGE_LIST)
409 return block_imageurl_using_imagelist(http, csp);
411 /* Don't know - assume HTML */
415 #endif /* defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
418 #ifdef USE_IMAGE_LIST
419 /*********************************************************************
421 * Function : block_imageurl
423 * Description : Test if a URL is in the imagelist.
426 * 1 : http = URL to check.
427 * 2 : csp = Current client state (buffers, headers, etc...)
429 * Returns : True (nonzero) if URL is in image list, false (0)
432 *********************************************************************/
433 int block_imageurl_using_imagelist(struct http_request *http, struct client_state *csp)
435 struct file_list *fl;
436 struct block_spec *b;
437 struct url_spec url[1];
439 if (((fl = csp->ilist) == NULL) || ((b = fl->f) == NULL))
444 *url = dsplit(http->host);
446 /* if splitting the domain fails, punt */
447 if (url->dbuf == NULL) return(0);
449 for (b = b->next; b ; b = b->next)
452 if ((b->url->port == 0) || (b->url->port == http->port))
454 /* port matches, check domain */
455 if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
457 /* domain matches, check path */
458 if ((b->url->path == NULL) ||
460 (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
462 (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
470 if (b->reject == 0) return(0);
482 #endif /* def USE_IMAGE_LIST */
486 /*********************************************************************
488 * Function : re_process_buffer
490 * Description : Apply all jobs from the joblist (aka. Perl regexp's) to
491 * the text buffer that's been accumulated in csp->iob->buf.
492 * Then, write the modified buffer out to the client
493 * (Maybe this should happen from jcc.c via flush_socket
494 * for better readability).
497 * 1 : csp = Current client state (buffers, headers, etc...)
501 *********************************************************************/
502 void re_process_buffer(struct client_state *csp)
505 int size = csp->iob->eod - csp->iob->cur;
506 char *old=csp->iob->cur, *new = NULL;
507 pcrs_job *job, *joblist;
509 struct file_list *fl;
510 struct re_filterfile_spec *b;
512 /* Sanity first ;-) */
518 if ( ( NULL == (fl = csp->rlist) ) || ( NULL == (b = fl->f) ) )
520 log_error(LOG_LEVEL_ERROR, "Unable to get current state of regexp filtering.");
524 joblist = b->joblist;
527 log_error(LOG_LEVEL_RE_FILTER, "re_filtering %s%s (size %d) ...",
528 csp->http->hostport, csp->http->path, size);
530 /* Apply all jobs from the joblist */
531 for (job = joblist; NULL != job; job = job->next)
533 hits += pcrs_exec_substitution(job, old, size, &new, &size);
534 if (old != csp->iob->cur) free(old);
538 log_error(LOG_LEVEL_RE_FILTER, " produced %d hits (new size %d).", hits, size);
540 if (write_socket(csp->cfd, old, size) != size)
542 log_error(LOG_LEVEL_ERROR, "write to client failed.");
545 /* fwiw, reset the iob */
551 #endif /* def PCRS */
555 /*********************************************************************
557 * Function : trust_url
559 * Description : Should we "trust" this URL? See "trustfile" line in config.
562 * 1 : http = http_request request for requested URL
563 * 2 : csp = Current client state (buffers, headers, etc...)
565 * Returns : NULL => trusted, else string to HTML "untrusted" description.
567 *********************************************************************/
568 char *trust_url(struct http_request *http, struct client_state *csp)
570 struct file_list *fl;
571 struct block_spec *b;
572 struct url_spec url[1], **tl, *t;
574 char *hostport, *path, *refer;
575 struct http_request rhttp[1];
578 if (((fl = csp->tlist) == NULL) || ((b = fl->f) == NULL))
583 *url = dsplit(http->host);
585 /* if splitting the domain fails, punt */
586 if (url->dbuf == NULL) return(NULL);
588 memset(rhttp, '\0', sizeof(*rhttp));
590 for (b = b->next; b ; b = b->next)
592 if ((b->url->port == 0) || (b->url->port == http->port))
594 if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
596 if ((b->url->path == NULL) ||
598 (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
600 (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
607 if (b->reject == 0) return(NULL);
609 hostport = url_encode(http->hostport);
610 path = url_encode(http->path);
614 refer = url_encode(csp->referrer);
618 refer = url_encode("undefined");
622 n += strlen(hostport);
626 p = (char *)malloc(n);
628 sprintf(p, CTRUST, hostport, path, refer);
643 if ((csp->referrer == NULL)|| (strlen(csp->referrer) <= 9))
645 /* no referrer was supplied */
646 goto trust_url_not_trusted;
649 /* forge a URL from the referrer so we can use
650 * convert_url() to parse it into its components.
654 p = strsav(p, "GET ");
655 p = strsav(p, csp->referrer + 9); /* skip over "Referer: " */
656 p = strsav(p, " HTTP/1.0");
658 parse_http_request(p, rhttp, csp);
660 if (rhttp->cmd == NULL)
663 goto trust_url_not_trusted;
668 *url = dsplit(rhttp->host);
670 /* if splitting the domain fails, punt */
671 if (url->dbuf == NULL) goto trust_url_not_trusted;
673 for (tl = trust_list; (t = *tl) ; tl++)
675 if ((t->port == 0) || (t->port == rhttp->port))
677 if ((t->domain[0] == '\0') || domaincmp(t, url) == 0)
679 if ((t->path == NULL) ||
681 (regexec(t->preg, rhttp->path, 0, NULL, 0) == 0)
683 (strncmp(t->path, rhttp->path, t->pathlen) == 0)
687 /* if the URL's referrer is from a trusted referrer, then
688 * add the target spec to the trustfile as an unblocked
689 * domain and return NULL (which means it's OK).
697 if ((fp = fopen(trustfile, "a")))
702 h = strsav(h, http->hostport);
708 /* since this path points into a user's home space
709 * be sure to include this spec in the trustfile.
711 if ((p = strchr(p, '/')))
714 h = strsav(h, http->path);
719 free_http_request(rhttp);
721 fprintf(fp, "%s\n", h);
731 trust_url_not_trusted:
732 free_http_request(rhttp);
734 hostport = url_encode(http->hostport);
735 path = url_encode(http->path);
739 refer = url_encode(csp->referrer);
743 refer = url_encode("undefined");
747 n += strlen(hostport);
751 p = (char *)malloc(n);
752 sprintf(p, CTRUST, hostport, path, refer);
761 #endif /* def TRUST_FILES */
764 /*********************************************************************
766 * Function : intercept_url
768 * Description : checks the URL `basename' against a list of URLs to
769 * snarf. If it matches, it calls the associated function
770 * which returns an HTML page to send back to the client.
771 * Right now, we snarf:
772 * "show-proxy-args", and
773 * "ij-untrusted-url" (optional w/TRUST_FILES)
776 * 1 : http = http_request request, check `basename's of blocklist
777 * 2 : csp = Current client state (buffers, headers, etc...)
779 * Returns : NULL for no recognized URLs, or an HTML description page.
781 *********************************************************************/
782 char *intercept_url(struct http_request *http, struct client_state *csp)
785 const struct interceptors *v;
787 basename = strrchr(http->path, '/');
789 if (basename == NULL) return(NULL);
791 basename ++; /* first char past the last slash */
795 for (v = intercept_patterns; v->str; v++)
797 if (strncmp(basename, v->str, v->len) == 0)
799 return((v->interceptor)(http, csp));
809 /*********************************************************************
811 * Function : url_permissions
813 * Description : Gets the permissions for this URL.
816 * 1 : http = http_request request for blocked URLs
817 * 2 : csp = Current client state (buffers, headers, etc...)
819 * Returns : permissions bitmask specifiying what this URL can do.
\r
820 * If not on list, will be default_permissions.
822 *********************************************************************/
823 int url_permissions(struct http_request *http, struct client_state *csp)
825 struct file_list *fl;
826 struct permissions_spec *b;
827 struct url_spec url[1];
829 if (((fl = csp->permissions_list) == NULL) || ((b = fl->f) == NULL))
831 return(default_permissions);
834 *url = dsplit(http->host);
836 /* if splitting the domain fails, punt */
837 if (url->dbuf == NULL)
\r
839 return(default_permissions);
\r
842 for (b = b->next; NULL != b; b = b->next)
844 if ((b->url->port == 0) || (b->url->port == http->port))
846 if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
848 if ((b->url->path == NULL) ||
850 (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
852 (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
858 return(b->permissions);
866 return(default_permissions);
871 /*********************************************************************
873 * Function : forward_url
875 * Description : Should we forward this to another proxy?
878 * 1 : http = http_request request for current URL
879 * 2 : csp = Current client state (buffers, headers, etc...)
881 * Returns : Return gw_default for no forward match,
882 * else a gateway pointer to a specific forwarding proxy.
884 *********************************************************************/
885 const struct gateway *forward_url(struct http_request *http, struct client_state *csp)
887 struct file_list *fl;
888 struct forward_spec *b;
889 struct url_spec url[1];
891 if (((fl = csp->flist) == NULL) || ((b = fl->f) == NULL))
896 *url = dsplit(http->host);
898 /* if splitting the domain fails, punt */
899 if (url->dbuf == NULL) return(gw_default);
901 for (b = b->next; b ; b = b->next)
903 if ((b->url->port == 0) || (b->url->port == http->port))
905 if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
907 if ((b->url->path == NULL) ||
909 (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
911 (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
930 /*********************************************************************
934 * Description : Takes a domain and returns a pointer to a url_spec
935 * structure populated with dbuf, dcnt and dvec. The
936 * other fields in the structure that is returned are zero.
939 * 1 : domain = a URL address
941 * Returns : url_spec structure populated with dbuf, dcnt and dvec.
943 *********************************************************************/
944 struct url_spec dsplit(char *domain)
946 struct url_spec ret[1];
951 memset(ret, '\0', sizeof(*ret));
953 if ((p = strrchr(domain, '.')))
961 ret->dbuf = strdup(domain);
963 /* map to lower case */
964 for (p = ret->dbuf; *p ; p++) *p = tolower(*p);
966 /* split the domain name into components */
967 ret->dcnt = ssplit(ret->dbuf, ".", v, SZ(v), 1, 1);
971 memset(ret, '\0', sizeof(ret));
975 /* save a copy of the pointers in dvec */
976 size = ret->dcnt * sizeof(*ret->dvec);
978 if ((ret->dvec = (char **)malloc(size)))
980 memcpy(ret->dvec, v, size);
988 /*********************************************************************
990 * Function : domaincmp
992 * Description : Compare domain names.
993 * domaincmp("a.b.c" , "a.b.c") => 0 (MATCH)
994 * domaincmp("a*.b.c", "a.b.c") => 0 (MATCH)
995 * domaincmp("b.c" , "a.b.c") => 0 (MATCH)
996 * domaincmp("" , "a.b.c") => 0 (MATCH)
999 * 1 : pattern = a domain that may contain a '*' as a wildcard.
1000 * 2 : fqdn = domain name against which the patterns are compared.
1002 * Returns : 0 => domains are equivalent, else no match.
1004 *********************************************************************/
1005 int domaincmp(struct url_spec *pattern, struct url_spec *fqdn)
1007 char **pv, **fv; /* vectors */
1008 int pn, fn; /* counters */
1009 char *p, *f; /* chars */
1017 while ((pn > 0) && (fn > 0))
1022 while (*p && *f && (*p == tolower(*f)))
1027 if ((*p != tolower(*f)) && (*p != '*')) return(1);
1030 if (pn > 0) return(1);
1037 /* intercept functions */
1039 /*********************************************************************
1041 * Function : show_proxy_args
1043 * Description : This "crunch"es "http:/any.thing/show-proxy-args" and
1044 * returns a web page describing the current status of IJB.
1047 * 1 : http = ignored
1048 * 2 : csp = Current client state (buffers, headers, etc...)
1050 * Returns : A string that contains the current status of IJB.
1052 *********************************************************************/
1053 char *show_proxy_args(struct http_request *http, struct client_state *csp)
1057 #ifdef SPLIT_PROXY_ARGS
1061 const char * filename = NULL;
1062 const char * file_description = NULL;
1063 char * query_string = strrchr(http->path, '?');
1064 char which_file = '\0';
1067 if (query_string != NULL)
1069 /* first char past the last '?' (maybe '\0')*/
1070 which_file = query_string[1];
1077 filename = csp->blist->filename;
1078 file_description = "Block List";
1082 if (csp->permissions_list)
1084 filename = csp->permissions_list->filename;
1085 file_description = "Permissions List";
1091 filename = csp->flist->filename;
1092 file_description = "Forward List";
1100 filename = csp->alist->filename;
1101 file_description = "Access Control List";
1104 #endif /* def ACL_FILES */
1106 #ifdef USE_IMAGE_LIST
1110 filename = csp->ilist->filename;
1111 file_description = "Image List";
1114 #endif /* def USE_IMAGE_LIST */
1120 filename = csp->rlist->filename;
1121 file_description = "RE Filter List";
1124 #endif /* def PCRS */
1130 filename = csp->tlist->filename;
1131 file_description = "Trust List";
1134 #endif /* def TRUST_FILES */
1139 /* Display specified file */
1140 /* FIXME: Add HTTP headers so this isn't cached */
1143 "Server: IJ/" VERSION "\n"
1144 "Content-type: text/html\n"
1145 "Pragma: no-cache\n"
1146 "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\n"
1147 "Expires: Thu Jul 31, 1997 07:42:22 pm GMT\n"
1152 "<title>Internet Junkbuster Proxy Status - ");
1153 s = strsav(s, file_description);
1157 "<body bgcolor=\"#f8f8f0\" link=\"#000078\" alink=\"#ff0022\" vlink=\"#787878\">\n"
1159 "<h1>" BANNER "\n");
1160 s = strsav(s, file_description);
1163 "<p><a href=\"show-proxy-args\">Back to proxy status</a></p>\n"
1165 s = strsav(s, file_description);
1168 "Contents of file "<code>");
1169 p = html_encode(filename);
1173 "</code>":<br>\n"
1177 if ((fp = fopen(filename, "r")) == NULL)
1179 s = strsav(s, "</pre><h1>ERROR OPENING FILE!</h1><pre>");
1183 while (fgets(buf, sizeof(buf), fp))
1185 p = html_encode(buf);
1190 s = strsav(s, "<br>");
1199 "<p><a href=\"show-proxy-args\">Back to proxy status</a></p>\n"
1201 "<small><small><p>\n"
1202 "The " BANNER " Proxy - \n"
1203 "<a href=\"" HOME_PAGE_URL "\">" HOME_PAGE_URL "</a>\n"
\r
1205 "</body></html>\n");
1208 #endif /* def SPLIT_PROXY_ARGS */
1210 s = strsav(s, proxy_args->header);
1211 s = strsav(s, proxy_args->invocation);
1214 #endif /* def STATISTICS */
1215 s = strsav(s, proxy_args->gateways);
1217 #ifdef SPLIT_PROXY_ARGS
1219 "<h2>The following files are in use:</h2>\n"
1220 "<p>(Click a filename to view it)</p>\n"
1225 s = strsav(s, "<li>Block List: <a href=\"show-proxy-args?block\"><code>");
1226 s = strsav(s, csp->blist->filename);
1227 s = strsav(s, "</code></a></li>\n");
1230 if (csp->permissions_list)
1232 s = strsav(s, "<li>Permissions List: <a href=\"show-proxy-args?permit\"><code>");
1233 s = strsav(s, csp->permissions_list->filename);
1234 s = strsav(s, "</code></a></li>\n");
1239 s = strsav(s, "<li>Forward List: <a href=\"show-proxy-args?forward\"><code>");
1240 s = strsav(s, csp->flist->filename);
1241 s = strsav(s, "</code></a></li>\n");
1247 s = strsav(s, "<li>Access Control List: <a href=\"show-proxy-args?acl\"><code>");
1248 s = strsav(s, csp->alist->filename);
1249 s = strsav(s, "</code></a></li>\n");
1251 #endif /* def ACL_FILES */
1253 #ifdef USE_IMAGE_LIST
1256 s = strsav(s, "<li>Image List: <a href=\"show-proxy-args?image\"><code>");
1257 s = strsav(s, csp->ilist->filename);
1258 s = strsav(s, "</code></a></li>\n");
1260 #endif /* def USE_IMAGE_LIST */
1265 s = strsav(s, "<li>RE Filter List: <a href=\"show-proxy-args?re\"><code>");
1266 s = strsav(s, csp->rlist->filename);
1267 s = strsav(s, "</code></a></li>\n");
1269 #endif /* def PCRS */
1274 s = strsav(s, "<li>Trust List: <a href=\"show-proxy-args?trust\"><code>");
1275 s = strsav(s, csp->tlist->filename);
1276 s = strsav(s, "</code></a></li>\n");
1278 #endif /* def TRUST_FILES */
1280 s = strsav(s, "</ul>");
1282 #else /* ifndef SPLIT_PROXY_ARGS */
1285 s = strsav(s, csp->blist->proxy_args);
1290 s = strsav(s, csp->clist->proxy_args);
1295 s = strsav(s, csp->flist->proxy_args);
1301 s = strsav(s, csp->alist->proxy_args);
1303 #endif /* def ACL_FILES */
1305 #ifdef USE_IMAGE_LIST
1308 s = strsav(s, csp->ilist->proxy_args);
1310 #endif /* def USE_IMAGE_LIST */
1315 s = strsav(s, csp->rlist->proxy_args);
1317 #endif /* def PCRS */
1322 s = strsav(s, csp->tlist->proxy_args);
1324 #endif /* def TRUST_FILES */
1326 #endif /* ndef SPLIT_PROXY_ARGS */
1328 s = strsav(s, proxy_args->trailer);
1336 /*********************************************************************
1338 * Function : ij_untrusted_url
1340 * Description : This "crunch"es "http:/any.thing/ij-untrusted-url" and
1341 * returns a web page describing why it was untrusted.
1344 * 1 : http = http_request request for crunched URL
1345 * 2 : csp = Current client state (buffers, headers, etc...)
1347 * Returns : A string that contains why this was untrusted.
1349 *********************************************************************/
1350 char *ij_untrusted_url(struct http_request *http, struct client_state *csp)
1353 char *hostport, *path, *refer, *p, *v[9];
1355 struct url_spec **tl, *t;
1358 static const char format[] =
1359 "HTTP/1.0 200 OK\r\n"
1360 "Pragma: no-cache\n"
1361 "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\n"
1362 "Expires: Thu Jul 31, 1997 07:42:22 pm GMT\n"
1363 "Content-Type: text/html\n\n"
1366 "<title>Internet Junkbuster: Request for untrusted URL</title>\n"
1372 "The " BANNER " Proxy "
1373 "<A href=\"" HOME_PAGE_URL "\">"
1374 "(" HOME_PAGE_URL ") </A>"
1375 "intercepted the request for %s%s\n"
1376 "because the URL is not trusted.\n"
1379 if ((n = ssplit(http->path, "?+", v, SZ(v), 0, 0)) == 4)
1381 hostport = url_decode(v[1]);
1382 path = url_decode(v[2]);
1383 refer = url_decode(v[3]);
1387 hostport = strdup("undefined_host");
1388 path = strdup("/undefined_path");
1389 refer = strdup("undefined");
1393 n += strlen(hostport);
1396 if ((p = (char *)malloc(n)))
1398 sprintf(p, format, hostport, path);
1401 strsav(p, "The referrer in this request was <strong>");
1403 strsav(p, "</strong><br>\n");
1409 p = strsav(p, "<h3>The following referrers are trusted</h3>\n");
1411 for (tl = trust_list; (t = *tl) ; tl++)
1413 sprintf(buf, "%s<br>\n", t->spec);
1417 if (trust_info->next)
1423 "You can learn more about what this means "
1424 "and what you may be able to do about it by "
1425 "reading the following documents:<br>\n"
1431 for (l = trust_info->next; l ; l = l->next)
1434 "<li> <a href=%s>%s</a><br>\n",
1439 p = strsav(p, "</ol>\n");
1442 p = strsav(p, "</body>\n" "</html>\n");
1447 #endif /* def TRUST_FILES */
1451 /*********************************************************************
1453 * Function : add_stats
1455 * Description : Statistics function of JB. Called by `show_proxy_args'.
1458 * 1 : s = string that holds the proxy args description page
1460 * Returns : A pointer to the descriptive status web page.
1462 *********************************************************************/
1463 char *add_stats(char *s)
1466 * Output details of the number of requests rejected and
1467 * accepted. This is switchable in the junkbuster config.
1468 * Does nothing if this option is not enabled.
1471 float perc_rej; /* Percentage of http requests rejected */
1473 int local_urls_read = urls_read;
1474 int local_urls_rejected = urls_rejected;
1477 * Need to alter the stats not to include the fetch of this
1480 * Can't do following thread safely! doh!
1483 * urls_rejected--; * This will be incremented subsequently *
1486 s = strsav(s,"<h2>Statistics for this " BANNER ":</h2>\n");
1488 if (local_urls_read == 0)
1491 s = strsav(s,"No activity so far!\n");
1497 perc_rej = (float)local_urls_rejected * 100.0F /
1498 (float)local_urls_read;
1501 "%d requests received, %d filtered "
1504 local_urls_rejected, perc_rej);
1506 s = strsav(s,out_str);
1511 #endif /* def STATISTICS */