xref: /aosp_15_r20/external/libpcap/rpcapd/fileconf.c (revision 8b26181f966a6af5cf6981a6f474313de533bb28)
1*8b26181fSAndroid Build Coastguard Worker /*
2*8b26181fSAndroid Build Coastguard Worker  * Copyright (c) 1987, 1993, 1994
3*8b26181fSAndroid Build Coastguard Worker  *      The Regents of the University of California.  All rights reserved.
4*8b26181fSAndroid Build Coastguard Worker  *
5*8b26181fSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
6*8b26181fSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
7*8b26181fSAndroid Build Coastguard Worker  * are met:
8*8b26181fSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright
9*8b26181fSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
10*8b26181fSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
11*8b26181fSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in the
12*8b26181fSAndroid Build Coastguard Worker  *    documentation and/or other materials provided with the distribution.
13*8b26181fSAndroid Build Coastguard Worker  * 3. All advertising materials mentioning features or use of this software
14*8b26181fSAndroid Build Coastguard Worker  *    must display the following acknowledgement:
15*8b26181fSAndroid Build Coastguard Worker  *      This product includes software developed by the University of
16*8b26181fSAndroid Build Coastguard Worker  *      California, Berkeley and its contributors.
17*8b26181fSAndroid Build Coastguard Worker  * 4. Neither the name of the University nor the names of its contributors
18*8b26181fSAndroid Build Coastguard Worker  *    may be used to endorse or promote products derived from this software
19*8b26181fSAndroid Build Coastguard Worker  *    without specific prior written permission.
20*8b26181fSAndroid Build Coastguard Worker  *
21*8b26181fSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22*8b26181fSAndroid Build Coastguard Worker  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23*8b26181fSAndroid Build Coastguard Worker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24*8b26181fSAndroid Build Coastguard Worker  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25*8b26181fSAndroid Build Coastguard Worker  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26*8b26181fSAndroid Build Coastguard Worker  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27*8b26181fSAndroid Build Coastguard Worker  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28*8b26181fSAndroid Build Coastguard Worker  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29*8b26181fSAndroid Build Coastguard Worker  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30*8b26181fSAndroid Build Coastguard Worker  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*8b26181fSAndroid Build Coastguard Worker  * SUCH DAMAGE.
32*8b26181fSAndroid Build Coastguard Worker  */
33*8b26181fSAndroid Build Coastguard Worker 
34*8b26181fSAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
35*8b26181fSAndroid Build Coastguard Worker #include <config.h>
36*8b26181fSAndroid Build Coastguard Worker #endif
37*8b26181fSAndroid Build Coastguard Worker 
38*8b26181fSAndroid Build Coastguard Worker #include "ftmacros.h"
39*8b26181fSAndroid Build Coastguard Worker 
40*8b26181fSAndroid Build Coastguard Worker #include <stdio.h>
41*8b26181fSAndroid Build Coastguard Worker #include <string.h>
42*8b26181fSAndroid Build Coastguard Worker #include <signal.h>
43*8b26181fSAndroid Build Coastguard Worker #include <pcap.h>		// for PCAP_ERRBUF_SIZE
44*8b26181fSAndroid Build Coastguard Worker 
45*8b26181fSAndroid Build Coastguard Worker #include "portability.h"
46*8b26181fSAndroid Build Coastguard Worker #include "rpcapd.h"
47*8b26181fSAndroid Build Coastguard Worker #include "config_params.h"	// configuration file parameters
48*8b26181fSAndroid Build Coastguard Worker #include "fileconf.h"
49*8b26181fSAndroid Build Coastguard Worker #include "rpcap-protocol.h"
50*8b26181fSAndroid Build Coastguard Worker #include "log.h"
51*8b26181fSAndroid Build Coastguard Worker 
52*8b26181fSAndroid Build Coastguard Worker //
53*8b26181fSAndroid Build Coastguard Worker // Parameter names.
54*8b26181fSAndroid Build Coastguard Worker //
55*8b26181fSAndroid Build Coastguard Worker #define PARAM_ACTIVECLIENT	"ActiveClient"
56*8b26181fSAndroid Build Coastguard Worker #define PARAM_PASSIVECLIENT	"PassiveClient"
57*8b26181fSAndroid Build Coastguard Worker #define PARAM_NULLAUTHPERMIT	"NullAuthPermit"
58*8b26181fSAndroid Build Coastguard Worker 
59*8b26181fSAndroid Build Coastguard Worker static char *skipws(char *ptr);
60*8b26181fSAndroid Build Coastguard Worker 
61*8b26181fSAndroid Build Coastguard Worker /*
62*8b26181fSAndroid Build Coastguard Worker  * Locale-independent version checks for alphabetical and alphanumerical
63*8b26181fSAndroid Build Coastguard Worker  * characters that also can handle being handed a char value that might
64*8b26181fSAndroid Build Coastguard Worker  * be negative.
65*8b26181fSAndroid Build Coastguard Worker  */
66*8b26181fSAndroid Build Coastguard Worker #define FILECONF_ISALPHA(c) \
67*8b26181fSAndroid Build Coastguard Worker 	(((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
68*8b26181fSAndroid Build Coastguard Worker #define FILECONF_ISALNUM(c) \
69*8b26181fSAndroid Build Coastguard Worker 	(FILECONF_ISALPHA(c) || ((c) >= '0' && (c) <= '9'))
70*8b26181fSAndroid Build Coastguard Worker 
fileconf_read(void)71*8b26181fSAndroid Build Coastguard Worker void fileconf_read(void)
72*8b26181fSAndroid Build Coastguard Worker {
73*8b26181fSAndroid Build Coastguard Worker 	FILE *fp;
74*8b26181fSAndroid Build Coastguard Worker 	unsigned int num_active_clients;
75*8b26181fSAndroid Build Coastguard Worker 
76*8b26181fSAndroid Build Coastguard Worker 	if ((fp = fopen(loadfile, "r")) != NULL)
77*8b26181fSAndroid Build Coastguard Worker 	{
78*8b26181fSAndroid Build Coastguard Worker 		char line[MAX_LINE + 1];
79*8b26181fSAndroid Build Coastguard Worker 		unsigned int lineno;
80*8b26181fSAndroid Build Coastguard Worker 
81*8b26181fSAndroid Build Coastguard Worker 		hostlist[0] = 0;
82*8b26181fSAndroid Build Coastguard Worker 		num_active_clients = 0;
83*8b26181fSAndroid Build Coastguard Worker 		lineno = 0;
84*8b26181fSAndroid Build Coastguard Worker 
85*8b26181fSAndroid Build Coastguard Worker 		while (fgets(line, MAX_LINE, fp) != NULL)
86*8b26181fSAndroid Build Coastguard Worker 		{
87*8b26181fSAndroid Build Coastguard Worker 			size_t linelen;
88*8b26181fSAndroid Build Coastguard Worker 			char *ptr;
89*8b26181fSAndroid Build Coastguard Worker 			char *param;
90*8b26181fSAndroid Build Coastguard Worker 			size_t result;
91*8b26181fSAndroid Build Coastguard Worker 			size_t toklen;
92*8b26181fSAndroid Build Coastguard Worker 
93*8b26181fSAndroid Build Coastguard Worker 			lineno++;
94*8b26181fSAndroid Build Coastguard Worker 
95*8b26181fSAndroid Build Coastguard Worker 			linelen = strlen(line);
96*8b26181fSAndroid Build Coastguard Worker 			if (line[linelen - 1] != '\n')
97*8b26181fSAndroid Build Coastguard Worker 			{
98*8b26181fSAndroid Build Coastguard Worker 				int c;
99*8b26181fSAndroid Build Coastguard Worker 
100*8b26181fSAndroid Build Coastguard Worker 				//
101*8b26181fSAndroid Build Coastguard Worker 				// Either the line doesn't fit in
102*8b26181fSAndroid Build Coastguard Worker 				// the buffer, or we got an EOF
103*8b26181fSAndroid Build Coastguard Worker 				// before the EOL.  Assume it's the
104*8b26181fSAndroid Build Coastguard Worker 				// former.
105*8b26181fSAndroid Build Coastguard Worker 				//
106*8b26181fSAndroid Build Coastguard Worker 				rpcapd_log(LOGPRIO_ERROR,
107*8b26181fSAndroid Build Coastguard Worker 				    "%s, line %u is longer than %u characters",
108*8b26181fSAndroid Build Coastguard Worker 				    loadfile, lineno, MAX_LINE);
109*8b26181fSAndroid Build Coastguard Worker 
110*8b26181fSAndroid Build Coastguard Worker 				//
111*8b26181fSAndroid Build Coastguard Worker 				// Eat characters until we get an NL.
112*8b26181fSAndroid Build Coastguard Worker 				//
113*8b26181fSAndroid Build Coastguard Worker 				while ((c = getc(fp)) != '\n')
114*8b26181fSAndroid Build Coastguard Worker 				{
115*8b26181fSAndroid Build Coastguard Worker 					if (c == EOF)
116*8b26181fSAndroid Build Coastguard Worker 						goto done;
117*8b26181fSAndroid Build Coastguard Worker 				}
118*8b26181fSAndroid Build Coastguard Worker 
119*8b26181fSAndroid Build Coastguard Worker 				//
120*8b26181fSAndroid Build Coastguard Worker 				// Try the next line.
121*8b26181fSAndroid Build Coastguard Worker 				//
122*8b26181fSAndroid Build Coastguard Worker 				continue;
123*8b26181fSAndroid Build Coastguard Worker 			}
124*8b26181fSAndroid Build Coastguard Worker 			ptr = line;
125*8b26181fSAndroid Build Coastguard Worker 
126*8b26181fSAndroid Build Coastguard Worker 			//
127*8b26181fSAndroid Build Coastguard Worker 			// Skip leading white space, if any.
128*8b26181fSAndroid Build Coastguard Worker 			//
129*8b26181fSAndroid Build Coastguard Worker 			ptr = skipws(ptr);
130*8b26181fSAndroid Build Coastguard Worker 			if (ptr == NULL)
131*8b26181fSAndroid Build Coastguard Worker 			{
132*8b26181fSAndroid Build Coastguard Worker 				// Blank line.
133*8b26181fSAndroid Build Coastguard Worker 				continue;
134*8b26181fSAndroid Build Coastguard Worker 			}
135*8b26181fSAndroid Build Coastguard Worker 
136*8b26181fSAndroid Build Coastguard Worker 			//
137*8b26181fSAndroid Build Coastguard Worker 			// Is the next character a "#"?  If so, this
138*8b26181fSAndroid Build Coastguard Worker 			// line is a comment; skip to the next line.
139*8b26181fSAndroid Build Coastguard Worker 			//
140*8b26181fSAndroid Build Coastguard Worker 			if (*ptr == '#')
141*8b26181fSAndroid Build Coastguard Worker 				continue;
142*8b26181fSAndroid Build Coastguard Worker 
143*8b26181fSAndroid Build Coastguard Worker 			//
144*8b26181fSAndroid Build Coastguard Worker 			// Is the next character alphabetic?  If not,
145*8b26181fSAndroid Build Coastguard Worker 			// this isn't a valid parameter name.
146*8b26181fSAndroid Build Coastguard Worker 			//
147*8b26181fSAndroid Build Coastguard Worker 			if (FILECONF_ISALPHA(*ptr))
148*8b26181fSAndroid Build Coastguard Worker 			{
149*8b26181fSAndroid Build Coastguard Worker 				rpcapd_log(LOGPRIO_ERROR,
150*8b26181fSAndroid Build Coastguard Worker 				    "%s, line %u doesn't have a valid parameter name",
151*8b26181fSAndroid Build Coastguard Worker 				    loadfile, lineno);
152*8b26181fSAndroid Build Coastguard Worker 				continue;
153*8b26181fSAndroid Build Coastguard Worker 			}
154*8b26181fSAndroid Build Coastguard Worker 
155*8b26181fSAndroid Build Coastguard Worker 			//
156*8b26181fSAndroid Build Coastguard Worker 			// Grab the first token, which is made of
157*8b26181fSAndroid Build Coastguard Worker 			// alphanumerics, underscores, and hyphens.
158*8b26181fSAndroid Build Coastguard Worker 			// That's the name of the parameter being set.
159*8b26181fSAndroid Build Coastguard Worker 			//
160*8b26181fSAndroid Build Coastguard Worker 			param = ptr;
161*8b26181fSAndroid Build Coastguard Worker 			while (FILECONF_ISALNUM(*ptr) || *ptr == '-' || *ptr == '_')
162*8b26181fSAndroid Build Coastguard Worker 				ptr++;
163*8b26181fSAndroid Build Coastguard Worker 
164*8b26181fSAndroid Build Coastguard Worker 			//
165*8b26181fSAndroid Build Coastguard Worker 			// Skip over white space, if any.
166*8b26181fSAndroid Build Coastguard Worker 			//
167*8b26181fSAndroid Build Coastguard Worker 			ptr = skipws(ptr);
168*8b26181fSAndroid Build Coastguard Worker 			if (ptr == NULL || *ptr != '=')
169*8b26181fSAndroid Build Coastguard Worker 			{
170*8b26181fSAndroid Build Coastguard Worker 				//
171*8b26181fSAndroid Build Coastguard Worker 				// We hit the end of the line before
172*8b26181fSAndroid Build Coastguard Worker 				// finding a non-white space character,
173*8b26181fSAndroid Build Coastguard Worker 				// or we found one but it's not an "=".
174*8b26181fSAndroid Build Coastguard Worker 				// That means there's no "=", so this
175*8b26181fSAndroid Build Coastguard Worker 				// line is invalid.  Complain and skip
176*8b26181fSAndroid Build Coastguard Worker 				// this line.
177*8b26181fSAndroid Build Coastguard Worker 				//
178*8b26181fSAndroid Build Coastguard Worker 				rpcapd_log(LOGPRIO_ERROR,
179*8b26181fSAndroid Build Coastguard Worker 				    "%s, line %u has a parameter but no =",
180*8b26181fSAndroid Build Coastguard Worker 				    loadfile, lineno);
181*8b26181fSAndroid Build Coastguard Worker 				continue;
182*8b26181fSAndroid Build Coastguard Worker 			}
183*8b26181fSAndroid Build Coastguard Worker 
184*8b26181fSAndroid Build Coastguard Worker 			//
185*8b26181fSAndroid Build Coastguard Worker 			// We found the '='; set it to '\0', and skip
186*8b26181fSAndroid Build Coastguard Worker 			// past it.
187*8b26181fSAndroid Build Coastguard Worker 			//
188*8b26181fSAndroid Build Coastguard Worker 			*ptr++ = '\0';
189*8b26181fSAndroid Build Coastguard Worker 
190*8b26181fSAndroid Build Coastguard Worker 			//
191*8b26181fSAndroid Build Coastguard Worker 			// Skip past any white space after the "=".
192*8b26181fSAndroid Build Coastguard Worker 			//
193*8b26181fSAndroid Build Coastguard Worker 			ptr = skipws(ptr);
194*8b26181fSAndroid Build Coastguard Worker 			if (ptr == NULL)
195*8b26181fSAndroid Build Coastguard Worker 			{
196*8b26181fSAndroid Build Coastguard Worker 				//
197*8b26181fSAndroid Build Coastguard Worker 				// The value is empty.
198*8b26181fSAndroid Build Coastguard Worker 				//
199*8b26181fSAndroid Build Coastguard Worker 				rpcapd_log(LOGPRIO_ERROR,
200*8b26181fSAndroid Build Coastguard Worker 				    "%s, line %u has a parameter but no value",
201*8b26181fSAndroid Build Coastguard Worker 				    loadfile, lineno);
202*8b26181fSAndroid Build Coastguard Worker 				continue;
203*8b26181fSAndroid Build Coastguard Worker 			}
204*8b26181fSAndroid Build Coastguard Worker 
205*8b26181fSAndroid Build Coastguard Worker 			//
206*8b26181fSAndroid Build Coastguard Worker 			// OK, what parameter is this?
207*8b26181fSAndroid Build Coastguard Worker 			//
208*8b26181fSAndroid Build Coastguard Worker 			if (strcmp(param, PARAM_ACTIVECLIENT) == 0) {
209*8b26181fSAndroid Build Coastguard Worker 				//
210*8b26181fSAndroid Build Coastguard Worker 				// Add this to the list of active clients.
211*8b26181fSAndroid Build Coastguard Worker 				//
212*8b26181fSAndroid Build Coastguard Worker 				char *address, *port;
213*8b26181fSAndroid Build Coastguard Worker 
214*8b26181fSAndroid Build Coastguard Worker 				//
215*8b26181fSAndroid Build Coastguard Worker 				// We can't have more than MAX_ACTIVE_LIST
216*8b26181fSAndroid Build Coastguard Worker 				// active clients.
217*8b26181fSAndroid Build Coastguard Worker 				//
218*8b26181fSAndroid Build Coastguard Worker 				if (num_active_clients >= MAX_ACTIVE_LIST)
219*8b26181fSAndroid Build Coastguard Worker 				{
220*8b26181fSAndroid Build Coastguard Worker 					//
221*8b26181fSAndroid Build Coastguard Worker 					// Too many entries for the active
222*8b26181fSAndroid Build Coastguard Worker 					// client list.  Complain and
223*8b26181fSAndroid Build Coastguard Worker 					// ignore it.
224*8b26181fSAndroid Build Coastguard Worker 					//
225*8b26181fSAndroid Build Coastguard Worker 					rpcapd_log(LOGPRIO_ERROR,
226*8b26181fSAndroid Build Coastguard Worker 					    "%s, line %u has an %s parameter, but we already have %u active clients",
227*8b26181fSAndroid Build Coastguard Worker 					    loadfile, lineno, PARAM_ACTIVECLIENT,
228*8b26181fSAndroid Build Coastguard Worker 					    MAX_ACTIVE_LIST);
229*8b26181fSAndroid Build Coastguard Worker 					continue;
230*8b26181fSAndroid Build Coastguard Worker 				}
231*8b26181fSAndroid Build Coastguard Worker 
232*8b26181fSAndroid Build Coastguard Worker 				//
233*8b26181fSAndroid Build Coastguard Worker 				// Get the address.
234*8b26181fSAndroid Build Coastguard Worker 				// It's terminated by a host list separator
235*8b26181fSAndroid Build Coastguard Worker 				// *or* a #; there *shouldn't* be a #, as
236*8b26181fSAndroid Build Coastguard Worker 				// that starts a comment, and that would
237*8b26181fSAndroid Build Coastguard Worker 				// mean that we have no port.
238*8b26181fSAndroid Build Coastguard Worker 				//
239*8b26181fSAndroid Build Coastguard Worker 				address = ptr;
240*8b26181fSAndroid Build Coastguard Worker 				toklen = strcspn(ptr, RPCAP_HOSTLIST_SEP "#");
241*8b26181fSAndroid Build Coastguard Worker 				ptr += toklen;	// skip to the terminator
242*8b26181fSAndroid Build Coastguard Worker 				if (toklen == 0)
243*8b26181fSAndroid Build Coastguard Worker 				{
244*8b26181fSAndroid Build Coastguard Worker 					if (*ptr == ' ' || *ptr == '\t' ||
245*8b26181fSAndroid Build Coastguard Worker 					    *ptr == '\r' || *ptr == '\n' ||
246*8b26181fSAndroid Build Coastguard Worker 					    *ptr == '#' || *ptr == '\0')
247*8b26181fSAndroid Build Coastguard Worker 					{
248*8b26181fSAndroid Build Coastguard Worker 						//
249*8b26181fSAndroid Build Coastguard Worker 						// The first character it saw
250*8b26181fSAndroid Build Coastguard Worker 						// was a whitespace character
251*8b26181fSAndroid Build Coastguard Worker 						// or a comment character,
252*8b26181fSAndroid Build Coastguard Worker 						// or we ran out of characters.
253*8b26181fSAndroid Build Coastguard Worker 						// This means that there's
254*8b26181fSAndroid Build Coastguard Worker 						// no value.
255*8b26181fSAndroid Build Coastguard Worker 						//
256*8b26181fSAndroid Build Coastguard Worker 						rpcapd_log(LOGPRIO_ERROR,
257*8b26181fSAndroid Build Coastguard Worker 						    "%s, line %u has a parameter but no value",
258*8b26181fSAndroid Build Coastguard Worker 						    loadfile, lineno);
259*8b26181fSAndroid Build Coastguard Worker 					}
260*8b26181fSAndroid Build Coastguard Worker 					else
261*8b26181fSAndroid Build Coastguard Worker 					{
262*8b26181fSAndroid Build Coastguard Worker 						//
263*8b26181fSAndroid Build Coastguard Worker 						// This means that the first
264*8b26181fSAndroid Build Coastguard Worker 						// character it saw was a
265*8b26181fSAndroid Build Coastguard Worker 						// separator.  This means that
266*8b26181fSAndroid Build Coastguard Worker 						// there's no address in the
267*8b26181fSAndroid Build Coastguard Worker 						// value, just a port.
268*8b26181fSAndroid Build Coastguard Worker 						//
269*8b26181fSAndroid Build Coastguard Worker 						rpcapd_log(LOGPRIO_ERROR,
270*8b26181fSAndroid Build Coastguard Worker 						    "%s, line %u has an %s parameter with a value containing no address",
271*8b26181fSAndroid Build Coastguard Worker 						    loadfile, lineno, PARAM_ACTIVECLIENT);
272*8b26181fSAndroid Build Coastguard Worker 					}
273*8b26181fSAndroid Build Coastguard Worker 					continue;
274*8b26181fSAndroid Build Coastguard Worker 				}
275*8b26181fSAndroid Build Coastguard Worker 
276*8b26181fSAndroid Build Coastguard Worker 				//
277*8b26181fSAndroid Build Coastguard Worker 				// Null-terminate the address, and skip past
278*8b26181fSAndroid Build Coastguard Worker 				// it.
279*8b26181fSAndroid Build Coastguard Worker 				//
280*8b26181fSAndroid Build Coastguard Worker 				*ptr++ = '\0';
281*8b26181fSAndroid Build Coastguard Worker 
282*8b26181fSAndroid Build Coastguard Worker 				//
283*8b26181fSAndroid Build Coastguard Worker 				// Skip any white space following the
284*8b26181fSAndroid Build Coastguard Worker 				// separating character.
285*8b26181fSAndroid Build Coastguard Worker 				//
286*8b26181fSAndroid Build Coastguard Worker 				ptr = skipws(ptr);
287*8b26181fSAndroid Build Coastguard Worker 				if (ptr == NULL)
288*8b26181fSAndroid Build Coastguard Worker 				{
289*8b26181fSAndroid Build Coastguard Worker 					//
290*8b26181fSAndroid Build Coastguard Worker 					// The value is empty, so there's
291*8b26181fSAndroid Build Coastguard Worker 					// no port in the value.
292*8b26181fSAndroid Build Coastguard Worker 					//
293*8b26181fSAndroid Build Coastguard Worker 					rpcapd_log(LOGPRIO_ERROR,
294*8b26181fSAndroid Build Coastguard Worker 					    "%s, line %u has an %s parameter with a value containing no port",
295*8b26181fSAndroid Build Coastguard Worker 					    loadfile, lineno, PARAM_ACTIVECLIENT);
296*8b26181fSAndroid Build Coastguard Worker 					continue;
297*8b26181fSAndroid Build Coastguard Worker 				}
298*8b26181fSAndroid Build Coastguard Worker 
299*8b26181fSAndroid Build Coastguard Worker 				//
300*8b26181fSAndroid Build Coastguard Worker 				// Get the port.
301*8b26181fSAndroid Build Coastguard Worker 				// We look for a white space character
302*8b26181fSAndroid Build Coastguard Worker 				// or a # as a terminator; the # introduces
303*8b26181fSAndroid Build Coastguard Worker 				// a comment that runs to the end of the
304*8b26181fSAndroid Build Coastguard Worker 				// line.
305*8b26181fSAndroid Build Coastguard Worker 				//
306*8b26181fSAndroid Build Coastguard Worker 				port = ptr;
307*8b26181fSAndroid Build Coastguard Worker 				toklen = strcspn(ptr, " \t#\r\n");
308*8b26181fSAndroid Build Coastguard Worker 				ptr += toklen;
309*8b26181fSAndroid Build Coastguard Worker 				if (toklen == 0)
310*8b26181fSAndroid Build Coastguard Worker 				{
311*8b26181fSAndroid Build Coastguard Worker 					//
312*8b26181fSAndroid Build Coastguard Worker 					// The value is empty, so there's
313*8b26181fSAndroid Build Coastguard Worker 					// no port in the value.
314*8b26181fSAndroid Build Coastguard Worker 					//
315*8b26181fSAndroid Build Coastguard Worker 					rpcapd_log(LOGPRIO_ERROR,
316*8b26181fSAndroid Build Coastguard Worker 					    "%s, line %u has an %s parameter with a value containing no port",
317*8b26181fSAndroid Build Coastguard Worker 					    loadfile, lineno, PARAM_ACTIVECLIENT);
318*8b26181fSAndroid Build Coastguard Worker 					continue;
319*8b26181fSAndroid Build Coastguard Worker 				}
320*8b26181fSAndroid Build Coastguard Worker 
321*8b26181fSAndroid Build Coastguard Worker 				//
322*8b26181fSAndroid Build Coastguard Worker 				// Null-terminate the port, and skip past
323*8b26181fSAndroid Build Coastguard Worker 				// it.
324*8b26181fSAndroid Build Coastguard Worker 				//
325*8b26181fSAndroid Build Coastguard Worker 				*ptr++ = '\0';
326*8b26181fSAndroid Build Coastguard Worker 				result = pcap_strlcpy(activelist[num_active_clients].address, address, sizeof(activelist[num_active_clients].address));
327*8b26181fSAndroid Build Coastguard Worker 				if (result >= sizeof(activelist[num_active_clients].address))
328*8b26181fSAndroid Build Coastguard Worker 				{
329*8b26181fSAndroid Build Coastguard Worker 					//
330*8b26181fSAndroid Build Coastguard Worker 					// It didn't fit.
331*8b26181fSAndroid Build Coastguard Worker 					//
332*8b26181fSAndroid Build Coastguard Worker 					rpcapd_log(LOGPRIO_ERROR,
333*8b26181fSAndroid Build Coastguard Worker 					    "%s, line %u has an %s parameter with an address with more than %u characters",
334*8b26181fSAndroid Build Coastguard Worker 					    loadfile, lineno, PARAM_ACTIVECLIENT,
335*8b26181fSAndroid Build Coastguard Worker 					    (unsigned int)(sizeof(activelist[num_active_clients].address) - 1));
336*8b26181fSAndroid Build Coastguard Worker 					continue;
337*8b26181fSAndroid Build Coastguard Worker 				}
338*8b26181fSAndroid Build Coastguard Worker 				if (strcmp(port, "DEFAULT") == 0) // the user choose a custom port
339*8b26181fSAndroid Build Coastguard Worker 					result = pcap_strlcpy(activelist[num_active_clients].port, RPCAP_DEFAULT_NETPORT_ACTIVE, sizeof(activelist[num_active_clients].port));
340*8b26181fSAndroid Build Coastguard Worker 				else
341*8b26181fSAndroid Build Coastguard Worker 					result = pcap_strlcpy(activelist[num_active_clients].port, port, sizeof(activelist[num_active_clients].port));
342*8b26181fSAndroid Build Coastguard Worker 				if (result >= sizeof(activelist[num_active_clients].address))
343*8b26181fSAndroid Build Coastguard Worker 				{
344*8b26181fSAndroid Build Coastguard Worker 					//
345*8b26181fSAndroid Build Coastguard Worker 					// It didn't fit.
346*8b26181fSAndroid Build Coastguard Worker 					//
347*8b26181fSAndroid Build Coastguard Worker 					rpcapd_log(LOGPRIO_ERROR,
348*8b26181fSAndroid Build Coastguard Worker 					    "%s, line %u has an %s parameter with an port with more than %u characters",
349*8b26181fSAndroid Build Coastguard Worker 					    loadfile, lineno, PARAM_ACTIVECLIENT,
350*8b26181fSAndroid Build Coastguard Worker 					    (unsigned int)(sizeof(activelist[num_active_clients].port) - 1));
351*8b26181fSAndroid Build Coastguard Worker 					continue;
352*8b26181fSAndroid Build Coastguard Worker 				}
353*8b26181fSAndroid Build Coastguard Worker 
354*8b26181fSAndroid Build Coastguard Worker 				num_active_clients++;
355*8b26181fSAndroid Build Coastguard Worker 			}
356*8b26181fSAndroid Build Coastguard Worker 			else if (strcmp(param, PARAM_PASSIVECLIENT) == 0)
357*8b26181fSAndroid Build Coastguard Worker 			{
358*8b26181fSAndroid Build Coastguard Worker 				char *eos;
359*8b26181fSAndroid Build Coastguard Worker 				char *host;
360*8b26181fSAndroid Build Coastguard Worker 
361*8b26181fSAndroid Build Coastguard Worker 				//
362*8b26181fSAndroid Build Coastguard Worker 				// Get the host.
363*8b26181fSAndroid Build Coastguard Worker 				// We look for a white space character
364*8b26181fSAndroid Build Coastguard Worker 				// or a # as a terminator; the # introduces
365*8b26181fSAndroid Build Coastguard Worker 				// a comment that runs to the end of the
366*8b26181fSAndroid Build Coastguard Worker 				// line.
367*8b26181fSAndroid Build Coastguard Worker 				//
368*8b26181fSAndroid Build Coastguard Worker 				host = ptr;
369*8b26181fSAndroid Build Coastguard Worker 				toklen = strcspn(ptr, " \t#\r\n");
370*8b26181fSAndroid Build Coastguard Worker 				if (toklen == 0)
371*8b26181fSAndroid Build Coastguard Worker 				{
372*8b26181fSAndroid Build Coastguard Worker 					//
373*8b26181fSAndroid Build Coastguard Worker 					// The first character it saw
374*8b26181fSAndroid Build Coastguard Worker 					// was a whitespace character
375*8b26181fSAndroid Build Coastguard Worker 					// or a comment character.
376*8b26181fSAndroid Build Coastguard Worker 					// This means that there's
377*8b26181fSAndroid Build Coastguard Worker 					// no value.
378*8b26181fSAndroid Build Coastguard Worker 					//
379*8b26181fSAndroid Build Coastguard Worker 					rpcapd_log(LOGPRIO_ERROR,
380*8b26181fSAndroid Build Coastguard Worker 					    "%s, line %u has a parameter but no value",
381*8b26181fSAndroid Build Coastguard Worker 					    loadfile, lineno);
382*8b26181fSAndroid Build Coastguard Worker 					continue;
383*8b26181fSAndroid Build Coastguard Worker 				}
384*8b26181fSAndroid Build Coastguard Worker 				ptr += toklen;
385*8b26181fSAndroid Build Coastguard Worker 				*ptr++ = '\0';
386*8b26181fSAndroid Build Coastguard Worker 
387*8b26181fSAndroid Build Coastguard Worker 				//
388*8b26181fSAndroid Build Coastguard Worker 				// Append this to the host list.
389*8b26181fSAndroid Build Coastguard Worker 				// Save the current end-of-string for the
390*8b26181fSAndroid Build Coastguard Worker 				// host list, in case the new host doesn't
391*8b26181fSAndroid Build Coastguard Worker 				// fit, so that we can discard the partially-
392*8b26181fSAndroid Build Coastguard Worker 				// copied host name.
393*8b26181fSAndroid Build Coastguard Worker 				//
394*8b26181fSAndroid Build Coastguard Worker 				eos = hostlist + strlen(hostlist);
395*8b26181fSAndroid Build Coastguard Worker 				if (eos != hostlist)
396*8b26181fSAndroid Build Coastguard Worker 				{
397*8b26181fSAndroid Build Coastguard Worker 					//
398*8b26181fSAndroid Build Coastguard Worker 					// The list is not empty, so prepend
399*8b26181fSAndroid Build Coastguard Worker 					// a comma before adding this host.
400*8b26181fSAndroid Build Coastguard Worker 					//
401*8b26181fSAndroid Build Coastguard Worker 					result = pcap_strlcat(hostlist, ",", sizeof(hostlist));
402*8b26181fSAndroid Build Coastguard Worker 					if (result >= sizeof(hostlist))
403*8b26181fSAndroid Build Coastguard Worker 					{
404*8b26181fSAndroid Build Coastguard Worker 						//
405*8b26181fSAndroid Build Coastguard Worker 						// It didn't fit.  Discard
406*8b26181fSAndroid Build Coastguard Worker 						// the comma (which wasn't
407*8b26181fSAndroid Build Coastguard Worker 						// added, but...), complain,
408*8b26181fSAndroid Build Coastguard Worker 						// and ignore this line.
409*8b26181fSAndroid Build Coastguard Worker 						//
410*8b26181fSAndroid Build Coastguard Worker 						*eos = '\0';
411*8b26181fSAndroid Build Coastguard Worker 						rpcapd_log(LOGPRIO_ERROR,
412*8b26181fSAndroid Build Coastguard Worker 						    "%s, line %u has a %s parameter with a host name that doesn't fit",
413*8b26181fSAndroid Build Coastguard Worker 						    loadfile, lineno, PARAM_PASSIVECLIENT);
414*8b26181fSAndroid Build Coastguard Worker 						continue;
415*8b26181fSAndroid Build Coastguard Worker 					}
416*8b26181fSAndroid Build Coastguard Worker 				}
417*8b26181fSAndroid Build Coastguard Worker 				result = pcap_strlcat(hostlist, host, sizeof(hostlist));
418*8b26181fSAndroid Build Coastguard Worker 				if (result >= sizeof(hostlist))
419*8b26181fSAndroid Build Coastguard Worker 				{
420*8b26181fSAndroid Build Coastguard Worker 					//
421*8b26181fSAndroid Build Coastguard Worker 					// It didn't fit.  Discard the comma,
422*8b26181fSAndroid Build Coastguard Worker 					// complain, and ignore this line.
423*8b26181fSAndroid Build Coastguard Worker 					//
424*8b26181fSAndroid Build Coastguard Worker 					*eos = '\0';
425*8b26181fSAndroid Build Coastguard Worker 					rpcapd_log(LOGPRIO_ERROR,
426*8b26181fSAndroid Build Coastguard Worker 					    "%s, line %u has a %s parameter with a host name that doesn't fit",
427*8b26181fSAndroid Build Coastguard Worker 					    loadfile, lineno, PARAM_PASSIVECLIENT);
428*8b26181fSAndroid Build Coastguard Worker 					continue;
429*8b26181fSAndroid Build Coastguard Worker 				}
430*8b26181fSAndroid Build Coastguard Worker 			}
431*8b26181fSAndroid Build Coastguard Worker 			else if (strcmp(param, PARAM_NULLAUTHPERMIT) == 0)
432*8b26181fSAndroid Build Coastguard Worker 			{
433*8b26181fSAndroid Build Coastguard Worker 				char *setting;
434*8b26181fSAndroid Build Coastguard Worker 
435*8b26181fSAndroid Build Coastguard Worker 				//
436*8b26181fSAndroid Build Coastguard Worker 				// Get the setting.
437*8b26181fSAndroid Build Coastguard Worker 				// We look for a white space character
438*8b26181fSAndroid Build Coastguard Worker 				// or a # as a terminator; the # introduces
439*8b26181fSAndroid Build Coastguard Worker 				// a comment that runs to the end of the
440*8b26181fSAndroid Build Coastguard Worker 				// line.
441*8b26181fSAndroid Build Coastguard Worker 				//
442*8b26181fSAndroid Build Coastguard Worker 				setting = ptr;
443*8b26181fSAndroid Build Coastguard Worker 				toklen = strcspn(ptr, " \t#\r\n");
444*8b26181fSAndroid Build Coastguard Worker 				ptr += toklen;
445*8b26181fSAndroid Build Coastguard Worker 				if (toklen == 0)
446*8b26181fSAndroid Build Coastguard Worker 				{
447*8b26181fSAndroid Build Coastguard Worker 					//
448*8b26181fSAndroid Build Coastguard Worker 					// The first character it saw
449*8b26181fSAndroid Build Coastguard Worker 					// was a whitespace character
450*8b26181fSAndroid Build Coastguard Worker 					// or a comment character.
451*8b26181fSAndroid Build Coastguard Worker 					// This means that there's
452*8b26181fSAndroid Build Coastguard Worker 					// no value.
453*8b26181fSAndroid Build Coastguard Worker 					//
454*8b26181fSAndroid Build Coastguard Worker 					rpcapd_log(LOGPRIO_ERROR,
455*8b26181fSAndroid Build Coastguard Worker 					    "%s, line %u has a parameter but no value",
456*8b26181fSAndroid Build Coastguard Worker 					    loadfile, lineno);
457*8b26181fSAndroid Build Coastguard Worker 					continue;
458*8b26181fSAndroid Build Coastguard Worker 				}
459*8b26181fSAndroid Build Coastguard Worker 				*ptr++ = '\0';
460*8b26181fSAndroid Build Coastguard Worker 
461*8b26181fSAndroid Build Coastguard Worker 				//
462*8b26181fSAndroid Build Coastguard Worker 				// XXX - should we complain if it's
463*8b26181fSAndroid Build Coastguard Worker 				// neither "yes" nor "no"?
464*8b26181fSAndroid Build Coastguard Worker 				//
465*8b26181fSAndroid Build Coastguard Worker 				if (strcmp(setting, "YES") == 0)
466*8b26181fSAndroid Build Coastguard Worker 					nullAuthAllowed = 1;
467*8b26181fSAndroid Build Coastguard Worker 				else
468*8b26181fSAndroid Build Coastguard Worker 					nullAuthAllowed = 0;
469*8b26181fSAndroid Build Coastguard Worker 			}
470*8b26181fSAndroid Build Coastguard Worker 			else
471*8b26181fSAndroid Build Coastguard Worker 			{
472*8b26181fSAndroid Build Coastguard Worker 				rpcapd_log(LOGPRIO_ERROR,
473*8b26181fSAndroid Build Coastguard Worker 				    "%s, line %u has an unknown parameter %s",
474*8b26181fSAndroid Build Coastguard Worker 				    loadfile, lineno, param);
475*8b26181fSAndroid Build Coastguard Worker 				continue;
476*8b26181fSAndroid Build Coastguard Worker 			}
477*8b26181fSAndroid Build Coastguard Worker 		}
478*8b26181fSAndroid Build Coastguard Worker 
479*8b26181fSAndroid Build Coastguard Worker done:
480*8b26181fSAndroid Build Coastguard Worker 		// clear the remaining fields of the active list
481*8b26181fSAndroid Build Coastguard Worker 		for (int i = num_active_clients; i < MAX_ACTIVE_LIST; i++)
482*8b26181fSAndroid Build Coastguard Worker 		{
483*8b26181fSAndroid Build Coastguard Worker 			activelist[i].address[0] = 0;
484*8b26181fSAndroid Build Coastguard Worker 			activelist[i].port[0] = 0;
485*8b26181fSAndroid Build Coastguard Worker 			num_active_clients++;
486*8b26181fSAndroid Build Coastguard Worker 		}
487*8b26181fSAndroid Build Coastguard Worker 
488*8b26181fSAndroid Build Coastguard Worker 		rpcapd_log(LOGPRIO_DEBUG, "New passive host list: %s", hostlist);
489*8b26181fSAndroid Build Coastguard Worker 		fclose(fp);
490*8b26181fSAndroid Build Coastguard Worker 	}
491*8b26181fSAndroid Build Coastguard Worker }
492*8b26181fSAndroid Build Coastguard Worker 
fileconf_save(const char * savefile)493*8b26181fSAndroid Build Coastguard Worker int fileconf_save(const char *savefile)
494*8b26181fSAndroid Build Coastguard Worker {
495*8b26181fSAndroid Build Coastguard Worker 	FILE *fp;
496*8b26181fSAndroid Build Coastguard Worker 
497*8b26181fSAndroid Build Coastguard Worker 	if ((fp = fopen(savefile, "w")) != NULL)
498*8b26181fSAndroid Build Coastguard Worker 	{
499*8b26181fSAndroid Build Coastguard Worker 		char *token; /*, *port;*/					// temp, needed to separate items into the hostlist
500*8b26181fSAndroid Build Coastguard Worker 		char temphostlist[MAX_HOST_LIST + 1];
501*8b26181fSAndroid Build Coastguard Worker 		int i = 0;
502*8b26181fSAndroid Build Coastguard Worker 		char *lasts;
503*8b26181fSAndroid Build Coastguard Worker 
504*8b26181fSAndroid Build Coastguard Worker 		fprintf(fp, "# Configuration file help.\n\n");
505*8b26181fSAndroid Build Coastguard Worker 
506*8b26181fSAndroid Build Coastguard Worker 		// Save list of clients which are allowed to connect to us in passive mode
507*8b26181fSAndroid Build Coastguard Worker 		fprintf(fp, "# Hosts which are allowed to connect to this server (passive mode)\n");
508*8b26181fSAndroid Build Coastguard Worker 		fprintf(fp, "# Format: PassiveClient = <name or address>\n\n");
509*8b26181fSAndroid Build Coastguard Worker 
510*8b26181fSAndroid Build Coastguard Worker 		pcap_strlcpy(temphostlist, hostlist, sizeof (temphostlist));
511*8b26181fSAndroid Build Coastguard Worker 
512*8b26181fSAndroid Build Coastguard Worker 		token = pcap_strtok_r(temphostlist, RPCAP_HOSTLIST_SEP, &lasts);
513*8b26181fSAndroid Build Coastguard Worker 		while(token != NULL)
514*8b26181fSAndroid Build Coastguard Worker 		{
515*8b26181fSAndroid Build Coastguard Worker 			fprintf(fp, "%s = %s\n", PARAM_PASSIVECLIENT, token);
516*8b26181fSAndroid Build Coastguard Worker 			token = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);
517*8b26181fSAndroid Build Coastguard Worker 		}
518*8b26181fSAndroid Build Coastguard Worker 
519*8b26181fSAndroid Build Coastguard Worker 
520*8b26181fSAndroid Build Coastguard Worker 		// Save list of clients which are allowed to connect to us in active mode
521*8b26181fSAndroid Build Coastguard Worker 		fprintf(fp, "\n\n");
522*8b26181fSAndroid Build Coastguard Worker 		fprintf(fp, "# Hosts to which this server is trying to connect to (active mode)\n");
523*8b26181fSAndroid Build Coastguard Worker 		fprintf(fp, "# Format: ActiveClient = <name or address>, <port | DEFAULT>\n\n");
524*8b26181fSAndroid Build Coastguard Worker 
525*8b26181fSAndroid Build Coastguard Worker 
526*8b26181fSAndroid Build Coastguard Worker 		while ((i < MAX_ACTIVE_LIST) && (activelist[i].address[0] != 0))
527*8b26181fSAndroid Build Coastguard Worker 		{
528*8b26181fSAndroid Build Coastguard Worker 			fprintf(fp, "%s = %s, %s\n", PARAM_ACTIVECLIENT,
529*8b26181fSAndroid Build Coastguard Worker 			    activelist[i].address, activelist[i].port);
530*8b26181fSAndroid Build Coastguard Worker 			i++;
531*8b26181fSAndroid Build Coastguard Worker 		}
532*8b26181fSAndroid Build Coastguard Worker 
533*8b26181fSAndroid Build Coastguard Worker 		// Save if we want to permit NULL authentication
534*8b26181fSAndroid Build Coastguard Worker 		fprintf(fp, "\n\n");
535*8b26181fSAndroid Build Coastguard Worker 		fprintf(fp, "# Permit NULL authentication: YES or NO\n\n");
536*8b26181fSAndroid Build Coastguard Worker 
537*8b26181fSAndroid Build Coastguard Worker 		fprintf(fp, "%s = %s\n", PARAM_NULLAUTHPERMIT,
538*8b26181fSAndroid Build Coastguard Worker 		    nullAuthAllowed ? "YES" : "NO");
539*8b26181fSAndroid Build Coastguard Worker 
540*8b26181fSAndroid Build Coastguard Worker 		fclose(fp);
541*8b26181fSAndroid Build Coastguard Worker 		return 0;
542*8b26181fSAndroid Build Coastguard Worker 	}
543*8b26181fSAndroid Build Coastguard Worker 	else
544*8b26181fSAndroid Build Coastguard Worker 	{
545*8b26181fSAndroid Build Coastguard Worker 		return -1;
546*8b26181fSAndroid Build Coastguard Worker 	}
547*8b26181fSAndroid Build Coastguard Worker 
548*8b26181fSAndroid Build Coastguard Worker }
549*8b26181fSAndroid Build Coastguard Worker 
550*8b26181fSAndroid Build Coastguard Worker //
551*8b26181fSAndroid Build Coastguard Worker // Skip over white space.
552*8b26181fSAndroid Build Coastguard Worker // If we hit a CR or LF, return NULL, otherwise return a pointer to
553*8b26181fSAndroid Build Coastguard Worker // the first non-white space character.  Replace white space characters
554*8b26181fSAndroid Build Coastguard Worker // other than CR or LF with '\0', so that, if we're skipping white space
555*8b26181fSAndroid Build Coastguard Worker // after a token, the token is null-terminated.
556*8b26181fSAndroid Build Coastguard Worker //
skipws(char * ptr)557*8b26181fSAndroid Build Coastguard Worker static char *skipws(char *ptr)
558*8b26181fSAndroid Build Coastguard Worker {
559*8b26181fSAndroid Build Coastguard Worker 	while (*ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n') {
560*8b26181fSAndroid Build Coastguard Worker 		if (*ptr == '\r' || *ptr == '\n')
561*8b26181fSAndroid Build Coastguard Worker 			return NULL;
562*8b26181fSAndroid Build Coastguard Worker 		*ptr++ = '\0';
563*8b26181fSAndroid Build Coastguard Worker 	}
564*8b26181fSAndroid Build Coastguard Worker 	return ptr;
565*8b26181fSAndroid Build Coastguard Worker }
566