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

Revision 176, 9.4 KB (checked in by alexcv, 9 years ago)

WiFiDog will now read multiple AuthServer? line in the config file but it
will only use the first one.

  • 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 <string.h>
34
35#include "common.h"
36
37#include "debug.h"
38#include "conf.h"
39#include "http.h"
40#include "auth.h"
41
42/** @internal
43 * Holds the current configuration of the gateway */
44static s_config config;
45
46/** @internal
47 * A flag.  If set to 1, there are missing or empty mandatory parameters in the config
48 */
49static int missing_parms;
50
51/** @internal
52 The different configuration options */
53typedef enum {
54        oBadOption,
55        oDaemon,
56        oDebugLevel,
57        oExternalInterface,
58        oGatewayID,
59        oGatewayInterface,
60        oGatewayAddress,
61        oGatewayPort,
62        oAuthServer,
63        oAuthservPath,
64        oAuthservLoginUrl,
65        oHTTPDMaxConn,
66        oHTTPDName,
67        oClientTimeout,
68        oCheckInterval,
69        oWdctlSocket,
70        oSyslogFacility
71} OpCodes;
72
73/** @internal
74 The config file keywords for the different configuration options */
75static const struct {
76        const char *name;
77        OpCodes opcode;
78        int required;
79} keywords[] = {
80        { "daemon",             oDaemon },
81        { "debuglevel",         oDebugLevel },
82        { "externalinterface",  oExternalInterface },
83        { "gatewayid",          oGatewayID },
84        { "gatewayinterface",   oGatewayInterface },
85        { "gatewayaddress",     oGatewayAddress },
86        { "gatewayport",        oGatewayPort },
87        { "authserver",         oAuthServer },
88        { "authservpath",       oAuthservPath },
89        { "authservloginurl",   oAuthservLoginUrl },
90        { "httpdmaxconn",       oHTTPDMaxConn },
91        { "httpdname",          oHTTPDName },
92        { "clienttimeout",      oClientTimeout },
93        { "checkinterval",      oCheckInterval },
94        { "syslogfacility",     oSyslogFacility },
95        { "wdctlsocket",        oWdctlSocket },
96        { NULL,                 oBadOption },
97};
98
99static OpCodes config_parse_token(const char *cp, const char *filename, int linenum);
100static void config_notnull(void *parm, char *parmname);
101static int parse_boolean_value(char *);
102static void new_auth_server(char *, int);
103
104/** Accessor for the current gateway configuration
105@return:  A pointer to the current config.  The pointer isn't opaque, but should be treated as READ-ONLY
106 */
107s_config *
108config_get_config(void)
109{
110    return &config;
111}
112
113/** Sets the default config parameters and initialises the configuration system */
114void
115config_init(void)
116{
117        debug(LOG_DEBUG, "Setting default config parameters");
118        strncpy(config.configfile, DEFAULT_CONFIGFILE, sizeof(config.configfile));
119        config.debuglevel = DEFAULT_DEBUGLEVEL;
120        config.httpdmaxconn = DEFAULT_HTTPDMAXCONN;
121        config.external_interface = NULL;
122        config.gw_id = DEFAULT_GATEWAYID;
123        config.gw_interface = NULL;
124        config.gw_address = NULL;
125        config.gw_port = DEFAULT_GATEWAYPORT;
126        config.auth_servers = NULL;
127        config.authserv_path = strdup(DEFAULT_AUTHSERVPATH);
128        config.authserv_loginurl = NULL;
129        config.httpdname = NULL;
130        config.clienttimeout = DEFAULT_CLIENTTIMEOUT;
131        config.checkinterval = DEFAULT_CHECKINTERVAL;
132        config.syslog_facility = DEFAULT_SYSLOG_FACILITY;
133        config.daemon = -1;
134        config.log_syslog = DEFAULT_LOG_SYSLOG;
135        config.wdctl_sock = strdup(DEFAULT_WDCTL_SOCK);
136}
137
138/**
139 * If the command-line didn't provide a config, use the default.
140 */
141void
142config_init_override(void)
143{
144    if (config.daemon == -1) config.daemon = DEFAULT_DAEMON;
145}
146
147/** @internal
148Parses a single token from the config file
149*/
150static OpCodes
151config_parse_token(const char *cp, const char *filename, int linenum)
152{
153        int i;
154
155        for (i = 0; keywords[i].name; i++)
156                if (strcasecmp(cp, keywords[i].name) == 0)
157                        return keywords[i].opcode;
158
159        debug(LOG_ERR, "%s: line %d: Bad configuration option: %s", 
160                        filename, linenum, cp);
161        return oBadOption;
162}
163
164/**
165@param filename Full path of the configuration file to be read
166*/
167void
168config_read(char *filename)
169{
170        FILE *fd;
171        char line[MAX_BUF], *s, *p1, *p2;
172        int linenum = 0, opcode, value;
173
174        debug(LOG_INFO, "Reading configuration file '%s'", filename);
175
176        if (!(fd = fopen(filename, "r"))) {
177                debug(LOG_ERR, "Could not open configuration file '%s', "
178                                "exiting...", filename);
179                exit(1);
180        }
181
182        while (!feof(fd) && fgets(line, MAX_BUF, fd)) {
183                s = line;
184
185                if (s[strlen(s) - 1] == '\n')
186                        s[strlen(s) - 1] = '\0';
187
188                if ((p1 = strchr(s, ' '))) {
189                        p1[0] = '\0';
190                } else if ((p1 = strchr(s, '\t'))) {
191                        p1[0] = '\0';
192                }
193
194                if (p1) {
195                        p1++;
196
197                        if ((p2 = strchr(p1, ' '))) {
198                                p2[0] = '\0';
199                        } else if ((p2 = strstr(p1, "\r\n"))) {
200                                p2[0] = '\0';
201                        } else if ((p2 = strchr(p1, '\n'))) {
202                                p2[0] = '\0';
203                        }
204                }
205
206                if (p1 && p1[0] != '\0') {
207                        /* Strip trailing spaces */
208                        /* Strip tailing spaces */
209
210                        if ((strncmp(s, "#", 1)) != 0) {
211                                debug(LOG_DEBUG, "Parsing token: %s, "
212                                                "value: %s", s, p1);
213                                opcode = config_parse_token(s, filename, linenum);
214
215                                switch(opcode) {
216                                case oDaemon:
217                                        if (config.daemon == -1 && ((value = parse_boolean_value(p1)) != -1)) {
218                                                config.daemon = value;
219                                        }
220                                        break;
221                                case oExternalInterface:
222                                        config.external_interface = strdup(p1);
223                                        break;
224                                case oGatewayID:
225                                        config.gw_id = strdup(p1);
226                                        break;
227                                case oGatewayInterface:
228                                        config.gw_interface = strdup(p1);
229                                        break;
230                                case oGatewayAddress:
231                                        config.gw_address = strdup(p1);
232                                        break;
233                                case oGatewayPort:
234                                        sscanf(p1, "%d", &config.gw_port);
235                                        break;
236                                case oAuthServer:
237                                        /* Check for the presence of more then
238                                         * one argument. */
239                                        if (p2 != NULL && (*(p2 + 1) != '\n')
240                                                       && (*(p2 + 1) != '\0')) {
241                                                p2++;
242                                                new_auth_server(p1, atoi(p2));
243                                        } else {
244                                                new_auth_server(p1, DEFAULT_AUTHSERVPORT);
245                                        }
246                                        break;
247                                case oHTTPDName:
248                                        config.httpdname = strdup(p1);
249                                        break;
250                                case oHTTPDMaxConn:
251                                        sscanf(p1, "%d", &config.httpdmaxconn);
252                                        break;
253                                case oAuthservPath:
254                                        free(config.authserv_path);
255                                        config.authserv_path = strdup(p1);
256                                        break;
257                                case oAuthservLoginUrl:
258                                        config.authserv_loginurl = strdup(p1);
259                                        break;
260                                case oBadOption:
261                    debug(LOG_ERR, "Exiting...");
262                                        exit(-1);
263                                        break;
264                                case oCheckInterval:
265                                        sscanf(p1, "%d", &config.checkinterval);
266                                        break;
267                                case oWdctlSocket:
268                                        free(config.wdctl_sock);
269                                        config.wdctl_sock = strdup(p1);
270                                        break;
271                                case oClientTimeout:
272                                        sscanf(p1, "%d", &config.clienttimeout);
273                                        break;
274                case oSyslogFacility:
275                                        sscanf(p1, "%d", &config.syslog_facility);
276                                        break;
277                                }
278                        }
279                }
280        }
281
282        fclose(fd);
283}
284
285/** @internal
286Parses a boolean value from the config file
287*/
288static int
289parse_boolean_value(char *line)
290{
291        if (strcasecmp(line, "yes") == 0) {
292                return 1;
293        }
294        if (strcasecmp(line, "no") == 0) {
295                return 0;
296        }
297        if (strcmp(line, "1") == 0) {
298                return 1;
299        }
300        if (strcmp(line, "0") == 0) {
301                return 0;
302        }
303
304        return -1;
305}
306
307/** Verifies if the configuration is complete and valid.  Terminates the program if it isn't */
308void
309config_validate(void)
310{
311        config_notnull(config.external_interface, "ExternalInterface");
312        config_notnull(config.gw_id, "GatewayID");
313        config_notnull(config.gw_interface, "GatewayInterface");
314        config_notnull(config.gw_address, "GatewayAddress");
315        config_notnull(config.auth_servers, "AuthServer");
316        config_notnull(config.authserv_loginurl, "AuthservLoginUrl");
317
318        if (missing_parms) {
319                debug(LOG_ERR, "Configuration is not complete, exiting...");
320                exit(-1);
321        }
322}
323
324/** @internal
325    Verifies that a required parameter is not a null pointer
326*/
327static void
328config_notnull(void *parm, char *parmname)
329{
330        if (parm == NULL) {
331                debug(LOG_ERR, "%s is not set", parmname);
332                missing_parms = 1;
333        }
334}
335
336/** @internal
337    Register a new auth server.
338*/
339static void
340new_auth_server(char *host, int port)
341{
342        t_auth_serv     *new, *tmp;
343
344        debug(LOG_DEBUG, "Adding %s:%d to the auth server list", host, port);
345
346        /* Allocate memory */
347        new = (t_auth_serv *)malloc(sizeof(t_auth_serv));
348        if (new == NULL) {
349                debug(LOG_ERR, "Could not allocate memory for auth server "
350                                "configuration");
351                exit(1);
352        }
353       
354        /* Fill in struct */
355        new->authserv_hostname = strdup(host);
356        new->authserv_port = port;
357        new->next = NULL;
358       
359        /* If it's the first, add to config, else append to last server */
360        if (config.auth_servers == NULL) {
361                config.auth_servers = new;
362        } else {
363                for (tmp = config.auth_servers; tmp->next != NULL;
364                                tmp = tmp->next);
365                tmp->next = new;
366        }
367       
368        debug(LOG_DEBUG, "Auth server added");
369}
Note: See TracBrowser for help on using the browser.