/* * ****** JEANNE.C ****** * * Squid redirector. Input validation for reverse proxy. * * Vincent Berk vberk@ists.dartmouth.edu * ISTS/Dartmouth College Hanover, NH * * jeanne.c Copyright (C) 2001 Vincent Berk GNU/GPL * * --------------------------------------- * Copyright (c) 2001 ISTS Dartmouth College * * Permission is hereby granted, free of charge, to everyone * obtaining a copy of this software and associated * documentation files (the "Software"), to use and modify. * Redistribution under conditions specified by ISTS is permitted * provided that this copyright and permission notice is maintained, * intact, in all copies and supporting documentation. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * * IN NO EVENT SHALL DARTMOUTH COLLEGE OR ITS EMPLOYEES BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OF OR OTHER DEALINGS WITH THE SOFTWARE. * --------------------------------------- */ #include #include #include #include /* Error codes */ #define E_OK 0 #define E_INPUT 1 #define E_NOMEM 2 /* Debug level */ #define D_NONE 0 #define D_ALL 1 /* Defaults */ #define DEF_BUFSIZE 1500 #define DEF_MAX_URLS 10000 #define DEF_URL_FILE "/home/root/rev-proxy/redir/urls" #define DEF_REJECT_URL "reject.html localhost/- - GET" /* syslog (LOG_NOTICE, LOG_WARNING, LOG_ERROR); if (DEBUG) (LOG_DEBUG); */ int get_config () { return (E_OK); } int get_urls (char **V, char *url_file, int *max_urls, int buf_size, int DEBUG) { int error, i, l; char *buffer; FILE *fd; if (DEBUG) syslog (LOG_DEBUG, "Retrieving URLs from %s", url_file); error = E_OK; buffer = malloc (buf_size * sizeof (char)); fd = fopen (url_file, "r"); if (!buffer || !fd) { syslog (LOG_ERR, "Could not retrieve URLs from %s", url_file); return (E_INPUT); } i = 0; while (!error && fgets_unlocked (buffer, buf_size, fd) && i < (*max_urls)) { /* Make sure that we don't get buffer overflows */ buffer[buf_size - 1] = '\0'; if (buffer[0] != '#' && buffer[0] != '\n' && buffer[0] != '\0' && buffer[0] != ' ') { /* Killing the endline with some magic... ;-) */ *(strchr (buffer, '\n')) = '\0'; /* Allocate no more than necessary, strlen doesn't include \0 */ l = strlen (buffer); l ++; V [i] = malloc (sizeof (char) * l); strncpy (V[i], buffer, l); /* Debug */ if (DEBUG) syslog (LOG_DEBUG, "%i: %s\n", i, V[i]); i ++; } } /* Set the current max_urls */ (*max_urls) = i; return (error); } int main_loop (FILE *I, FILE *O, char **V, int max_urls, int buf_size, char *reject_url, int DEBUG) { int error, i; char *buffer, *qptr, *inputstr, *url; if (DEBUG) syslog (LOG_DEBUG, "Entering Main Loop"); error = E_OK; buffer = malloc (buf_size * sizeof (char)); inputstr = malloc (buf_size * sizeof (char)); url = malloc (buf_size * sizeof (char)); if (!buffer || !inputstr || !url) { syslog (LOG_ERR, "Error Allocating Buffer Memory"); return (E_INPUT); } while (!error && fgets_unlocked (buffer, buf_size -1, I)) { /* In case capture was exactly buf_size -1, no overflows */ buffer[buf_size -1] = '\0'; if (DEBUG) syslog (LOG_DEBUG, "Got Request %s", buffer); /* Find first space in string. That'll give the url. Magic? ;-) */ *(strchr (buffer, ' ')) = '\0'; /* Find a ? in the string */ qptr = strchr (buffer, '?'); if (qptr) { /* Querry, retrieve inputstr */ qptr ++; strncpy (inputstr, qptr, buf_size -1); /* Snip the inputstr from the url, after the ? */ *(qptr) = '\0'; } else { inputstr[0] = '\0'; } /* Try to find a match in the Valids array */ i = 0; while (i < max_urls && strcmp (V[i], buffer)) i ++; if (i < max_urls) { /* Match, validate the search string, syslog */ fprintf (O, "%s%s\n", V[i], inputstr); if (DEBUG) syslog (LOG_DEBUG, "Match Found: %i %s%s", i, V[i], inputstr); } else { /* No match, output reject */ fprintf (O, "%s\n", reject_url); if (DEBUG) syslog (LOG_DEBUG, "No Match Found"); } fflush (O); } return (error); } int main (int argc, char **argv) { int DEBUG, error, buf_size, max_urls; FILE *I, *O; /* Input, Output */ char **V; /* Valids */ char *url_file, *reject_url; /* Set some defaults */ DEBUG = D_NONE; error = E_OK; buf_size = DEF_BUFSIZE; max_urls = DEF_MAX_URLS; I = stdin; O = stdout; /* Setup the logging and debug */ if (!argv[0]) argv[0] = "jeanne"; if (DEBUG) openlog (argv[0], LOG_CONS|LOG_PERROR|LOG_PID, LOG_DAEMON); else openlog (argv[0], LOG_CONS|LOG_PID, LOG_DAEMON); /* Set defaults for the url filename and the reject url */ url_file = malloc (buf_size * sizeof (char)); reject_url = malloc (buf_size * sizeof (char)); if (!url_file || !reject_url) { syslog (LOG_ERR, "Error Allocating Memory"); return (E_NOMEM); } strncpy (url_file, DEF_URL_FILE, buf_size); strncpy (reject_url, DEF_REJECT_URL, buf_size); /* Get configuration */ error = get_config (); if (error) return (error); /* Create the array of pointers */ V = malloc (max_urls * sizeof (char*)); if (!V) { syslog (LOG_ERR, "Error Allocating Memory"); return (E_NOMEM); } /* Get URLs, max_urls is reset here to indicate total retrieved */ error = get_urls (V, url_file, &max_urls, buf_size, DEBUG); if (error) return (error); /* Enter main loop */ error = main_loop (I, O, V, max_urls, buf_size, reject_url, DEBUG); if (error) return (error); return (error); }