157e22627SCy Schubert /*
257e22627SCy Schubert * Copyright (c) 1987, 1993, 1994
357e22627SCy Schubert * The Regents of the University of California. All rights reserved.
457e22627SCy Schubert *
557e22627SCy Schubert * Redistribution and use in source and binary forms, with or without
657e22627SCy Schubert * modification, are permitted provided that the following conditions
757e22627SCy Schubert * are met:
857e22627SCy Schubert * 1. Redistributions of source code must retain the above copyright
957e22627SCy Schubert * notice, this list of conditions and the following disclaimer.
1057e22627SCy Schubert * 2. Redistributions in binary form must reproduce the above copyright
1157e22627SCy Schubert * notice, this list of conditions and the following disclaimer in the
1257e22627SCy Schubert * documentation and/or other materials provided with the distribution.
1357e22627SCy Schubert * 3. All advertising materials mentioning features or use of this software
1457e22627SCy Schubert * must display the following acknowledgement:
1557e22627SCy Schubert * This product includes software developed by the University of
1657e22627SCy Schubert * California, Berkeley and its contributors.
1757e22627SCy Schubert * 4. Neither the name of the University nor the names of its contributors
1857e22627SCy Schubert * may be used to endorse or promote products derived from this software
1957e22627SCy Schubert * without specific prior written permission.
2057e22627SCy Schubert *
2157e22627SCy Schubert * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2257e22627SCy Schubert * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2357e22627SCy Schubert * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2457e22627SCy Schubert * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2557e22627SCy Schubert * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2657e22627SCy Schubert * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2757e22627SCy Schubert * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2857e22627SCy Schubert * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2957e22627SCy Schubert * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3057e22627SCy Schubert * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3157e22627SCy Schubert * SUCH DAMAGE.
3257e22627SCy Schubert */
3357e22627SCy Schubert
3457e22627SCy Schubert #include <config.h>
3557e22627SCy Schubert
3657e22627SCy Schubert #include "ftmacros.h"
3757e22627SCy Schubert
3857e22627SCy Schubert #include <stdio.h>
3957e22627SCy Schubert #include <string.h>
4057e22627SCy Schubert #include <signal.h>
4157e22627SCy Schubert #include <pcap.h> // for PCAP_ERRBUF_SIZE
4257e22627SCy Schubert
4357e22627SCy Schubert #include "portability.h"
4457e22627SCy Schubert #include "rpcapd.h"
4557e22627SCy Schubert #include "config_params.h" // configuration file parameters
4657e22627SCy Schubert #include "fileconf.h"
4757e22627SCy Schubert #include "rpcap-protocol.h"
4857e22627SCy Schubert #include "log.h"
4957e22627SCy Schubert
5057e22627SCy Schubert //
5157e22627SCy Schubert // Parameter names.
5257e22627SCy Schubert //
5357e22627SCy Schubert #define PARAM_ACTIVECLIENT "ActiveClient"
5457e22627SCy Schubert #define PARAM_PASSIVECLIENT "PassiveClient"
5557e22627SCy Schubert #define PARAM_NULLAUTHPERMIT "NullAuthPermit"
5657e22627SCy Schubert
5757e22627SCy Schubert static char *skipws(char *ptr);
5857e22627SCy Schubert
596f9cba8fSJoseph Mingrone /*
606f9cba8fSJoseph Mingrone * Locale-independent version checks for alphabetical and alphanumerical
616f9cba8fSJoseph Mingrone * characters that also can handle being handed a char value that might
626f9cba8fSJoseph Mingrone * be negative.
636f9cba8fSJoseph Mingrone */
646f9cba8fSJoseph Mingrone #define FILECONF_ISALPHA(c) \
656f9cba8fSJoseph Mingrone (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
666f9cba8fSJoseph Mingrone #define FILECONF_ISALNUM(c) \
676f9cba8fSJoseph Mingrone (FILECONF_ISALPHA(c) || ((c) >= '0' && (c) <= '9'))
686f9cba8fSJoseph Mingrone
fileconf_read(void)6957e22627SCy Schubert void fileconf_read(void)
7057e22627SCy Schubert {
7157e22627SCy Schubert FILE *fp;
7257e22627SCy Schubert unsigned int num_active_clients;
7357e22627SCy Schubert
7457e22627SCy Schubert if ((fp = fopen(loadfile, "r")) != NULL)
7557e22627SCy Schubert {
7657e22627SCy Schubert char line[MAX_LINE + 1];
7757e22627SCy Schubert unsigned int lineno;
7857e22627SCy Schubert
7957e22627SCy Schubert hostlist[0] = 0;
8057e22627SCy Schubert num_active_clients = 0;
8157e22627SCy Schubert lineno = 0;
8257e22627SCy Schubert
8357e22627SCy Schubert while (fgets(line, MAX_LINE, fp) != NULL)
8457e22627SCy Schubert {
8557e22627SCy Schubert size_t linelen;
8657e22627SCy Schubert char *ptr;
8757e22627SCy Schubert char *param;
8857e22627SCy Schubert size_t result;
8957e22627SCy Schubert size_t toklen;
9057e22627SCy Schubert
9157e22627SCy Schubert lineno++;
9257e22627SCy Schubert
9357e22627SCy Schubert linelen = strlen(line);
9457e22627SCy Schubert if (line[linelen - 1] != '\n')
9557e22627SCy Schubert {
9657e22627SCy Schubert int c;
9757e22627SCy Schubert
9857e22627SCy Schubert //
9957e22627SCy Schubert // Either the line doesn't fit in
10057e22627SCy Schubert // the buffer, or we got an EOF
10157e22627SCy Schubert // before the EOL. Assume it's the
10257e22627SCy Schubert // former.
10357e22627SCy Schubert //
10457e22627SCy Schubert rpcapd_log(LOGPRIO_ERROR,
10557e22627SCy Schubert "%s, line %u is longer than %u characters",
10657e22627SCy Schubert loadfile, lineno, MAX_LINE);
10757e22627SCy Schubert
10857e22627SCy Schubert //
10957e22627SCy Schubert // Eat characters until we get an NL.
11057e22627SCy Schubert //
11157e22627SCy Schubert while ((c = getc(fp)) != '\n')
11257e22627SCy Schubert {
11357e22627SCy Schubert if (c == EOF)
11457e22627SCy Schubert goto done;
11557e22627SCy Schubert }
11657e22627SCy Schubert
11757e22627SCy Schubert //
11857e22627SCy Schubert // Try the next line.
11957e22627SCy Schubert //
12057e22627SCy Schubert continue;
12157e22627SCy Schubert }
12257e22627SCy Schubert ptr = line;
12357e22627SCy Schubert
12457e22627SCy Schubert //
12557e22627SCy Schubert // Skip leading white space, if any.
12657e22627SCy Schubert //
12757e22627SCy Schubert ptr = skipws(ptr);
12857e22627SCy Schubert if (ptr == NULL)
12957e22627SCy Schubert {
13057e22627SCy Schubert // Blank line.
13157e22627SCy Schubert continue;
13257e22627SCy Schubert }
13357e22627SCy Schubert
13457e22627SCy Schubert //
13557e22627SCy Schubert // Is the next character a "#"? If so, this
13657e22627SCy Schubert // line is a comment; skip to the next line.
13757e22627SCy Schubert //
13857e22627SCy Schubert if (*ptr == '#')
13957e22627SCy Schubert continue;
14057e22627SCy Schubert
14157e22627SCy Schubert //
14257e22627SCy Schubert // Is the next character alphabetic? If not,
14357e22627SCy Schubert // this isn't a valid parameter name.
14457e22627SCy Schubert //
1456f9cba8fSJoseph Mingrone if (FILECONF_ISALPHA(*ptr))
14657e22627SCy Schubert {
14757e22627SCy Schubert rpcapd_log(LOGPRIO_ERROR,
14857e22627SCy Schubert "%s, line %u doesn't have a valid parameter name",
14957e22627SCy Schubert loadfile, lineno);
15057e22627SCy Schubert continue;
15157e22627SCy Schubert }
15257e22627SCy Schubert
15357e22627SCy Schubert //
15457e22627SCy Schubert // Grab the first token, which is made of
15557e22627SCy Schubert // alphanumerics, underscores, and hyphens.
15657e22627SCy Schubert // That's the name of the parameter being set.
15757e22627SCy Schubert //
15857e22627SCy Schubert param = ptr;
1596f9cba8fSJoseph Mingrone while (FILECONF_ISALNUM(*ptr) || *ptr == '-' || *ptr == '_')
16057e22627SCy Schubert ptr++;
16157e22627SCy Schubert
16257e22627SCy Schubert //
16357e22627SCy Schubert // Skip over white space, if any.
16457e22627SCy Schubert //
16557e22627SCy Schubert ptr = skipws(ptr);
16657e22627SCy Schubert if (ptr == NULL || *ptr != '=')
16757e22627SCy Schubert {
16857e22627SCy Schubert //
16957e22627SCy Schubert // We hit the end of the line before
17057e22627SCy Schubert // finding a non-white space character,
17157e22627SCy Schubert // or we found one but it's not an "=".
17257e22627SCy Schubert // That means there's no "=", so this
17357e22627SCy Schubert // line is invalid. Complain and skip
17457e22627SCy Schubert // this line.
17557e22627SCy Schubert //
17657e22627SCy Schubert rpcapd_log(LOGPRIO_ERROR,
17757e22627SCy Schubert "%s, line %u has a parameter but no =",
17857e22627SCy Schubert loadfile, lineno);
17957e22627SCy Schubert continue;
18057e22627SCy Schubert }
18157e22627SCy Schubert
18257e22627SCy Schubert //
18357e22627SCy Schubert // We found the '='; set it to '\0', and skip
18457e22627SCy Schubert // past it.
18557e22627SCy Schubert //
18657e22627SCy Schubert *ptr++ = '\0';
18757e22627SCy Schubert
18857e22627SCy Schubert //
18957e22627SCy Schubert // Skip past any white space after the "=".
19057e22627SCy Schubert //
19157e22627SCy Schubert ptr = skipws(ptr);
19257e22627SCy Schubert if (ptr == NULL)
19357e22627SCy Schubert {
19457e22627SCy Schubert //
19557e22627SCy Schubert // The value is empty.
19657e22627SCy Schubert //
19757e22627SCy Schubert rpcapd_log(LOGPRIO_ERROR,
19857e22627SCy Schubert "%s, line %u has a parameter but no value",
19957e22627SCy Schubert loadfile, lineno);
20057e22627SCy Schubert continue;
20157e22627SCy Schubert }
20257e22627SCy Schubert
20357e22627SCy Schubert //
20457e22627SCy Schubert // OK, what parameter is this?
20557e22627SCy Schubert //
20657e22627SCy Schubert if (strcmp(param, PARAM_ACTIVECLIENT) == 0) {
20757e22627SCy Schubert //
20857e22627SCy Schubert // Add this to the list of active clients.
20957e22627SCy Schubert //
21057e22627SCy Schubert char *address, *port;
21157e22627SCy Schubert
21257e22627SCy Schubert //
21357e22627SCy Schubert // We can't have more than MAX_ACTIVE_LIST
21457e22627SCy Schubert // active clients.
21557e22627SCy Schubert //
21657e22627SCy Schubert if (num_active_clients >= MAX_ACTIVE_LIST)
21757e22627SCy Schubert {
21857e22627SCy Schubert //
21957e22627SCy Schubert // Too many entries for the active
22057e22627SCy Schubert // client list. Complain and
22157e22627SCy Schubert // ignore it.
22257e22627SCy Schubert //
22357e22627SCy Schubert rpcapd_log(LOGPRIO_ERROR,
22457e22627SCy Schubert "%s, line %u has an %s parameter, but we already have %u active clients",
22557e22627SCy Schubert loadfile, lineno, PARAM_ACTIVECLIENT,
22657e22627SCy Schubert MAX_ACTIVE_LIST);
22757e22627SCy Schubert continue;
22857e22627SCy Schubert }
22957e22627SCy Schubert
23057e22627SCy Schubert //
23157e22627SCy Schubert // Get the address.
23257e22627SCy Schubert // It's terminated by a host list separator
23357e22627SCy Schubert // *or* a #; there *shouldn't* be a #, as
23457e22627SCy Schubert // that starts a comment, and that would
23557e22627SCy Schubert // mean that we have no port.
23657e22627SCy Schubert //
23757e22627SCy Schubert address = ptr;
23857e22627SCy Schubert toklen = strcspn(ptr, RPCAP_HOSTLIST_SEP "#");
23957e22627SCy Schubert ptr += toklen; // skip to the terminator
24057e22627SCy Schubert if (toklen == 0)
24157e22627SCy Schubert {
2426f9cba8fSJoseph Mingrone if (*ptr == ' ' || *ptr == '\t' ||
2436f9cba8fSJoseph Mingrone *ptr == '\r' || *ptr == '\n' ||
2446f9cba8fSJoseph Mingrone *ptr == '#' || *ptr == '\0')
24557e22627SCy Schubert {
24657e22627SCy Schubert //
24757e22627SCy Schubert // The first character it saw
24857e22627SCy Schubert // was a whitespace character
2496f9cba8fSJoseph Mingrone // or a comment character,
2506f9cba8fSJoseph Mingrone // or we ran out of characters.
25157e22627SCy Schubert // This means that there's
25257e22627SCy Schubert // no value.
25357e22627SCy Schubert //
25457e22627SCy Schubert rpcapd_log(LOGPRIO_ERROR,
25557e22627SCy Schubert "%s, line %u has a parameter but no value",
25657e22627SCy Schubert loadfile, lineno);
25757e22627SCy Schubert }
25857e22627SCy Schubert else
25957e22627SCy Schubert {
26057e22627SCy Schubert //
26157e22627SCy Schubert // This means that the first
26257e22627SCy Schubert // character it saw was a
26357e22627SCy Schubert // separator. This means that
26457e22627SCy Schubert // there's no address in the
26557e22627SCy Schubert // value, just a port.
26657e22627SCy Schubert //
26757e22627SCy Schubert rpcapd_log(LOGPRIO_ERROR,
26857e22627SCy Schubert "%s, line %u has an %s parameter with a value containing no address",
26957e22627SCy Schubert loadfile, lineno, PARAM_ACTIVECLIENT);
27057e22627SCy Schubert }
27157e22627SCy Schubert continue;
27257e22627SCy Schubert }
27357e22627SCy Schubert
27457e22627SCy Schubert //
27557e22627SCy Schubert // Null-terminate the address, and skip past
27657e22627SCy Schubert // it.
27757e22627SCy Schubert //
27857e22627SCy Schubert *ptr++ = '\0';
27957e22627SCy Schubert
28057e22627SCy Schubert //
28157e22627SCy Schubert // Skip any white space following the
28257e22627SCy Schubert // separating character.
28357e22627SCy Schubert //
28457e22627SCy Schubert ptr = skipws(ptr);
28557e22627SCy Schubert if (ptr == NULL)
28657e22627SCy Schubert {
28757e22627SCy Schubert //
28857e22627SCy Schubert // The value is empty, so there's
28957e22627SCy Schubert // no port in the value.
29057e22627SCy Schubert //
29157e22627SCy Schubert rpcapd_log(LOGPRIO_ERROR,
29257e22627SCy Schubert "%s, line %u has an %s parameter with a value containing no port",
29357e22627SCy Schubert loadfile, lineno, PARAM_ACTIVECLIENT);
29457e22627SCy Schubert continue;
29557e22627SCy Schubert }
29657e22627SCy Schubert
29757e22627SCy Schubert //
29857e22627SCy Schubert // Get the port.
29957e22627SCy Schubert // We look for a white space character
30057e22627SCy Schubert // or a # as a terminator; the # introduces
30157e22627SCy Schubert // a comment that runs to the end of the
30257e22627SCy Schubert // line.
30357e22627SCy Schubert //
30457e22627SCy Schubert port = ptr;
30557e22627SCy Schubert toklen = strcspn(ptr, " \t#\r\n");
30657e22627SCy Schubert ptr += toklen;
30757e22627SCy Schubert if (toklen == 0)
30857e22627SCy Schubert {
30957e22627SCy Schubert //
31057e22627SCy Schubert // The value is empty, so there's
31157e22627SCy Schubert // no port in the value.
31257e22627SCy Schubert //
31357e22627SCy Schubert rpcapd_log(LOGPRIO_ERROR,
31457e22627SCy Schubert "%s, line %u has an %s parameter with a value containing no port",
31557e22627SCy Schubert loadfile, lineno, PARAM_ACTIVECLIENT);
31657e22627SCy Schubert continue;
31757e22627SCy Schubert }
31857e22627SCy Schubert
31957e22627SCy Schubert //
32057e22627SCy Schubert // Null-terminate the port, and skip past
32157e22627SCy Schubert // it.
32257e22627SCy Schubert //
32357e22627SCy Schubert *ptr++ = '\0';
324*afdbf109SJoseph Mingrone result = pcapint_strlcpy(activelist[num_active_clients].address, address, sizeof(activelist[num_active_clients].address));
32557e22627SCy Schubert if (result >= sizeof(activelist[num_active_clients].address))
32657e22627SCy Schubert {
32757e22627SCy Schubert //
32857e22627SCy Schubert // It didn't fit.
32957e22627SCy Schubert //
33057e22627SCy Schubert rpcapd_log(LOGPRIO_ERROR,
33157e22627SCy Schubert "%s, line %u has an %s parameter with an address with more than %u characters",
33257e22627SCy Schubert loadfile, lineno, PARAM_ACTIVECLIENT,
33357e22627SCy Schubert (unsigned int)(sizeof(activelist[num_active_clients].address) - 1));
33457e22627SCy Schubert continue;
33557e22627SCy Schubert }
33657e22627SCy Schubert if (strcmp(port, "DEFAULT") == 0) // the user choose a custom port
337*afdbf109SJoseph Mingrone result = pcapint_strlcpy(activelist[num_active_clients].port, RPCAP_DEFAULT_NETPORT_ACTIVE, sizeof(activelist[num_active_clients].port));
33857e22627SCy Schubert else
339*afdbf109SJoseph Mingrone result = pcapint_strlcpy(activelist[num_active_clients].port, port, sizeof(activelist[num_active_clients].port));
34057e22627SCy Schubert if (result >= sizeof(activelist[num_active_clients].address))
34157e22627SCy Schubert {
34257e22627SCy Schubert //
34357e22627SCy Schubert // It didn't fit.
34457e22627SCy Schubert //
34557e22627SCy Schubert rpcapd_log(LOGPRIO_ERROR,
34657e22627SCy Schubert "%s, line %u has an %s parameter with an port with more than %u characters",
34757e22627SCy Schubert loadfile, lineno, PARAM_ACTIVECLIENT,
34857e22627SCy Schubert (unsigned int)(sizeof(activelist[num_active_clients].port) - 1));
34957e22627SCy Schubert continue;
35057e22627SCy Schubert }
35157e22627SCy Schubert
35257e22627SCy Schubert num_active_clients++;
35357e22627SCy Schubert }
35457e22627SCy Schubert else if (strcmp(param, PARAM_PASSIVECLIENT) == 0)
35557e22627SCy Schubert {
35657e22627SCy Schubert char *eos;
35757e22627SCy Schubert char *host;
35857e22627SCy Schubert
35957e22627SCy Schubert //
36057e22627SCy Schubert // Get the host.
36157e22627SCy Schubert // We look for a white space character
36257e22627SCy Schubert // or a # as a terminator; the # introduces
36357e22627SCy Schubert // a comment that runs to the end of the
36457e22627SCy Schubert // line.
36557e22627SCy Schubert //
36657e22627SCy Schubert host = ptr;
36757e22627SCy Schubert toklen = strcspn(ptr, " \t#\r\n");
36857e22627SCy Schubert if (toklen == 0)
36957e22627SCy Schubert {
37057e22627SCy Schubert //
37157e22627SCy Schubert // The first character it saw
37257e22627SCy Schubert // was a whitespace character
37357e22627SCy Schubert // or a comment character.
37457e22627SCy Schubert // This means that there's
37557e22627SCy Schubert // no value.
37657e22627SCy Schubert //
37757e22627SCy Schubert rpcapd_log(LOGPRIO_ERROR,
37857e22627SCy Schubert "%s, line %u has a parameter but no value",
37957e22627SCy Schubert loadfile, lineno);
38057e22627SCy Schubert continue;
38157e22627SCy Schubert }
38257e22627SCy Schubert ptr += toklen;
38357e22627SCy Schubert *ptr++ = '\0';
38457e22627SCy Schubert
38557e22627SCy Schubert //
38657e22627SCy Schubert // Append this to the host list.
3876f9cba8fSJoseph Mingrone // Save the current end-of-string for the
38857e22627SCy Schubert // host list, in case the new host doesn't
38957e22627SCy Schubert // fit, so that we can discard the partially-
39057e22627SCy Schubert // copied host name.
39157e22627SCy Schubert //
39257e22627SCy Schubert eos = hostlist + strlen(hostlist);
39357e22627SCy Schubert if (eos != hostlist)
39457e22627SCy Schubert {
39557e22627SCy Schubert //
39657e22627SCy Schubert // The list is not empty, so prepend
39757e22627SCy Schubert // a comma before adding this host.
39857e22627SCy Schubert //
399*afdbf109SJoseph Mingrone result = pcapint_strlcat(hostlist, ",", sizeof(hostlist));
40057e22627SCy Schubert if (result >= sizeof(hostlist))
40157e22627SCy Schubert {
40257e22627SCy Schubert //
40357e22627SCy Schubert // It didn't fit. Discard
40457e22627SCy Schubert // the comma (which wasn't
40557e22627SCy Schubert // added, but...), complain,
40657e22627SCy Schubert // and ignore this line.
40757e22627SCy Schubert //
40857e22627SCy Schubert *eos = '\0';
40957e22627SCy Schubert rpcapd_log(LOGPRIO_ERROR,
41057e22627SCy Schubert "%s, line %u has a %s parameter with a host name that doesn't fit",
41157e22627SCy Schubert loadfile, lineno, PARAM_PASSIVECLIENT);
41257e22627SCy Schubert continue;
41357e22627SCy Schubert }
41457e22627SCy Schubert }
415*afdbf109SJoseph Mingrone result = pcapint_strlcat(hostlist, host, sizeof(hostlist));
41657e22627SCy Schubert if (result >= sizeof(hostlist))
41757e22627SCy Schubert {
41857e22627SCy Schubert //
41957e22627SCy Schubert // It didn't fit. Discard the comma,
42057e22627SCy Schubert // complain, and ignore this line.
42157e22627SCy Schubert //
42257e22627SCy Schubert *eos = '\0';
42357e22627SCy Schubert rpcapd_log(LOGPRIO_ERROR,
42457e22627SCy Schubert "%s, line %u has a %s parameter with a host name that doesn't fit",
42557e22627SCy Schubert loadfile, lineno, PARAM_PASSIVECLIENT);
42657e22627SCy Schubert continue;
42757e22627SCy Schubert }
42857e22627SCy Schubert }
42957e22627SCy Schubert else if (strcmp(param, PARAM_NULLAUTHPERMIT) == 0)
43057e22627SCy Schubert {
43157e22627SCy Schubert char *setting;
43257e22627SCy Schubert
43357e22627SCy Schubert //
43457e22627SCy Schubert // Get the setting.
43557e22627SCy Schubert // We look for a white space character
43657e22627SCy Schubert // or a # as a terminator; the # introduces
43757e22627SCy Schubert // a comment that runs to the end of the
43857e22627SCy Schubert // line.
43957e22627SCy Schubert //
44057e22627SCy Schubert setting = ptr;
44157e22627SCy Schubert toklen = strcspn(ptr, " \t#\r\n");
44257e22627SCy Schubert ptr += toklen;
44357e22627SCy Schubert if (toklen == 0)
44457e22627SCy Schubert {
44557e22627SCy Schubert //
44657e22627SCy Schubert // The first character it saw
44757e22627SCy Schubert // was a whitespace character
44857e22627SCy Schubert // or a comment character.
44957e22627SCy Schubert // This means that there's
45057e22627SCy Schubert // no value.
45157e22627SCy Schubert //
45257e22627SCy Schubert rpcapd_log(LOGPRIO_ERROR,
45357e22627SCy Schubert "%s, line %u has a parameter but no value",
45457e22627SCy Schubert loadfile, lineno);
45557e22627SCy Schubert continue;
45657e22627SCy Schubert }
45757e22627SCy Schubert *ptr++ = '\0';
45857e22627SCy Schubert
45957e22627SCy Schubert //
46057e22627SCy Schubert // XXX - should we complain if it's
46157e22627SCy Schubert // neither "yes" nor "no"?
46257e22627SCy Schubert //
46357e22627SCy Schubert if (strcmp(setting, "YES") == 0)
46457e22627SCy Schubert nullAuthAllowed = 1;
46557e22627SCy Schubert else
46657e22627SCy Schubert nullAuthAllowed = 0;
46757e22627SCy Schubert }
46857e22627SCy Schubert else
46957e22627SCy Schubert {
47057e22627SCy Schubert rpcapd_log(LOGPRIO_ERROR,
47157e22627SCy Schubert "%s, line %u has an unknown parameter %s",
47257e22627SCy Schubert loadfile, lineno, param);
47357e22627SCy Schubert continue;
47457e22627SCy Schubert }
47557e22627SCy Schubert }
47657e22627SCy Schubert
47757e22627SCy Schubert done:
47857e22627SCy Schubert // clear the remaining fields of the active list
47957e22627SCy Schubert for (int i = num_active_clients; i < MAX_ACTIVE_LIST; i++)
48057e22627SCy Schubert {
48157e22627SCy Schubert activelist[i].address[0] = 0;
48257e22627SCy Schubert activelist[i].port[0] = 0;
48357e22627SCy Schubert num_active_clients++;
48457e22627SCy Schubert }
48557e22627SCy Schubert
48657e22627SCy Schubert rpcapd_log(LOGPRIO_DEBUG, "New passive host list: %s", hostlist);
48757e22627SCy Schubert fclose(fp);
48857e22627SCy Schubert }
48957e22627SCy Schubert }
49057e22627SCy Schubert
fileconf_save(const char * savefile)49157e22627SCy Schubert int fileconf_save(const char *savefile)
49257e22627SCy Schubert {
49357e22627SCy Schubert FILE *fp;
49457e22627SCy Schubert
49557e22627SCy Schubert if ((fp = fopen(savefile, "w")) != NULL)
49657e22627SCy Schubert {
49757e22627SCy Schubert char *token; /*, *port;*/ // temp, needed to separate items into the hostlist
49857e22627SCy Schubert char temphostlist[MAX_HOST_LIST + 1];
49957e22627SCy Schubert int i = 0;
50057e22627SCy Schubert char *lasts;
50157e22627SCy Schubert
50257e22627SCy Schubert fprintf(fp, "# Configuration file help.\n\n");
50357e22627SCy Schubert
50457e22627SCy Schubert // Save list of clients which are allowed to connect to us in passive mode
50557e22627SCy Schubert fprintf(fp, "# Hosts which are allowed to connect to this server (passive mode)\n");
50657e22627SCy Schubert fprintf(fp, "# Format: PassiveClient = <name or address>\n\n");
50757e22627SCy Schubert
508*afdbf109SJoseph Mingrone pcapint_strlcpy(temphostlist, hostlist, sizeof (temphostlist));
50957e22627SCy Schubert
510*afdbf109SJoseph Mingrone token = pcapint_strtok_r(temphostlist, RPCAP_HOSTLIST_SEP, &lasts);
51157e22627SCy Schubert while(token != NULL)
51257e22627SCy Schubert {
51357e22627SCy Schubert fprintf(fp, "%s = %s\n", PARAM_PASSIVECLIENT, token);
514*afdbf109SJoseph Mingrone token = pcapint_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);
51557e22627SCy Schubert }
51657e22627SCy Schubert
51757e22627SCy Schubert
51857e22627SCy Schubert // Save list of clients which are allowed to connect to us in active mode
51957e22627SCy Schubert fprintf(fp, "\n\n");
52057e22627SCy Schubert fprintf(fp, "# Hosts to which this server is trying to connect to (active mode)\n");
52157e22627SCy Schubert fprintf(fp, "# Format: ActiveClient = <name or address>, <port | DEFAULT>\n\n");
52257e22627SCy Schubert
52357e22627SCy Schubert
52457e22627SCy Schubert while ((i < MAX_ACTIVE_LIST) && (activelist[i].address[0] != 0))
52557e22627SCy Schubert {
52657e22627SCy Schubert fprintf(fp, "%s = %s, %s\n", PARAM_ACTIVECLIENT,
52757e22627SCy Schubert activelist[i].address, activelist[i].port);
52857e22627SCy Schubert i++;
52957e22627SCy Schubert }
53057e22627SCy Schubert
53157e22627SCy Schubert // Save if we want to permit NULL authentication
53257e22627SCy Schubert fprintf(fp, "\n\n");
53357e22627SCy Schubert fprintf(fp, "# Permit NULL authentication: YES or NO\n\n");
53457e22627SCy Schubert
53557e22627SCy Schubert fprintf(fp, "%s = %s\n", PARAM_NULLAUTHPERMIT,
53657e22627SCy Schubert nullAuthAllowed ? "YES" : "NO");
53757e22627SCy Schubert
53857e22627SCy Schubert fclose(fp);
53957e22627SCy Schubert return 0;
54057e22627SCy Schubert }
54157e22627SCy Schubert else
54257e22627SCy Schubert {
54357e22627SCy Schubert return -1;
54457e22627SCy Schubert }
54557e22627SCy Schubert
54657e22627SCy Schubert }
54757e22627SCy Schubert
54857e22627SCy Schubert //
54957e22627SCy Schubert // Skip over white space.
55057e22627SCy Schubert // If we hit a CR or LF, return NULL, otherwise return a pointer to
55157e22627SCy Schubert // the first non-white space character. Replace white space characters
55257e22627SCy Schubert // other than CR or LF with '\0', so that, if we're skipping white space
55357e22627SCy Schubert // after a token, the token is null-terminated.
55457e22627SCy Schubert //
skipws(char * ptr)55557e22627SCy Schubert static char *skipws(char *ptr)
55657e22627SCy Schubert {
5576f9cba8fSJoseph Mingrone while (*ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n') {
55857e22627SCy Schubert if (*ptr == '\r' || *ptr == '\n')
55957e22627SCy Schubert return NULL;
56057e22627SCy Schubert *ptr++ = '\0';
56157e22627SCy Schubert }
56257e22627SCy Schubert return ptr;
56357e22627SCy Schubert }
564