2 * Copyright (c) 1987, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 #include <pcap.h> // for PCAP_ERRBUF_SIZE
46 #include "portability.h"
48 #include "config_params.h" // configuration file parameters
50 #include "rpcap-protocol.h"
56 #define PARAM_ACTIVECLIENT "ActiveClient"
57 #define PARAM_PASSIVECLIENT "PassiveClient"
58 #define PARAM_NULLAUTHPERMIT "NullAuthPermit"
60 static char *skipws(char *ptr);
62 void fileconf_read(void)
65 unsigned int num_active_clients;
67 if ((fp = fopen(loadfile, "r")) != NULL)
69 char line[MAX_LINE + 1];
73 num_active_clients = 0;
76 while (fgets(line, MAX_LINE, fp) != NULL)
86 linelen = strlen(line);
87 if (line[linelen - 1] != '\n')
92 // Either the line doesn't fit in
93 // the buffer, or we got an EOF
94 // before the EOL. Assume it's the
97 rpcapd_log(LOGPRIO_ERROR,
98 "%s, line %u is longer than %u characters",
99 loadfile, lineno, MAX_LINE);
102 // Eat characters until we get an NL.
104 while ((c = getc(fp)) != '\n')
111 // Try the next line.
118 // Skip leading white space, if any.
128 // Is the next character a "#"? If so, this
129 // line is a comment; skip to the next line.
135 // Is the next character alphabetic? If not,
136 // this isn't a valid parameter name.
138 if (!isascii((unsigned char)*ptr) ||
139 !isalpha((unsigned char)*ptr))
141 rpcapd_log(LOGPRIO_ERROR,
142 "%s, line %u doesn't have a valid parameter name",
148 // Grab the first token, which is made of
149 // alphanumerics, underscores, and hyphens.
150 // That's the name of the parameter being set.
153 while (isascii((unsigned char)*ptr) &&
154 (isalnum((unsigned char)*ptr) || *ptr == '-' || *ptr == '_'))
158 // Skip over white space, if any.
161 if (ptr == NULL || *ptr != '=')
164 // We hit the end of the line before
165 // finding a non-white space character,
166 // or we found one but it's not an "=".
167 // That means there's no "=", so this
168 // line is invalid. Complain and skip
171 rpcapd_log(LOGPRIO_ERROR,
172 "%s, line %u has a parameter but no =",
178 // We found the '='; set it to '\0', and skip
184 // Skip past any white space after the "=".
190 // The value is empty.
192 rpcapd_log(LOGPRIO_ERROR,
193 "%s, line %u has a parameter but no value",
199 // OK, what parameter is this?
201 if (strcmp(param, PARAM_ACTIVECLIENT) == 0) {
203 // Add this to the list of active clients.
205 char *address, *port;
208 // We can't have more than MAX_ACTIVE_LIST
211 if (num_active_clients >= MAX_ACTIVE_LIST)
214 // Too many entries for the active
215 // client list. Complain and
218 rpcapd_log(LOGPRIO_ERROR,
219 "%s, line %u has an %s parameter, but we already have %u active clients",
220 loadfile, lineno, PARAM_ACTIVECLIENT,
227 // It's terminated by a host list separator
228 // *or* a #; there *shouldn't* be a #, as
229 // that starts a comment, and that would
230 // mean that we have no port.
233 toklen = strcspn(ptr, RPCAP_HOSTLIST_SEP "#");
234 ptr += toklen; // skip to the terminator
237 if (isascii((unsigned char)*ptr) &&
238 (isspace((unsigned char)*ptr) || *ptr == '#' || *ptr == '\0'))
241 // The first character it saw
242 // was a whitespace character
243 // or a comment character.
244 // This means that there's
247 rpcapd_log(LOGPRIO_ERROR,
248 "%s, line %u has a parameter but no value",
254 // This means that the first
255 // character it saw was a
256 // separator. This means that
257 // there's no address in the
258 // value, just a port.
260 rpcapd_log(LOGPRIO_ERROR,
261 "%s, line %u has an %s parameter with a value containing no address",
262 loadfile, lineno, PARAM_ACTIVECLIENT);
268 // Null-terminate the address, and skip past
274 // Skip any white space following the
275 // separating character.
281 // The value is empty, so there's
282 // no port in the value.
284 rpcapd_log(LOGPRIO_ERROR,
285 "%s, line %u has an %s parameter with a value containing no port",
286 loadfile, lineno, PARAM_ACTIVECLIENT);
292 // We look for a white space character
293 // or a # as a terminator; the # introduces
294 // a comment that runs to the end of the
298 toklen = strcspn(ptr, " \t#\r\n");
303 // The value is empty, so there's
304 // no port in the value.
306 rpcapd_log(LOGPRIO_ERROR,
307 "%s, line %u has an %s parameter with a value containing no port",
308 loadfile, lineno, PARAM_ACTIVECLIENT);
313 // Null-terminate the port, and skip past
317 result = pcap_strlcpy(activelist[num_active_clients].address, address, sizeof(activelist[num_active_clients].address));
318 if (result >= sizeof(activelist[num_active_clients].address))
323 rpcapd_log(LOGPRIO_ERROR,
324 "%s, line %u has an %s parameter with an address with more than %u characters",
325 loadfile, lineno, PARAM_ACTIVECLIENT,
326 (unsigned int)(sizeof(activelist[num_active_clients].address) - 1));
329 if (strcmp(port, "DEFAULT") == 0) // the user choose a custom port
330 result = pcap_strlcpy(activelist[num_active_clients].port, RPCAP_DEFAULT_NETPORT_ACTIVE, sizeof(activelist[num_active_clients].port));
332 result = pcap_strlcpy(activelist[num_active_clients].port, port, sizeof(activelist[num_active_clients].port));
333 if (result >= sizeof(activelist[num_active_clients].address))
338 rpcapd_log(LOGPRIO_ERROR,
339 "%s, line %u has an %s parameter with an port with more than %u characters",
340 loadfile, lineno, PARAM_ACTIVECLIENT,
341 (unsigned int)(sizeof(activelist[num_active_clients].port) - 1));
345 num_active_clients++;
347 else if (strcmp(param, PARAM_PASSIVECLIENT) == 0)
354 // We look for a white space character
355 // or a # as a terminator; the # introduces
356 // a comment that runs to the end of the
360 toklen = strcspn(ptr, " \t#\r\n");
364 // The first character it saw
365 // was a whitespace character
366 // or a comment character.
367 // This means that there's
370 rpcapd_log(LOGPRIO_ERROR,
371 "%s, line %u has a parameter but no value",
379 // Append this to the host list.
380 // Save the curren end-of-string for the
381 // host list, in case the new host doesn't
382 // fit, so that we can discard the partially-
385 eos = hostlist + strlen(hostlist);
389 // The list is not empty, so prepend
390 // a comma before adding this host.
392 result = pcap_strlcat(hostlist, ",", sizeof(hostlist));
393 if (result >= sizeof(hostlist))
396 // It didn't fit. Discard
397 // the comma (which wasn't
398 // added, but...), complain,
399 // and ignore this line.
402 rpcapd_log(LOGPRIO_ERROR,
403 "%s, line %u has a %s parameter with a host name that doesn't fit",
404 loadfile, lineno, PARAM_PASSIVECLIENT);
408 result = pcap_strlcat(hostlist, host, sizeof(hostlist));
409 if (result >= sizeof(hostlist))
412 // It didn't fit. Discard the comma,
413 // complain, and ignore this line.
416 rpcapd_log(LOGPRIO_ERROR,
417 "%s, line %u has a %s parameter with a host name that doesn't fit",
418 loadfile, lineno, PARAM_PASSIVECLIENT);
422 else if (strcmp(param, PARAM_NULLAUTHPERMIT) == 0)
428 // We look for a white space character
429 // or a # as a terminator; the # introduces
430 // a comment that runs to the end of the
434 toklen = strcspn(ptr, " \t#\r\n");
439 // The first character it saw
440 // was a whitespace character
441 // or a comment character.
442 // This means that there's
445 rpcapd_log(LOGPRIO_ERROR,
446 "%s, line %u has a parameter but no value",
453 // XXX - should we complain if it's
454 // neither "yes" nor "no"?
456 if (strcmp(setting, "YES") == 0)
463 rpcapd_log(LOGPRIO_ERROR,
464 "%s, line %u has an unknown parameter %s",
465 loadfile, lineno, param);
471 // clear the remaining fields of the active list
472 for (int i = num_active_clients; i < MAX_ACTIVE_LIST; i++)
474 activelist[i].address[0] = 0;
475 activelist[i].port[0] = 0;
476 num_active_clients++;
479 rpcapd_log(LOGPRIO_DEBUG, "New passive host list: %s", hostlist);
484 int fileconf_save(const char *savefile)
488 if ((fp = fopen(savefile, "w")) != NULL)
490 char *token; /*, *port;*/ // temp, needed to separate items into the hostlist
491 char temphostlist[MAX_HOST_LIST + 1];
495 fprintf(fp, "# Configuration file help.\n\n");
497 // Save list of clients which are allowed to connect to us in passive mode
498 fprintf(fp, "# Hosts which are allowed to connect to this server (passive mode)\n");
499 fprintf(fp, "# Format: PassiveClient = <name or address>\n\n");
501 strncpy(temphostlist, hostlist, MAX_HOST_LIST);
502 temphostlist[MAX_HOST_LIST] = 0;
504 token = pcap_strtok_r(temphostlist, RPCAP_HOSTLIST_SEP, &lasts);
507 fprintf(fp, "%s = %s\n", PARAM_PASSIVECLIENT, token);
508 token = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);
512 // Save list of clients which are allowed to connect to us in active mode
514 fprintf(fp, "# Hosts to which this server is trying to connect to (active mode)\n");
515 fprintf(fp, "# Format: ActiveClient = <name or address>, <port | DEFAULT>\n\n");
518 while ((i < MAX_ACTIVE_LIST) && (activelist[i].address[0] != 0))
520 fprintf(fp, "%s = %s, %s\n", PARAM_ACTIVECLIENT,
521 activelist[i].address, activelist[i].port);
525 // Save if we want to permit NULL authentication
527 fprintf(fp, "# Permit NULL authentication: YES or NO\n\n");
529 fprintf(fp, "%s = %s\n", PARAM_NULLAUTHPERMIT,
530 nullAuthAllowed ? "YES" : "NO");
543 // Skip over white space.
544 // If we hit a CR or LF, return NULL, otherwise return a pointer to
545 // the first non-white space character. Replace white space characters
546 // other than CR or LF with '\0', so that, if we're skipping white space
547 // after a token, the token is null-terminated.
549 static char *skipws(char *ptr)
551 while (isascii((unsigned char)*ptr) && isspace((unsigned char)*ptr)) {
552 if (*ptr == '\r' || *ptr == '\n')