root/trunk/wifidog/src/conf.c @ 765

Revision 765, 19.8 KB (checked in by minaguib, 8 years ago)

Merged branch "wdctlrestart":

* New wdctl command "restart" which will get wifidog to restart itself while preserving the existing clientlist. Perfect for 0-downtime upgrading!
* safe.c: New safe_fork that croaks if the fork fails, also takes care of closing some global file descriptors for the child
* debug.c: Now also logs the PID as part of every entry
* gateway.c: Handler for SIGCHLD now waitpid()s with WNOHANG flag to prevent deadlock when the handler is called and another wait() or waitpid() is used
* util.c: execute() now uses waitpid() instead of wait() to reap only the child it fork/executed
* Extra debugging entries throughout code

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/********************************************************************\
2 * This program is free software; you can redistribute it and/or    *
3 * modify it under the terms of the GNU General Public License as   *
4 * published by the Free Software Foundation; either version 2 of   *
5 * the License, or (at your option) any later version.              *
6 *                                                                  *
7 * This program is distributed in the hope that it will be useful,  *
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
10 * GNU General Public License for more details.                     *
11 *                                                                  *
12 * You should have received a copy of the GNU General Public License*
13 * along with this program; if not, contact:                        *
14 *                                                                  *
15 * Free Software Foundation           Voice:  +1-617-542-5942       *
16 * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
17 * Boston, MA  02111-1307,  USA       gnu@gnu.org                   *
18 *                                                                  *
19 \********************************************************************/
20
21/* $Header$ */
22/** @file conf.c
23  @brief Config file parsing
24  @author Copyright (C) 2004 Philippe April <papril777@yahoo.com>
25 */
26
27#define _GNU_SOURCE
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <syslog.h>
32
33#include <pthread.h>
34
35#include <string.h>
36#include <ctype.h>
37
38#include "common.h"
39#include "safe.h"
40#include "debug.h"
41#include "conf.h"
42#include "http.h"
43#include "auth.h"
44#include "firewall.h"
45
46#include "util.h"
47
48/** @internal
49 * Holds the current configuration of the gateway */
50static s_config config;
51
52/**
53 * Mutex for the configuration file, used by the auth_servers related
54 * functions. */
55pthread_mutex_t config_mutex = PTHREAD_MUTEX_INITIALIZER;
56
57/** @internal
58 * A flag.  If set to 1, there are missing or empty mandatory parameters in the config
59 */
60static int missing_parms;
61
62/** @internal
63 The different configuration options */
64typedef enum {
65        oBadOption,
66        oDaemon,
67        oDebugLevel,
68        oExternalInterface,
69        oGatewayID,
70        oGatewayInterface,
71        oGatewayAddress,
72        oGatewayPort,
73        oAuthServer,
74        oAuthServHostname,
75        oAuthServSSLAvailable,
76        oAuthServSSLPort,
77        oAuthServHTTPPort,
78        oAuthServPath,
79        oAuthServMaxTries,
80        oHTTPDMaxConn,
81        oHTTPDName,
82        oClientTimeout,
83        oCheckInterval,
84        oWdctlSocket,
85        oSyslogFacility,
86        oFirewallRule,
87        oFirewallRuleSet,
88        oTrustedMACList
89} OpCodes;
90
91/** @internal
92 The config file keywords for the different configuration options */
93static const struct {
94        const char *name;
95        OpCodes opcode;
96        int required;
97} keywords[] = {
98        { "daemon",             oDaemon },
99        { "debuglevel",         oDebugLevel },
100        { "externalinterface",  oExternalInterface },
101        { "gatewayid",          oGatewayID },
102        { "gatewayinterface",   oGatewayInterface },
103        { "gatewayaddress",     oGatewayAddress },
104        { "gatewayport",        oGatewayPort },
105        { "authserver",         oAuthServer },
106        { "authservmaxtries",   oAuthServMaxTries },
107        { "httpdmaxconn",       oHTTPDMaxConn },
108        { "httpdname",          oHTTPDName },
109        { "clienttimeout",      oClientTimeout },
110        { "checkinterval",      oCheckInterval },
111        { "syslogfacility",     oSyslogFacility },
112        { "wdctlsocket",            oWdctlSocket },
113        { "hostname",               oAuthServHostname },
114        { "sslavailable",           oAuthServSSLAvailable },
115        { "sslport",                oAuthServSSLPort },
116        { "httpport",               oAuthServHTTPPort },
117        { "path",                       oAuthServPath },
118        { "firewallruleset",    oFirewallRuleSet },
119        { "firewallrule",           oFirewallRule },
120        { "trustedmaclist",         oTrustedMACList },
121        { NULL,                 oBadOption },
122};
123
124static OpCodes config_parse_token(const char *cp, const char *filename, int linenum);
125
126/** Accessor for the current gateway configuration
127@return:  A pointer to the current config.  The pointer isn't opaque, but should be treated as READ-ONLY
128 */
129s_config *
130config_get_config(void)
131{
132    return &config;
133}
134
135/** Sets the default config parameters and initialises the configuration system */
136void
137config_init(void)
138{
139        debug(LOG_DEBUG, "Setting default config parameters");
140        strncpy(config.configfile, DEFAULT_CONFIGFILE, sizeof(config.configfile));
141        config.debuglevel = DEFAULT_DEBUGLEVEL;
142        config.httpdmaxconn = DEFAULT_HTTPDMAXCONN;
143        config.external_interface = NULL;
144        config.gw_id = DEFAULT_GATEWAYID;
145        config.gw_interface = NULL;
146        config.gw_address = NULL;
147        config.gw_port = DEFAULT_GATEWAYPORT;
148        config.auth_servers = NULL;
149        config.authserv_maxtries = DEFAULT_AUTHSERVMAXTRIES;
150        config.httpdname = NULL;
151        config.clienttimeout = DEFAULT_CLIENTTIMEOUT;
152        config.checkinterval = DEFAULT_CHECKINTERVAL;
153        config.syslog_facility = DEFAULT_SYSLOG_FACILITY;
154        config.daemon = -1;
155        config.log_syslog = DEFAULT_LOG_SYSLOG;
156        config.wdctl_sock = safe_strdup(DEFAULT_WDCTL_SOCK);
157        config.internal_sock = safe_strdup(DEFAULT_INTERNAL_SOCK);
158        config.rulesets = NULL;
159        config.trustedmaclist = NULL;
160}
161
162/**
163 * If the command-line didn't provide a config, use the default.
164 */
165void
166config_init_override(void)
167{
168    if (config.daemon == -1) config.daemon = DEFAULT_DAEMON;
169}
170
171/** @internal
172Parses a single token from the config file
173*/
174static OpCodes
175config_parse_token(const char *cp, const char *filename, int linenum)
176{
177        int i;
178
179        for (i = 0; keywords[i].name; i++)
180                if (strcasecmp(cp, keywords[i].name) == 0)
181                        return keywords[i].opcode;
182
183        debug(LOG_ERR, "%s: line %d: Bad configuration option: %s", 
184                        filename, linenum, cp);
185        return oBadOption;
186}
187
188/** @internal
189Parses auth server information
190*/
191static void
192parse_auth_server(FILE *file, char *filename, int *linenum)
193{
194        char            *host = NULL,
195                        *path = NULL,
196                        line[MAX_BUF],
197                        *p1,
198                        *p2;
199        int             http_port,
200                        ssl_port,
201                        ssl_available,
202                        opcode;
203        t_auth_serv     *new,
204                        *tmp;
205
206        /* Defaults */
207        path = safe_strdup(DEFAULT_AUTHSERVPATH);
208        http_port = DEFAULT_AUTHSERVPORT;
209        ssl_port = DEFAULT_AUTHSERVSSLPORT;
210        ssl_available = DEFAULT_AUTHSERVSSLAVAILABLE;
211       
212        /* Read first line */   
213        memset(line, 0, MAX_BUF);
214        fgets(line, MAX_BUF - 1, file);
215        (*linenum)++; /* increment line counter. */
216
217        /* Parsing loop */
218        while ((line[0] != '\0') && (strchr(line, '}') == NULL)) {
219                /* skip leading blank spaces */
220                for (p1 = line; isblank(*p1); p1++);
221
222                /* End at end of line */
223                if ((p2 = strchr(p1, '#')) != NULL) {
224                        *p2 = '\0';
225                } else if ((p2 = strchr(p1, '\r')) != NULL) {
226                        *p2 = '\0';
227                } else if ((p2 = strchr(p1, '\n')) != NULL) {
228                        *p2 = '\0';
229                }
230
231                /* next, we coopt the parsing of the regular config */
232                if (strlen(p1) > 0) {
233                        p2 = p1;
234                        /* keep going until word boundary is found. */
235                        while ((*p2 != '\0') && (!isblank(*p2)))
236                                p2++;
237
238                        /* Terminate first word. */
239                        *p2 = '\0';
240                        p2++;
241
242                        /* skip all further blanks. */
243                        while (isblank(*p2))
244                                p2++;
245                       
246                        /* Get opcode */
247                        opcode = config_parse_token(p1, filename, *linenum);
248                       
249                        switch (opcode) {
250                                case oAuthServHostname:
251                                        host = safe_strdup(p2);
252                                        break;
253                                case oAuthServPath:
254                                        free(path);
255                                        path = safe_strdup(p2);
256                                        break;
257                                case oAuthServSSLPort:
258                                        ssl_port = atoi(p2);
259                                        break;
260                                case oAuthServHTTPPort:
261                                        http_port = atoi(p2);
262                                        break;
263                                case oAuthServSSLAvailable:
264                                        ssl_available = parse_boolean_value(p2);
265                                        if (ssl_available < 0)
266                                                ssl_available = 0;
267                                        break;
268                                case oBadOption:
269                                default:
270                                        debug(LOG_ERR, "Bad option on line %d "
271                                                        "in %s.", *linenum,
272                                                        filename);
273                                        debug(LOG_ERR, "Exiting...");
274                                        exit(-1);
275                                        break;
276                        }
277                }
278
279                /* Read next line */
280                memset(line, 0, MAX_BUF);
281                fgets(line, MAX_BUF - 1, file);
282                (*linenum)++; /* increment line counter. */
283        }
284
285        /* only proceed if we have an host and a path */
286        if (host == NULL)
287                return;
288       
289        debug(LOG_DEBUG, "Adding %s:%d (SSL: %d) %s to the auth server list",
290                        host, http_port, ssl_port, path);
291
292        /* Allocate memory */
293        new = safe_malloc(sizeof(t_auth_serv));
294       
295        /* Fill in struct */
296        memset(new, 0, sizeof(t_auth_serv)); /*< Fill all with NULL */
297        new->authserv_hostname = host;
298        new->authserv_use_ssl = ssl_available;
299        new->authserv_path = path;
300        new->authserv_http_port = http_port;
301        new->authserv_ssl_port = ssl_port;
302       
303        /* If it's the first, add to config, else append to last server */
304        if (config.auth_servers == NULL) {
305                config.auth_servers = new;
306        } else {
307                for (tmp = config.auth_servers; tmp->next != NULL;
308                                tmp = tmp->next);
309                tmp->next = new;
310        }
311       
312        debug(LOG_DEBUG, "Auth server added");
313}
314
315/**
316Advance to the next word
317@param s string to parse, this is the next_word pointer, the value of s
318         when the macro is called is the current word, after the macro
319         completes, s contains the beginning of the NEXT word, so you
320         need to save s to something else before doing TO_NEXT_WORD
321@param e should be 0 when calling TO_NEXT_WORD(), it'll be changed to 1
322         if the end of the string is reached.
323*/
324#define TO_NEXT_WORD(s, e) do { \
325        while (*s != '\0' && !isblank(*s)) { \
326                s++; \
327        } \
328        if (*s != '\0') { \
329                *s = '\0'; \
330                s++; \
331                while (isblank(*s)) \
332                        s++; \
333        } else { \
334                e = 1; \
335        } \
336} while (0)
337
338/** @internal
339Parses firewall rule set information
340*/
341static void
342parse_firewall_ruleset(char *ruleset, FILE *file, char *filename, int *linenum)
343{
344        char            line[MAX_BUF],
345                        *p1,
346                        *p2;
347        int             opcode;
348
349        debug(LOG_DEBUG, "Adding Firewall Rule Set %s", ruleset);
350       
351        /* Read first line */   
352        memset(line, 0, MAX_BUF);
353        fgets(line, MAX_BUF - 1, file);
354        (*linenum)++; /* increment line counter. */
355
356        /* Parsing loop */
357        while ((line[0] != '\0') && (strchr(line, '}') == NULL)) {
358                /* skip leading blank spaces */
359                for (p1 = line; isblank(*p1); p1++);
360
361                /* End at end of line */
362                if ((p2 = strchr(p1, '#')) != NULL) {
363                        *p2 = '\0';
364                } else if ((p2 = strchr(p1, '\r')) != NULL) {
365                        *p2 = '\0';
366                } else if ((p2 = strchr(p1, '\n')) != NULL) {
367                        *p2 = '\0';
368                }
369
370                /* next, we coopt the parsing of the regular config */
371                if (strlen(p1) > 0) {
372                        p2 = p1;
373                        /* keep going until word boundary is found. */
374                        while ((*p2 != '\0') && (!isblank(*p2)))
375                                p2++;
376
377                        /* Terminate first word. */
378                        *p2 = '\0';
379                        p2++;
380
381                        /* skip all further blanks. */
382                        while (isblank(*p2))
383                                p2++;
384                       
385                        /* Get opcode */
386                        opcode = config_parse_token(p1, filename, *linenum);
387
388                        debug(LOG_DEBUG, "p1 = [%s]; p2 = [%s]", p1, p2);
389                       
390                        switch (opcode) {
391                                case oFirewallRule:
392                                        parse_firewall_rule(ruleset, p2);
393                                        break;
394
395                                case oBadOption:
396                                default:
397                                        debug(LOG_ERR, "Bad option on line %d "
398                                                        "in %s.", *linenum,
399                                                        filename);
400                                        debug(LOG_ERR, "Exiting...");
401                                        exit(-1);
402                                        break;
403                        }
404                }
405
406                /* Read next line */
407                memset(line, 0, MAX_BUF);
408                fgets(line, MAX_BUF - 1, file);
409                (*linenum)++; /* increment line counter. */
410        }
411
412        debug(LOG_DEBUG, "Firewall Rule Set %s added.", ruleset);
413}
414
415static int
416parse_firewall_rule(char *ruleset, char *leftover)
417{
418        int i;
419        int block_allow = 0; /**< 0 == block, 1 == allow */
420        int all_nums = 1; /**< If 0, port contained non-numerics */
421        int finished = 0; /**< reached end of line */
422        char *token = NULL; /**< First word */
423        char *port = NULL; /**< port to open/block */
424        char *protocol = NULL; /**< protocol to block, tcp/udp/icmp */
425        char *mask = NULL; /**< Netmask */
426        char *other_kw = NULL; /**< other key word */
427        t_firewall_ruleset *tmpr;
428        t_firewall_ruleset *tmpr2;
429        t_firewall_rule *tmp;
430        t_firewall_rule *tmp2;
431
432        debug(LOG_DEBUG, "leftover: %s", leftover);
433
434        /* lower case */
435        for (i = 0; *(leftover + i) != '\0'
436                        && (*(leftover + i) = tolower(*(leftover + i))); i++);
437       
438        token = leftover;
439        TO_NEXT_WORD(leftover, finished);
440       
441        /* Parse token */
442        if (!strcasecmp(token, "block") || finished) {
443                block_allow = 0;
444        } else if (!strcasecmp(token, "allow")) {
445                block_allow = 1;
446        } else {
447                debug(LOG_ERR, "Invalid rule type %s, expecting "
448                                "\"block\" or \"allow\"", token);
449                return -1;
450        }
451
452        /* Parse the remainder */
453        /* Get the protocol */
454        if (strncmp(leftover, "tcp", 3) == 0
455                        || strncmp(leftover, "udp", 3) == 0
456                        || strncmp(leftover, "icmp", 4) == 0) {
457                protocol = leftover;
458                TO_NEXT_WORD(leftover, finished);
459        }
460
461        /* should be exactly "port" */
462        if (strncmp(leftover, "port", 4) == 0) {
463                TO_NEXT_WORD(leftover, finished);
464                /* Get port now */
465                port = leftover;
466                TO_NEXT_WORD(leftover, finished);
467                for (i = 0; *(port + i) != '\0'; i++)
468                        if (!isdigit(*(port + i)))
469                                all_nums = 0; /*< No longer only digits */
470                if (!all_nums) {
471                        debug(LOG_ERR, "Invalid port %s", port);
472                        return -3; /*< Fail */
473                }
474        }
475
476        /* Now, further stuff is optional */
477        if (!finished) {
478                /* should be exactly "to" */
479                other_kw = leftover;
480                TO_NEXT_WORD(leftover, finished);
481                if (strcmp(other_kw, "to") || finished) {
482                        debug(LOG_ERR, "Invalid or unexpected keyword %s, "
483                                        "expecting \"to\"", other_kw);
484                        return -4; /*< Fail */
485                }
486
487                /* Get port now */
488                mask = leftover;
489                TO_NEXT_WORD(leftover, finished);
490                all_nums = 1;
491                for (i = 0; *(mask + i) != '\0'; i++)
492                        if (!isdigit(*(mask + i)) && (*(mask + i) != '.')
493                                        && (*(mask + i) != '/'))
494                                all_nums = 0; /*< No longer only digits */
495                if (!all_nums) {
496                        debug(LOG_ERR, "Invalid mask %s", mask);
497                        return -3; /*< Fail */
498                }
499        }
500
501        /* Generate rule record */
502        tmp = safe_malloc(sizeof(t_firewall_rule));
503        memset((void *)tmp, 0, sizeof(t_firewall_rule));
504        tmp->block_allow = block_allow;
505        if (protocol != NULL)
506                tmp->protocol = safe_strdup(protocol);
507        if (port != NULL)
508                tmp->port = safe_strdup(port);
509        if (mask == NULL)
510                tmp->mask = safe_strdup("0.0.0.0/0");
511        else
512                tmp->mask = safe_strdup(mask);
513
514        debug(LOG_DEBUG, "Adding Firewall Rule %s %s port %s to %s", token, tmp->protocol, tmp->port, tmp->mask);
515       
516        /* Append the rule record */
517        if (config.rulesets == NULL) {
518                config.rulesets = safe_malloc(sizeof(t_firewall_ruleset));
519                memset(config.rulesets, 0, sizeof(t_firewall_ruleset));
520                config.rulesets->name = safe_strdup(ruleset);
521                tmpr = config.rulesets;
522        } else {
523                tmpr2 = tmpr = config.rulesets;
524                while (tmpr != NULL && (strcmp(tmpr->name, ruleset) != 0)) {
525                        tmpr2 = tmpr;
526                        tmpr = tmpr->next;
527                }
528                if (tmpr == NULL) {
529                        /* Rule did not exist */
530                        tmpr = safe_malloc(sizeof(t_firewall_ruleset));
531                        memset(tmpr, 0, sizeof(t_firewall_ruleset));
532                        tmpr->name = safe_strdup(ruleset);
533                        tmpr2->next = tmpr;
534                }
535        }
536
537        /* At this point, tmpr == current ruleset */
538        if (tmpr->rules == NULL) {
539                /* No rules... */
540                tmpr->rules = tmp;
541        } else {
542                tmp2 = tmpr->rules;
543                while (tmp2->next != NULL)
544                        tmp2 = tmp2->next;
545                tmp2->next = tmp;
546        }
547       
548        return 1;
549}
550
551t_firewall_rule *
552get_ruleset(char *ruleset)
553{
554        t_firewall_ruleset      *tmp;
555
556        for (tmp = config.rulesets; tmp != NULL
557                        && strcmp(tmp->name, ruleset) != 0; tmp = tmp->next);
558
559        if (tmp == NULL)
560                return NULL;
561
562        return(tmp->rules);
563}
564
565/**
566@param filename Full path of the configuration file to be read
567*/
568void
569config_read(char *filename)
570{
571        FILE *fd;
572        char line[MAX_BUF], *s, *p1, *p2;
573        int linenum = 0, opcode, value;
574
575        debug(LOG_INFO, "Reading configuration file '%s'", filename);
576
577        if (!(fd = fopen(filename, "r"))) {
578                debug(LOG_ERR, "Could not open configuration file '%s', "
579                                "exiting...", filename);
580                exit(1);
581        }
582
583        while (!feof(fd) && fgets(line, MAX_BUF, fd)) {
584                linenum++;
585                s = line;
586
587                if (s[strlen(s) - 1] == '\n')
588                        s[strlen(s) - 1] = '\0';
589
590                if ((p1 = strchr(s, ' '))) {
591                        p1[0] = '\0';
592                } else if ((p1 = strchr(s, '\t'))) {
593                        p1[0] = '\0';
594                }
595
596                if (p1) {
597                        p1++;
598
599                        if ((p2 = strchr(p1, ' '))) {
600                                p2[0] = '\0';
601                        } else if ((p2 = strstr(p1, "\r\n"))) {
602                                p2[0] = '\0';
603                        } else if ((p2 = strchr(p1, '\n'))) {
604                                p2[0] = '\0';
605                        }
606                }
607
608                if (p1 && p1[0] != '\0') {
609                        /* Strip trailing spaces */
610                        /* Strip tailing spaces */
611
612                        if ((strncmp(s, "#", 1)) != 0) {
613                                debug(LOG_DEBUG, "Parsing token: %s, "
614                                                "value: %s", s, p1);
615                                opcode = config_parse_token(s, filename, linenum);
616
617                                switch(opcode) {
618                                case oDaemon:
619                                        if (config.daemon == -1 && ((value = parse_boolean_value(p1)) != -1)) {
620                                                config.daemon = value;
621                                        }
622                                        break;
623                                case oExternalInterface:
624                                        config.external_interface = safe_strdup(p1);
625                                        break;
626                                case oGatewayID:
627                                        config.gw_id = safe_strdup(p1);
628                                        break;
629                                case oGatewayInterface:
630                                        config.gw_interface = safe_strdup(p1);
631                                        break;
632                                case oGatewayAddress:
633                                        config.gw_address = safe_strdup(p1);
634                                        break;
635                                case oGatewayPort:
636                                        sscanf(p1, "%d", &config.gw_port);
637                                        break;
638                                case oAuthServer:
639                                        parse_auth_server(fd, filename,
640                                                        &linenum);
641                                        break;
642                                case oFirewallRuleSet:
643                                        parse_firewall_ruleset(p1, fd, filename, &linenum);
644                                        break;
645                                case oTrustedMACList:
646                                        parse_trusted_mac_list(p1);
647                                        break;
648                                case oHTTPDName:
649                                        config.httpdname = safe_strdup(p1);
650                                        break;
651                                case oHTTPDMaxConn:
652                                        sscanf(p1, "%d", &config.httpdmaxconn);
653                                        break;
654                                case oAuthServMaxTries:
655                                        sscanf(p1, "%d", &config.authserv_maxtries);
656                                        break;
657                                case oBadOption:
658                                        debug(LOG_ERR, "Bad option on line %d "
659                                                        "in %s.", linenum,
660                                                        filename);
661                                        debug(LOG_ERR, "Exiting...");
662                                        exit(-1);
663                                        break;
664                                case oCheckInterval:
665                                        sscanf(p1, "%d", &config.checkinterval);
666                                        break;
667                                case oWdctlSocket:
668                                        free(config.wdctl_sock);
669                                        config.wdctl_sock = safe_strdup(p1);
670                                        break;
671                                case oClientTimeout:
672                                        sscanf(p1, "%d", &config.clienttimeout);
673                                        break;
674                                case oSyslogFacility:
675                                        sscanf(p1, "%d", &config.syslog_facility);
676                                        break;
677                                }
678                        }
679                }
680        }
681
682        fclose(fd);
683}
684
685/** @internal
686Parses a boolean value from the config file
687*/
688static int
689parse_boolean_value(char *line)
690{
691        if (strcasecmp(line, "yes") == 0) {
692                return 1;
693        }
694        if (strcasecmp(line, "no") == 0) {
695                return 0;
696        }
697        if (strcmp(line, "1") == 0) {
698                return 1;
699        }
700        if (strcmp(line, "0") == 0) {
701                return 0;
702        }
703
704        return -1;
705}
706
707void parse_trusted_mac_list(char *ptr) {
708        char *ptrcopy = NULL;
709        char *possiblemac = NULL;
710        char *mac = NULL;
711        t_trusted_mac *p = NULL;
712
713        debug(LOG_DEBUG, "Parsing string [%s] for trusted MAC addresses", ptr);
714
715        mac = safe_malloc(18);
716
717        /* strsep modifies original, so let's make a copy */
718        ptrcopy = safe_strdup(ptr);
719
720        while ((possiblemac = strsep(&ptrcopy, ", "))) {
721                if (sscanf(possiblemac, " %17[A-Fa-f0-9:]", mac) == 1) {
722                        /* Copy mac to the list */
723
724                        debug(LOG_DEBUG, "Adding MAC address [%s] to trusted list", mac);
725
726                        if (config.trustedmaclist == NULL) {
727                                config.trustedmaclist = safe_malloc(sizeof(t_trusted_mac));
728                                config.trustedmaclist->mac = safe_strdup(mac);
729                                config.trustedmaclist->next = NULL;
730                        }
731                        else {
732                                /* Advance to the last entry */
733                                for (p = config.trustedmaclist; p->next != NULL; p = p->next);
734                                p->next = safe_malloc(sizeof(t_trusted_mac));
735                                p = p->next;
736                                p->mac = safe_strdup(mac);
737                                p->next = NULL;
738                        }
739
740                }
741        }
742
743        free(ptrcopy);
744
745        free(mac);
746
747}
748
749/** Verifies if the configuration is complete and valid.  Terminates the program if it isn't */
750void
751config_validate(void)
752{
753        config_notnull(config.gw_interface, "GatewayInterface");
754        config_notnull(config.auth_servers, "AuthServer");
755
756        if (missing_parms) {
757                debug(LOG_ERR, "Configuration is not complete, exiting...");
758                exit(-1);
759        }
760}
761
762/** @internal
763    Verifies that a required parameter is not a null pointer
764*/
765static void
766config_notnull(void *parm, char *parmname)
767{
768        if (parm == NULL) {
769                debug(LOG_ERR, "%s is not set", parmname);
770                missing_parms = 1;
771        }
772}
773
774/**
775 * This function returns the current (first auth_server)
776 */
777t_auth_serv *
778get_auth_server(void)
779{
780
781        /* This is as good as atomic */
782        return config.auth_servers;
783}
784
785/**
786 * This function marks the current auth_server, if it matches the argument,
787 * as bad. Basically, the "bad" server becomes the last one on the list.
788 */
789void
790mark_auth_server_bad(t_auth_serv *bad_server)
791{
792        t_auth_serv     *tmp;
793
794        if (config.auth_servers == bad_server && bad_server->next != NULL) {
795                /* Go to the last */
796                for (tmp = config.auth_servers; tmp->next != NULL; tmp = tmp->next);
797                /* Set bad server as last */
798                tmp->next = bad_server;
799                /* Remove bad server from start of list */
800                config.auth_servers = bad_server->next;
801                /* Set the next pointe to NULL in the last element */
802                bad_server->next = NULL;
803        }
804
805}
Note: See TracBrowser for help on using the browser.