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

Revision 799, 19.9 KB (checked in by aprilp, 8 years ago)

* Ability to run wifidog without an auth server (splash only).
* Does not allow (yet) to specify a custom splash/disclaimer, but will
forward to the portal of your choice if specified in the config (or
a generic one if none is specified).
Of course, using wifidog without an authentication server will not give
you statistics and all the rest of the cool features.

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