"Fossies" - the Fresh Open Source Software Archive

Member "tcpproxy-2.0.0-beta15/config.c" (20 Mar 2007, 15019 Bytes) of package /linux/privat/old/tcpproxy-2.0.0-beta15.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "config.c" see the Fossies "Dox" file reference documentation.

    1 
    2 /*
    3 
    4     File: config.c
    5 
    6     Copyright (C) 2005  Wolfgang Zekoll  <wzk@quietsche-entchen.de>
    7   
    8     This software is free software; you can redistribute it and/or modify
    9     it under the terms of the GNU General Public License as published by
   10     the Free Software Foundation; either version 2 of the License, or
   11     (at your option) any later version.
   12   
   13     This program is distributed in the hope that it will be useful,
   14     but WITHOUT ANY WARRANTY; without even the implied warranty of
   15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16     GNU General Public License for more details.
   17   
   18     You should have received a copy of the GNU General Public License
   19     along with this program; if not, write to the Free Software
   20     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   21 
   22  */
   23 
   24 
   25 
   26 #include <stdlib.h>
   27 #include <stdio.h>
   28 #include <string.h>
   29 #include <unistd.h>
   30 
   31 #include <errno.h>
   32 #include <ctype.h>
   33 #include <pwd.h>
   34 #include <grp.h>
   35 
   36 
   37 #include "lib.h"
   38 #include "ip-lib.h"
   39 #include "procinfo.h"
   40 #include "tcpproxy.h"
   41 
   42 
   43 proxy_t *new_configuration(config_t *config, proxy_t *def)
   44 {
   45     proxy_t *x;
   46 
   47     x = allocate(sizeof(proxy_t));
   48     if (def != NULL)
   49         memmove(x, def, sizeof(proxy_t));
   50 
   51     if (config->first == NULL) {
   52         config->first = x;
   53         config->last  = x;
   54         }
   55     else {
   56         config->last->next = x;
   57         config->last = x;
   58         }
   59 
   60     config->proxy_count++;
   61     return (x);
   62 }
   63 
   64 proxy_t *find_configuration(config_t *config, char *interface, unsigned int port)
   65 {
   66     proxy_t *x, *global;
   67 
   68     global = NULL;
   69     x = config->first;
   70     while (x != NULL) {
   71         if (x->port == port) {
   72             if (*x->interface == 0  ||  strcmp(x->interface, "0.0.0.0") == 0)
   73                 global = x;
   74             else if (strcmp(x->interface, interface) == 0)
   75                 break;
   76             }
   77             
   78         x = x->next;
   79         }
   80 
   81     if (x == NULL) {
   82 
   83         /*
   84          * Check if we have a configuration for a matching
   85          * interface name.
   86          */
   87 
   88         x = config->first;
   89         while (x != NULL) {
   90             if (x->port == port  &&  isalpha(*x->interface)) {
   91                 char    ipnum[80];
   92 
   93                 if (get_phyint_addr(x->interface, ipnum, sizeof(ipnum)) < 0)
   94                     ;
   95                 else if (strcmp(interface, ipnum) == 0)
   96                     break;
   97                 }
   98 
   99             x = x->next;
  100             }
  101         }
  102 
  103     if (x == NULL  &&  global != NULL)
  104         x = global;
  105         
  106     return (x);
  107 }
  108 
  109 
  110 int _check_interface(proxy_t *x, char *par, char *filename, int lineno)
  111 {
  112     if (*x->interface == 0)
  113         printerror(1, "-ERR", "parameter requires proxy configuration: %s, %s:%d", par, filename, lineno);
  114 
  115     return (0);
  116 }
  117 
  118 int _check_proxytype(proxy_t *x, int lineno)
  119 {
  120     if (x->proxytype != 0) {
  121         printerror(ERR_STDERR, "-ERR", "line %d: service redefinition", lineno);
  122         exit (1);
  123         }
  124     
  125     return (0);
  126 }
  127 
  128 
  129 int addsrcip(proxy_t *x, char *par)
  130 {
  131     int k;
  132     char    ip[40];
  133 
  134 /*  if (x->proxytype == PROXY_PROGRAM)
  135  *      return (0);
  136  */
  137 
  138     copy_string(ip, par, sizeof(ip));
  139     if (x->srcip.count >= x->srcip.max) {
  140         x->srcip.max += 10;
  141         x->srcip.srcip = reallocate(x->srcip.srcip, x->srcip.max * sizeof(char *));
  142         }
  143 
  144     k = x->srcip.count++;
  145     x->srcip.srcip[k] = strdup(ip);
  146 
  147     return (0);
  148 }
  149 
  150 char *iptoa(unsigned long ip, char *str, int size)
  151 {
  152     unsigned char *p;
  153 
  154     p = (unsigned char *) &ip;
  155     snprintf (str, size-2, "%u.%u.%u.%u", p[3], p[2], p[1], p[0]);
  156 
  157     return (0);
  158 }
  159 
  160 int addsrc(proxy_t *x, char *ip, char *filename, int lineno)
  161 {
  162     int error;
  163     char    *p;
  164     unsigned long ipnum;
  165 
  166     ipnum = atoip(ip, &p, &error);
  167     if (error != 0)
  168         printerror(1, "-ERR", "error in IP number: %s, %s:%d", ip, filename, lineno);
  169 
  170 /* fprintf (stderr, "p= %s c= %d\n", p, *p); */
  171     if (*p == 0)
  172         addsrcip(x, ip);
  173     else if (*p == '-') {
  174         unsigned int i, start, end;
  175         unsigned long num;
  176         char    adr[20];
  177 
  178         p++;
  179         start = ipnum & 0xFF;
  180         end = strtoul(p, &p, 10) & 0xFF;
  181         if (*p != 0)
  182             printerror(1, "-ERR", "error in IP range: %s, %s:%d", ip, filename, lineno);
  183 
  184 /*      if (start > end) {
  185  *          i= end;
  186  *          end = start;
  187  *          start = i;
  188  *          }
  189  */
  190         for (i=start; i<=end; i++) {
  191             num = (ipnum & 0xFFFFFF00) | i;
  192             iptoa(num, adr, sizeof(adr));
  193             addsrcip(x, adr);
  194             }
  195         }
  196     else {
  197         printerror(1, "-ERR", "error in IP number: %s, %s:%d", ip, filename, lineno);
  198         }
  199 
  200     return (0);
  201 }
  202 
  203 
  204 
  205 
  206 #define printyesno(x, y)    (y != 0? printf ("%s: %s\n", x, (y == 0)? "no": "yes"): 0)
  207 #define printnum(x, y)      ((y > 0)? printf ("%s: %u\n", x, y): 0)
  208 #define printoct(x, y)      ((y > 0)? printf ("%s: %03o\n", x, y): 0)
  209 #define printstring(x, y)   ((y != NULL  &&  *y != 0)? printf("%s: %s\n", x, y): 0)
  210 
  211 
  212 static int check_parameter(char **from, char *par, char *filename, int lineno)
  213 {
  214     *from = skip_ws(*from);
  215     if (**from == 0)
  216         printerror(1, "-ERR", "missing parameter: %s, %s:%d", par, filename, lineno);
  217 
  218     return (0);
  219 }
  220 
  221 static int get_yesno(char **from, char *par, char *filename, int lineno)
  222 {
  223     char    word[80];
  224 
  225     if (**from == 0)
  226         printerror(1, "-ERR", "missing parameter: %s, %s:%d", par, filename, lineno);
  227 
  228     get_word(from, word, sizeof(word));
  229     if (strcmp(word, "yes") == 0)
  230         return (1);
  231     else if (strcmp(word, "no") == 0)
  232         return (0);
  233     else
  234         printerror(1, "-ERR", "bad parameter value: %s, parameter= %s, %s:%d", word, par, filename, lineno);
  235 
  236     return (0);
  237 }
  238 
  239 static char *get_wordpar(char **from, char *par, char *word, int size,
  240         char *filename, int lineno)
  241 {
  242     if (**from == 0)
  243         printerror(1, "-ERR", "missing parameter: %s, %s:%d", par, filename, lineno);
  244 
  245     get_word(from, word, size);
  246     if (strcmp(word, "-") == 0)
  247         *word = 0;
  248 
  249     *from = skip_ws(*from);
  250     if (**from != 0)
  251         printerror(1, "-ERR", "trailing characters: %s, parameter= %s, %s:%d", *from, par, filename, lineno);
  252 
  253     return (word);
  254 }
  255 
  256 static char *get_parameter(char **from, char *par, char *value, int size,
  257         char *filename, int lineno)
  258 {
  259     if (**from == 0)
  260         printerror(1, "-ERR", "missing parameter: %s, %s:%d", par, filename, lineno);
  261 
  262     copy_string(value, *from, size);
  263     if (strcmp(value, "-") == 0)
  264         *value = 0;
  265 
  266     return (value);
  267 }
  268 
  269 static long get_number(char **from, char *par, char *filename, int lineno)
  270 {
  271     long    num;
  272     char    *p, word[80];
  273 
  274     if (**from == 0)
  275         printerror(1, "-ERR", "missing parameter: %s, %s:%d", par, filename, lineno);
  276 
  277     get_word(from, word, sizeof(word));
  278     *from = skip_ws(*from);
  279     if (**from != 0)
  280         printerror(1, "-ERR", "bad number: %s, %s:%d", par, filename, lineno);
  281 
  282     num = strtol(word, &p, 10);
  283     if (*p != 0)
  284         printerror(1, "-ERR", "not a number: %s, parameter= %s, %s:%d", word, par, filename, lineno);
  285 
  286     return (num);
  287 }
  288 
  289 
  290 int set_redirmode(proxy_t *x, char *word, char *filename, int lineno)
  291 {
  292     if (strcmp(word, "none") == 0  ||  strcmp(word, "off") == 0  ||
  293         strcmp(word, "no") == 0) {
  294         x->redirmode = REDIR_NONE;
  295         }
  296     else if (strcmp(word, "accept") == 0  ||  strcmp(word, "redirect") == 0)
  297         x->redirmode = REDIR_ACCEPT;
  298     else if (strcmp(word, "forward") == 0)
  299         x->redirmode = REDIR_FORWARD;
  300     else if (strcmp(word, "forward-only") == 0)
  301         x->redirmode = REDIR_FORWARD_ONLY;
  302     else
  303         printerror(1, "-ERR", "bad keyword: %s, %s:%d", word, filename, lineno);
  304 
  305     return (0);
  306 }
  307 
  308 int set_username(proxy_t *x, char *username, char *filename, int lineno)
  309 {
  310     char    *p, *q, word[40];
  311     struct passwd *pw;
  312     struct group *gr;
  313 
  314     p = username;
  315     get_quoted(&p, '.', word, sizeof(word));
  316     if (isdigit(*word) != 0) {
  317         x->uid = strtoul(word, &q, 10);
  318         if (*q != 0)
  319             printerror(1, "-ERR", "bad user id: %s, %s:%d", word, filename, lineno);
  320         }
  321     else if (*word != 0) {
  322         if ((pw = getpwnam(word)) == NULL) {
  323             printerror(1, "-ERR", "can't read passwd entry: %s, error= %s",
  324                     word, strerror(errno));
  325             }
  326 
  327         x->uid = pw->pw_uid;
  328         if (*p == 0)
  329             x->gid = pw->pw_gid;
  330         }
  331 
  332     if (*p == '.') {
  333         p++;
  334         if (isdigit(*p) != 0) {
  335             x->gid = strtoul(p, &q, 10);
  336             if (*q != 0)
  337                 printerror(1, "-ERR", "bad group id: %s, %s:%d", p, filename, lineno);
  338             }
  339         else if (*p != 0) {
  340             if ((gr = getgrnam(p)) == NULL) {
  341                 printerror(1, "-ERR", "can't read group entry: %s, error= %s",
  342                         p, strerror(errno));
  343                 }
  344 
  345             x->gid = gr->gr_gid;
  346             }
  347         }
  348 
  349     return (0);
  350 }
  351 
  352 
  353 char *uncomma(char *string)
  354 {
  355     int c;
  356     char    *p;
  357 
  358     for (p = string; (c = *p) != 0; p++) {
  359         if (c == ',')
  360             *p = ' ';
  361         }
  362 
  363     p = skip_ws(string);
  364     return (p);
  365 }
  366 
  367 int read_configuration(config_t *config, char *filename)
  368 {
  369     int lineno;
  370     unsigned int port;
  371     char    *p, word[80], par[200], line[300];
  372     FILE    *fp;
  373     proxy_t *x;
  374 
  375     /*
  376      * Open and read the configuration file.
  377      */
  378      
  379     if ((fp = fopen(filename, "r")) == NULL)
  380         printerror(1, "-ERR", "can't read config file: %s, error= %s", filename, strerror(errno));
  381 
  382 
  383     /*
  384      * All parameters before the first `port' go into the default
  385      * configuration profile.
  386      */
  387 
  388     if (config->def == NULL)
  389         config->def = allocate(sizeof(proxy_t));
  390 
  391     x = config->def;
  392 
  393     
  394     lineno = 0;
  395     port   = 0;
  396     while (fgets(line, sizeof(line), fp) != NULL) {
  397         lineno++;
  398 
  399         p = skip_ws(noctrl(line));
  400         if (*p == 0  ||  *p == '#')
  401             continue;
  402 
  403         get_word(&p, word, sizeof(word));
  404         strlwr(word);
  405         p = skip_ws(p);
  406 
  407         /*
  408          * Global options
  409          */
  410          
  411         if (strcmp(word, "pidfile") == 0) {
  412             char    pidfile[200];
  413 
  414             get_wordpar(&p, word, pidfile, sizeof(pidfile), filename, lineno);
  415             setpidfile(pidfile);
  416             }
  417         else if (strcmp(word, "standalone") == 0)
  418             config->standalone = get_yesno(&p, word, filename, lineno);
  419         else if (strcmp(word, "logname") == 0) {
  420 
  421             /*
  422              * The logname can be configuration specific.
  423              */
  424 
  425             if (config->binds == 0)
  426                 get_parameter(&p, word, config->logname, sizeof(config->logname), filename, lineno);
  427             else
  428                 get_parameter(&p, word, x->logname, sizeof(x->logname), filename, lineno);
  429             }
  430 
  431 
  432         /*
  433          * Globale Vorgaben, bzw. Serviceparameter
  434          */
  435 
  436         else if (strcmp(word, "timeout") == 0) {
  437             x->timeout = get_number(&p, word, filename, lineno);
  438             if (x->timeout < 1)
  439                 x->timeout = 60;
  440             }
  441         else if (strcmp(word, "setenv") == 0) {
  442             get_parameter(&p, word, varname, sizeof(varname), filename, lineno);
  443             if (*varname == 0)
  444                 strcpy(varname, "PROXY_");
  445             }
  446         else if (strcmp(word, "acp") == 0)
  447             get_parameter(&p, word, x->acp, sizeof(x->acp), filename, lineno);
  448         else if (strcmp(word, "ctp") == 0)
  449             get_parameter(&p, word, x->ctp, sizeof(x->ctp), filename, lineno);
  450 
  451 
  452         /*
  453          * For compatibility, use new `user' option instead.
  454          */
  455 
  456         else if (strcmp(word, "uid") == 0)
  457             x->uid = get_number(&p, word, filename, lineno);
  458         else if (strcmp(word, "gid") == 0)
  459             x->gid = get_number(&p, word, filename, lineno);
  460 
  461         else if (strcmp(word, "user") == 0) {
  462             char    username[40];
  463 
  464             get_wordpar(&p, word, username, sizeof(username), filename, lineno);
  465             set_username(x, username, filename, lineno);
  466             }
  467 
  468         /*
  469          * server configuration
  470          */
  471          
  472         else if (strcmp(word, "port") == 0  ||  strcmp(word, "bind") == 0) {
  473             char    portname[40];
  474 
  475             if (config->binds >= MAX_PORT)
  476                 printerror(1, "-ERR", "too many ports %s:%d", filename, lineno);
  477 
  478             get_wordpar(&p, "word", portname, sizeof(portname), filename, lineno);
  479             port = getportnum(portname);
  480 
  481             /*
  482              * The bindport computation is done before we bind
  483              * to the ports.
  484              * 
  485              * config->bindport[config->binds].port  = port;
  486              * config->bindport[config->binds].count = 0;
  487              * config->binds++;
  488              */
  489             }
  490         else if (strcmp(word, "interface") == 0) {
  491 /*          if (config->binds == 0  ||  port == 0) */
  492             if (port == 0)
  493                 printerror(1, "-ERR", "no port specification: %s:%d", filename, lineno);
  494 
  495             x = new_configuration(config, config->def);
  496             x->port = port;
  497             get_wordpar(&p, word, x->interface, sizeof(x->interface), filename, lineno);
  498             if (strcmp(x->interface, "*") == 0  ||  strcmp(x->interface, "any") == 0)
  499                 strcpy(x->interface, "0.0.0.0");
  500             else if (isalpha(*x->interface) != 0) {
  501 
  502                 /*
  503                  * An interface name.  Check if this interface exists.
  504                  */
  505 
  506                 }
  507 
  508             /*
  509              * This is now done before we bind to the configured
  510              * ports.
  511              *
  512              * copy_string(config->bindport[config->binds - 1].ip, x->interface, sizeof(config->bindport[config->binds - 1].ip));
  513              * config->bindport[config->binds - 1].count++;
  514              */
  515             }
  516         else if (strcmp(word, "server") == 0) {
  517             _check_interface(x, word, filename, lineno);
  518 
  519             get_parameter(&p, word, x->server, sizeof(x->server), filename, lineno);
  520             if (*x->server == '/')
  521                 printerror(1, "-ERR", "bad server specification: %s", x->server);
  522             }
  523         else if (strcmp(word, "srcip") == 0) {
  524             char    ipnum[40];
  525 
  526             _check_interface(x, word, filename, lineno);
  527 
  528             get_wordpar(&p, word, ipnum, sizeof(ipnum), filename, lineno);
  529             addsrcip(x, ipnum);
  530             }
  531         else if (strcmp(word, "rotate") == 0) {
  532             _check_interface(x, word, filename, lineno);
  533 
  534             check_parameter(&p, word, filename, lineno);
  535             while (*get_word(&p, word, sizeof(word)) != 0)
  536                 addsrc(x, word, filename, lineno);
  537             }
  538         else if (strcmp(word, "exec") == 0) {
  539             _check_interface(x, word, filename, lineno);
  540 
  541             x->proxytype = PROXY_PROGRAM;
  542             get_parameter(&p, word, x->server, sizeof(x->server), filename, lineno);
  543             if (*x->server != '/')
  544                 printerror(1, "-ERR", "bad program specification: %s", x->server);
  545             }
  546         else if (strcmp(word, "writefile") == 0  ||  strcmp(word, "debug") == 0) {
  547             _check_interface(x, word, filename, lineno);
  548             get_wordpar(&p, word, x->writefile, sizeof(x->writefile), filename, lineno);
  549             if (strcmp(word, "debug") == 0)
  550                 debug = 1;
  551             }
  552 
  553         else if (strcmp(word, "redirect-mode") == 0) {
  554             char    type[40];
  555 
  556             get_wordpar(&p, word, type, sizeof(type), filename, lineno);
  557             set_redirmode(x, type, filename, lineno);
  558             }
  559         else if (strcmp(word, "acl") == 0) {
  560             char    acl[200];
  561 
  562             get_parameter(&p, word, acl, sizeof(acl), filename, lineno);
  563             if (*(p = acl) == '=') {
  564                 p++;
  565                 clearstr(&x->acl);
  566                 }
  567 
  568             p = skip_ws(p);
  569             append(&x->acl, x->acl.len > 0? " ": "", p);
  570             }
  571         else if (strcmp(word, "statdir") == 0)
  572             get_wordpar(&p, word, statdir, sizeof(statdir), filename, lineno);
  573 
  574         else if (strcmp(word, "name") == 0)
  575             get_wordpar(&p, word, x->name, sizeof(x->name), filename, lineno);
  576 
  577         else if (strcmp(word, "extended-info") == 0)
  578             x->extendedinfo = get_yesno(&p, word, filename, lineno);
  579 
  580         else if (strcmp(word, "sessiondir") == 0)
  581             get_wordpar(&p, word, sessiondir, sizeof(sessiondir), filename, lineno);
  582         else if (strcmp(word, "session-mode") == 0) {
  583             char    mode[40];
  584 
  585             get_wordpar(&p, word, mode, sizeof(mode), filename, lineno);
  586             set_sessionmode(mode, filename, lineno);
  587             }
  588         else if (strcmp(word, "exit-handler") == 0  ||  strcmp(word, "error-handler") == 0) {
  589             get_parameter(&p, word, par, sizeof(par), filename, lineno);
  590             set_exithandler(par);
  591             }
  592         else if (strcmp(word, "exit-codes") == 0  ||  strcmp(word, "error-types") == 0) {
  593             unsigned int error, mask;
  594             char    list[200];
  595 
  596             get_parameter(&p, word, list, sizeof(list), filename, lineno);
  597             p = uncomma(list);
  598             mask = 0;
  599             while (*get_word(&p, word, sizeof(word)) != 0) {
  600                 error = geterrcode(word);
  601                 if (error == 0)
  602                     printerror(0 | ERR_INFO, "-INFO", "bad keyword: %s, %s:%d", word, filename, lineno);
  603                 else if (error == 1)
  604                     mask = 0;
  605                 else
  606                     mask |= error;
  607 
  608                 set_exitcodes(mask);
  609                 }
  610             }
  611 
  612         else {
  613             printerror(ERR_STDERR, "-ERR", "line %d: unkown configuration directive %s", lineno, word);
  614             exit (1);
  615             }
  616         }
  617 
  618     fclose (fp);
  619     return (0);
  620 }
  621 
  622