home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Spezial / SPEZIAL2_97.zip / SPEZIAL2_97.iso / ANWEND / ONLINE / IJB20OS2 / SOURCE / FILTERS.C < prev    next >
Text File  |  1997-09-16  |  14KB  |  641 lines

  1. char *filters_rcs = "$Id: filters.c,v 1.7 1997/09/08 14:05:05 ACJC Exp $";
  2. /* Written and copyright by the Anonymous Coders and Junkbusters Corporation.
  3.  * Will be made available under the GNU General Public License.
  4.  * This software comes with NO WARRANTY.
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <sys/types.h>
  9. #include <stdlib.h>
  10. #include <ctype.h>
  11. #include <string.h>
  12.  
  13. #ifndef _WIN32
  14. #include <unistd.h>
  15. #endif
  16.  
  17. #ifdef REGEX
  18. #include <gnu_regex.h>
  19. #endif
  20.  
  21. #include "jcc.h"
  22.  
  23. #define URL(X) url_encode(url_code_map, (X))
  24.  
  25. char CBLOCK[] = "HTTP/1.0 202 Request for blocked URL\n"
  26.          "Pragma: no-cache\n"
  27.          "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\n"
  28.          "Expires:       Thu Jul 31, 1997 07:42:22 pm GMT\n"
  29.          "Content-Type: text/html\n\n"
  30.          "<html>\n"
  31.          "<head>\n"
  32.          "<title>Internet Junkbuster: Request for blocked URL</title>\n"
  33.          "</head>\n"
  34.          WHITEBG
  35.          "<center>"
  36.          "<a href=http://internet.junkbuster.com/ij-blocked-url?%s+%s+%s>"
  37.          BANNER
  38.          "</a>"
  39.          "</center>"
  40.          "</body>\n"
  41.          "</html>\n"
  42.          ;
  43.  
  44. char CTRUST[] = "HTTP/1.0 202 Request for untrusted URL\n"
  45.          "Pragma: no-cache\n"
  46.          "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\n"
  47.          "Expires:       Thu Jul 31, 1997 07:42:22 pm GMT\n"
  48.          "Content-Type: text/html\n\n"
  49.          "<html>\n"
  50.          "<head>\n"
  51.          "<title>Internet Junkbuster: Request for untrusted URL</title>\n"
  52.          "</head>\n"
  53.          WHITEBG
  54.          "<center>"
  55.          "<a href=http://internet.junkbuster.com/ij-untrusted-url?%s+%s+%s>"
  56.          BANNER
  57.          "</a>"
  58.          "</center>"
  59.          "</body>\n"
  60.          "</html>\n"
  61.          ;
  62.  
  63. char *
  64. block_url(struct http_request *http, struct client_state *csp)
  65. {
  66.     struct file_list *fl;
  67.     struct block_spec *b;
  68.     struct url_spec url[1];
  69.     char *p;
  70.     char *hostport, *path, *spec;
  71.     int n;
  72.  
  73.     if(((fl = csp->blist) == NULL) || ((b  = fl->f) == NULL)) {
  74.         return(NULL);
  75.     }
  76.  
  77.     *url = dsplit(http->host);
  78.  
  79.     for(b = b->next; b ; b = b->next) {
  80.         if((b->url->port == 0) || (b->url->port == http->port)) {
  81.             if((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0)) {
  82.                 if((b->url->path == NULL) ||
  83. #ifdef REGEX
  84.                    (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
  85. #else
  86.                    (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
  87. #endif
  88.                 ) {
  89.                     freez(url->dbuf);
  90.                     freez(url->dvec);
  91.  
  92.                     if(b->reject == 0) return(NULL);
  93.  
  94.                     hostport = URL(http->hostport);
  95.                     path     = URL(http->path);
  96.                     spec     = URL(b->url->spec);
  97.  
  98.                     n  = strlen(CBLOCK);
  99.                     n += strlen(hostport);
  100.                     n += strlen(path);
  101.                     n += strlen(spec);
  102.  
  103.                     p = malloc(n);
  104.  
  105.                     sprintf(p, CBLOCK,
  106.                         hostport, path, spec);
  107.  
  108.                     freez(hostport);
  109.                     freez(path);
  110.                     freez(spec);
  111.  
  112.                     return(p);
  113.                 }
  114.             }
  115.         }
  116.     }
  117.     freez(url->dbuf);
  118.     freez(url->dvec);
  119.     return(NULL);
  120. }
  121.  
  122. char *
  123. trust_url(struct http_request *http, struct client_state *csp)
  124. {
  125.     struct file_list *fl;
  126.     struct block_spec *b;
  127.     struct url_spec url[1], **tl, *t;
  128.     char *p, *h;
  129.     char *hostport, *path, *referrer;
  130.     struct http_request rhttp[1];
  131.     int n;
  132.  
  133.     if(((fl = csp->tlist) == NULL) || ((b  = fl->f) == NULL)) {
  134.         return(NULL);
  135.     }
  136.  
  137.     *url = dsplit(http->host);
  138.  
  139.     memset(rhttp, '\0', sizeof(*rhttp));
  140.  
  141.     for(b = b->next; b ; b = b->next) {
  142.  
  143.         if((b->url->port == 0) || (b->url->port == http->port)) {
  144.             if((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0)) {
  145.                 if((b->url->path == NULL) ||
  146. #ifdef REGEX
  147.                    (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
  148. #else
  149.                    (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
  150. #endif
  151.                 ) {
  152.                     freez(url->dbuf);
  153.                     freez(url->dvec);
  154.  
  155.                     if(b->reject == 0) return(NULL);
  156.  
  157.                     hostport = URL(http->hostport);
  158.                     path     = URL(http->path);
  159.  
  160.                     if(csp->referrer) {
  161.                         referrer = URL(csp->referrer);
  162.                     } else {
  163.                         referrer = URL("undefined");
  164.                     }
  165.  
  166.                     n  = strlen(CTRUST);
  167.                     n += strlen(hostport);
  168.                     n += strlen(path);
  169.                     n += strlen(referrer);
  170.  
  171.                     p = malloc(n);
  172.  
  173.                     sprintf(p, CTRUST,
  174.                         hostport, path, referrer);
  175.  
  176.                     freez(hostport);
  177.                     freez(path);
  178.                     freez(referrer);
  179.  
  180.                     return(p);
  181.                 }
  182.             }
  183.         }
  184.     }
  185.  
  186.     freez(url->dbuf);
  187.     freez(url->dvec);
  188.  
  189.     if((csp->referrer == NULL)|| (strlen(csp->referrer) <= 9)) {
  190.         /* no referrer was supplied */
  191.         goto trust_url_not_trusted;
  192.     }
  193.  
  194.     /* forge a URL from the referrer so we can use
  195.      * convert_url() to parse it into its components.
  196.      */
  197.  
  198.     p = NULL;
  199.     p = strsav(p, "GET ");
  200.     p = strsav(p, csp->referrer + 9);    /* skip over "Referer: " */
  201.     p = strsav(p, " HTTP/1.0");
  202.  
  203.     parse_http_request(p, rhttp, csp);
  204.  
  205.     if(rhttp->cmd == NULL) {
  206.         freez(p);
  207.         goto trust_url_not_trusted;
  208.     }
  209.  
  210.     freez(p);
  211.  
  212.     *url = dsplit(rhttp->host);
  213.  
  214.     for(tl = trust_list; (t = *tl) ; tl++) {
  215.         if((t->port == 0) || (t->port == rhttp->port)) {
  216.             if((t->domain[0] == '\0') || domaincmp(t, url) == 0) {
  217.                 if((t->path == NULL) ||
  218. #ifdef REGEX
  219.                    (regexec(t->preg, rhttp->path, 0, NULL, 0) == 0)
  220. #else
  221.                    (strncmp(t->path, rhttp->path, t->pathlen) == 0)
  222. #endif
  223.                 ) {
  224.                     /* if the URL's referrer is from a trusted referrer, then
  225.                      * add the target spec to the trustfile as an unblocked
  226.                      * domain and return NULL (which means it's OK).
  227.                      */
  228.  
  229.                     FILE *fp;
  230.                     
  231.                     freez(url->dbuf);
  232.                     freez(url->dvec);
  233.  
  234.                     if((fp = fopen(trustfile, "a"))) {
  235.                         h = NULL;
  236.  
  237.                         h = strsav(h, "~");
  238.                         h = strsav(h, http->hostport);
  239.  
  240.                         p = http->path;
  241.                         if((*p++ == '/')
  242.                         && (*p++ == '~')) {
  243.                         /* since this path points into a user's home space
  244.                          * be sure to include this spec in the trustfile.
  245.                          */
  246.                             if((p = strchr(p, '/'))) {
  247.                                 *p = '\0';
  248.                                 h = strsav(h, http->path);
  249.                                 h = strsav(h, "/");
  250.                             }
  251.                         }
  252.  
  253.                         free_http_request(rhttp);
  254.  
  255.                         fprintf(fp, "%s\n", h);
  256.                         freez(h);
  257.                         fclose(fp);
  258.                     }
  259.                     return(NULL);
  260.                 }
  261.             }
  262.         }
  263.     }
  264.  
  265. trust_url_not_trusted:
  266.     free_http_request(rhttp);
  267.  
  268.     hostport = URL(http->hostport);
  269.     path     = URL(http->path);
  270.  
  271.     if(csp->referrer) {
  272.         referrer = URL(csp->referrer);
  273.     } else {
  274.         referrer = URL("undefined");
  275.     }
  276.  
  277.     n  = strlen(CTRUST);
  278.     n += strlen(hostport);
  279.     n += strlen(path);
  280.     n += strlen(referrer);
  281.  
  282.     p = malloc(n);
  283.     sprintf(p, CTRUST, hostport, path, referrer);
  284.  
  285.     freez(hostport);
  286.     freez(path);
  287.     freez(referrer);
  288.  
  289.     return(p);
  290. }
  291.  
  292. /* intercept_url() checks the URL `basename' against a list of URLs
  293.  * to snarf.  If it matches, it calls the associated function which
  294.  * returns an HTML page to send back to the client.
  295.  */
  296.  
  297. char *
  298. intercept_url(struct http_request *http, struct client_state *csp)
  299. {
  300.     char *basename;
  301.     struct interceptors *v;
  302.     
  303.     basename = strrchr(http->path, '/');
  304.  
  305.     if(basename == NULL) return(NULL);
  306.  
  307.     basename++; /* first char past the last slash */
  308.  
  309.     if(*basename) {
  310.         for(v = intercept_patterns; v->str; v++) {
  311.             if(strncmp(basename, v->str, v->len) == 0) {
  312.  
  313.                 return((v->interceptor)(http, csp));
  314.             }
  315.         }
  316.     }
  317.  
  318.     return(NULL);
  319. }
  320.  
  321. struct cookie_spec *
  322. cookie_url(struct http_request *http, struct client_state *csp)
  323. {
  324.     struct file_list *fl;
  325.     struct cookie_spec *b;
  326.     struct url_spec url[1];
  327.  
  328.     if(((fl = csp->clist) == NULL) || ((b  = fl->f) == NULL)) {
  329.         return(NULL);
  330.     }
  331.  
  332.     *url = dsplit(http->host);
  333.  
  334.     for(b = b->next; b ; b = b->next) {
  335.         if((b->url->port == 0) || (b->url->port == http->port)) {
  336.             if((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0)) {
  337.                 if((b->url->path == NULL) ||
  338. #ifdef REGEX
  339.                    (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
  340. #else
  341.                    (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
  342. #endif
  343.                 ) {
  344.                     freez(url->dbuf);
  345.                     freez(url->dvec);
  346.                     return(b);
  347.                 }
  348.             }
  349.         }
  350.     }
  351.     freez(url->dbuf);
  352.     freez(url->dvec);
  353.     return(NULL);
  354. }
  355.  
  356. struct gateway *
  357. forward_url(struct http_request *http, struct client_state *csp)
  358. {
  359.     struct file_list *fl;
  360.     struct forward_spec *b;
  361.     struct url_spec url[1];
  362.  
  363.     if(((fl = csp->flist) == NULL) || ((b  = fl->f) == NULL)) {
  364.         return(gw_default);
  365.     }
  366.  
  367.     *url = dsplit(http->host);
  368.  
  369.     for(b = b->next; b ; b = b->next) {
  370.         if((b->url->port == 0) || (b->url->port == http->port)) {
  371.             if((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0)) {
  372.                 if((b->url->path == NULL) ||
  373. #ifdef REGEX
  374.                    (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
  375. #else
  376.                    (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
  377. #endif
  378.                 ) {
  379.                     freez(url->dbuf);
  380.                     freez(url->dvec);
  381.                     return(b->gw);
  382.                 }
  383.             }
  384.         }
  385.     }
  386.     freez(url->dbuf);
  387.     freez(url->dvec);
  388.     return(gw_default);
  389. }
  390.  
  391. /* dsplit() takes a domain and returns a pointer to a url_spec
  392.  * structure populated with dbuf, dcnt and dvec.  the other fields
  393.  * in the structure that is returned are zero.
  394.  *
  395.  */
  396.  
  397. struct url_spec
  398. dsplit(char *domain)
  399. {
  400.     struct url_spec ret[1];
  401.     char *v[BUFSIZ];
  402.     int size;
  403.     char *p;
  404.  
  405.     memset(ret, '\0', sizeof(*ret));
  406.  
  407.     ret->dbuf = strdup(domain);
  408.  
  409.     /* map to lower case */
  410.     for(p = ret->dbuf; *p ; p++) *p = tolower(*p);
  411.  
  412.     /* split the domain name into components */
  413.     ret->dcnt = ssplit(ret->dbuf, ".", v, SZ(v), 1, 1);
  414.  
  415.     /* save a copy of the pointers in dvec */
  416.     size = ret->dcnt * sizeof(*ret->dvec);
  417.         
  418.     if((ret->dvec = malloc(size))) {
  419.         memcpy(ret->dvec, v, size);
  420.     }
  421.  
  422.     return(*ret);
  423. }
  424.  
  425. /* the "pattern" is a domain that may contain a '*' as a wildcard.
  426.  * the "fqdn" is the domain name against which the patterns are compared.
  427.  *
  428.  * domaincmp("a.b.c" , "a.b.c")    => 0 (MATCH)
  429.  * domaincmp("a*.b.c", "a.b.c")    => 0 (MATCH)
  430.  * domaincmp("b.c"   , "a.b.c")    => 0 (MATCH)
  431.  * domaincmp(""      , "a.b.c")    => 0 (MATCH)
  432.  */
  433.  
  434. int
  435. domaincmp(struct url_spec *pattern, struct url_spec *fqdn)
  436. {
  437.     char **pv, **fv;    /* vectors  */
  438.     int    pn,   fn;    /* counters */
  439.     char  *p,   *f;        /* chars    */
  440.     
  441.     pv = pattern->dvec;
  442.     pn = pattern->dcnt;
  443.  
  444.     fv = fqdn->dvec;
  445.     fn = fqdn->dcnt;
  446.  
  447.     while((pn > 0) && (fn > 0)) {
  448.         p = pv[--pn];
  449.         f = fv[--fn];
  450.  
  451.         while(*p && *f && (*p == tolower(*f))) {
  452.             p++, f++;
  453.         }
  454.  
  455.         if((*p != tolower(*f)) && (*p != '*')) return(1);
  456.     }
  457.  
  458.     if(pn > 0) return(1);
  459.  
  460.     return(0);
  461. }
  462.  
  463. /* intercept functions */
  464.  
  465. char *
  466. show_proxy_args(struct http_request *http, struct client_state *csp)
  467. {
  468.     char *s = NULL;
  469.  
  470.     s = strsav(s, proxy_args->header);
  471.     s = strsav(s, proxy_args->invocation);
  472.     s = strsav(s, proxy_args->gateways);
  473.  
  474.     if(csp->blist) {
  475.         s = strsav(s, csp->blist->proxy_args);
  476.     }
  477.  
  478.     if(csp->clist) {
  479.         s = strsav(s, csp->clist->proxy_args);
  480.     }
  481.  
  482.     if(csp->tlist) {
  483.         s = strsav(s, csp->tlist->proxy_args);
  484.     }
  485.  
  486.     if(csp->flist) {
  487.         s = strsav(s, csp->flist->proxy_args);
  488.     }
  489.     s = strsav(s, proxy_args->trailer);
  490.  
  491.     return(s);
  492. }
  493.  
  494. char *
  495. ij_blocked_url(struct http_request *http, struct client_state *csp)
  496. {
  497.     int n;
  498.     char *hostport, *path, *pattern, *p, *v[9];
  499.  
  500.     char *template =
  501.         "HTTP/1.0 200 OK\r\n"
  502.         "Pragma: no-cache\n"
  503.         "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\n"
  504.         "Expires:       Thu Jul 31, 1997 07:42:22 pm GMT\n"
  505.         "Content-Type: text/html\n\n"
  506.         "<html>\n"
  507.         "<head>\n"
  508.         "<title>Internet Junkbuster: Request for blocked URL</title>\n"
  509.         "</head>\n"
  510.         BODY
  511.         "<center><h1>"
  512.         BANNER
  513.         "</h1></center>"
  514.         "The " BANNER " Proxy "
  515.         "<A href=\"http://internet.junkbuster.com\">"
  516.         "(http://internet.junkbuster.com) </A>"
  517.         "intercepted the request for %s%s\n"
  518.         "because the URL matches the following pattern "
  519.         "in the blockfile: %s\n"
  520.         "</body>\n"
  521.         "</html>\n"
  522.         ;
  523.  
  524.     if((n = ssplit(http->path, "?+", v, SZ(v), 0, 0)) == 4) {
  525.         hostport = url_decode(v[1]);
  526.         path     = url_decode(v[2]);
  527.         pattern  = url_decode(v[3]);
  528.     } else {
  529.         hostport = strdup("undefined_host");
  530.         path     = strdup("/undefined_path");
  531.         path     = strdup("undefined_pattern");
  532.     }
  533.  
  534.     n  = strlen(template);
  535.     n += strlen(hostport);
  536.     n += strlen(path    );
  537.     n += strlen(pattern );
  538.  
  539.     if((p = malloc(n))) {
  540.         sprintf(p, template, hostport, path, pattern);
  541.     }
  542.  
  543.     freez(hostport);
  544.     freez(path    );
  545.     freez(pattern );
  546.  
  547.     return(p);
  548. }
  549.  
  550. char *
  551. ij_untrusted_url(struct http_request *http, struct client_state *csp)
  552. {
  553.     int n;
  554.     char *hostport, *path, *p, *v[9];
  555.     char buf[BUFSIZ];
  556.     struct url_spec **tl, *t;
  557.  
  558.  
  559.     char *template =
  560.         "HTTP/1.0 200 OK\r\n"
  561.         "Pragma: no-cache\n"
  562.         "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\n"
  563.         "Expires:       Thu Jul 31, 1997 07:42:22 pm GMT\n"
  564.         "Content-Type: text/html\n\n"
  565.         "<html>\n"
  566.         "<head>\n"
  567.         "<title>Internet Junkbuster: Request for untrusted URL</title>\n"
  568.         "</head>\n"
  569.         BODY
  570.         "<center><h1>"
  571.         BANNER
  572.         "</h1></center>"
  573.         "The " BANNER " Proxy "
  574.         "<A href=\"http://internet.junkbuster.com\">"
  575.         "(http://internet.junkbuster.com) </A>"
  576.         "intercepted the request for %s%s\n"
  577.         "because the URL is not trusted.\n"
  578.         "<br><br>\n"
  579.         ;
  580.  
  581.     if((n = ssplit(http->path, "?+", v, SZ(v), 0, 0)) == 4) {
  582.         hostport = url_decode(v[1]);
  583.         path     = url_decode(v[2]);
  584.         referrer = url_decode(v[3]);
  585.     } else {
  586.         hostport = strdup("undefined_host");
  587.         path     = strdup("/undefined_path");
  588.         referrer = strdup("undefined");
  589.     }
  590.  
  591.     n  = strlen(template);
  592.     n += strlen(hostport);
  593.     n += strlen(path    );
  594.     n += strlen(referrer);
  595.  
  596.     if((p = malloc(n))) {
  597.         sprintf(p, template, hostport, path);
  598.     }
  599.  
  600.     freez(hostport);
  601.     freez(path    );
  602.  
  603.     strsav(p, "The referrer in this request was <strong>");
  604.     strsav(p, referrer);
  605.     strsav(p, "</strong><br>\n");
  606.  
  607.     p = strsav(p, "<h3>The following referrers are trusted</h3>\n");
  608.  
  609.     for(tl = trust_list; (t = *tl) ; tl++) {
  610.         sprintf(buf, "%s<br>\n", t->spec);
  611.         p = strsav(p, buf);
  612.     }
  613.  
  614.     if(trust_info->next) {
  615.         struct list *l;
  616.  
  617.         strcpy(buf,
  618.             "<p>"
  619.             "You can learn more about what this means "
  620.             "and what you may be able to do about it by "
  621.             "reading the following documents:<br>\n"
  622.             "<ol>\n"
  623.         );
  624.  
  625.         p = strsav(p, buf);
  626.         
  627.         for(l = trust_info->next; l ; l = l->next) {
  628.             sprintf(buf,
  629.                 "<li> <a href=%s>%s</a><br>\n",
  630.                     l->str, l->str);
  631.             p = strsav(p, buf);
  632.         }
  633.  
  634.         p = strsav(p, "</ol>\n");
  635.     }
  636.  
  637.     p = strsav(p, "</body>\n" "</html>\n");
  638.  
  639.     return(p);
  640. }
  641.