xref: /freebsd/contrib/libpcap/rpcapd/fileconf.c (revision afdbf109c6a661a729938f68211054a0a50d38ac)
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