/*
 * Copyright (c) 1987, 1993, 1994
 *      The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by the University of
 *      California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "ftmacros.h"

#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <pcap.h>		// for PCAP_ERRBUF_SIZE

#include "portability.h"
#include "rpcapd.h"
#include "config_params.h"	// configuration file parameters
#include "fileconf.h"
#include "rpcap-protocol.h"
#include "log.h"

//
// Parameter names.
//
#define PARAM_ACTIVECLIENT	"ActiveClient"
#define PARAM_PASSIVECLIENT	"PassiveClient"
#define PARAM_NULLAUTHPERMIT	"NullAuthPermit"

static char *skipws(char *ptr);

/*
 * Locale-independent version checks for alphabetical and alphanumerical
 * characters that also can handle being handed a char value that might
 * be negative.
 */
#define FILECONF_ISALPHA(c) \
	(((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
#define FILECONF_ISALNUM(c) \
	(FILECONF_ISALPHA(c) || ((c) >= '0' && (c) <= '9'))

void fileconf_read(void)
{
	FILE *fp;
	unsigned int num_active_clients;

	if ((fp = fopen(loadfile, "r")) != NULL)
	{
		char line[MAX_LINE + 1];
		unsigned int lineno;

		hostlist[0] = 0;
		num_active_clients = 0;
		lineno = 0;

		while (fgets(line, MAX_LINE, fp) != NULL)
		{
			size_t linelen;
			char *ptr;
			char *param;
			size_t result;
			size_t toklen;

			lineno++;

			linelen = strlen(line);
			if (line[linelen - 1] != '\n')
			{
				int c;

				//
				// Either the line doesn't fit in
				// the buffer, or we got an EOF
				// before the EOL.  Assume it's the
				// former.
				//
				rpcapd_log(LOGPRIO_ERROR,
				    "%s, line %u is longer than %u characters",
				    loadfile, lineno, MAX_LINE);

				//
				// Eat characters until we get an NL.
				//
				while ((c = getc(fp)) != '\n')
				{
					if (c == EOF)
						goto done;
				}

				//
				// Try the next line.
				//
				continue;
			}
			ptr = line;

			//
			// Skip leading white space, if any.
			//
			ptr = skipws(ptr);
			if (ptr == NULL)
			{
				// Blank line.
				continue;
			}

			//
			// Is the next character a "#"?  If so, this
			// line is a comment; skip to the next line.
			//
			if (*ptr == '#')
				continue;

			//
			// Is the next character alphabetic?  If not,
			// this isn't a valid parameter name.
			//
			if (FILECONF_ISALPHA(*ptr))
			{
				rpcapd_log(LOGPRIO_ERROR,
				    "%s, line %u doesn't have a valid parameter name",
				    loadfile, lineno);
				continue;
			}

			//
			// Grab the first token, which is made of
			// alphanumerics, underscores, and hyphens.
			// That's the name of the parameter being set.
			//
			param = ptr;
			while (FILECONF_ISALNUM(*ptr) || *ptr == '-' || *ptr == '_')
				ptr++;

			//
			// Skip over white space, if any.
			//
			ptr = skipws(ptr);
			if (ptr == NULL || *ptr != '=')
			{
				//
				// We hit the end of the line before
				// finding a non-white space character,
				// or we found one but it's not an "=".
				// That means there's no "=", so this
				// line is invalid.  Complain and skip
				// this line.
				//
				rpcapd_log(LOGPRIO_ERROR,
				    "%s, line %u has a parameter but no =",
				    loadfile, lineno);
				continue;
			}

			//
			// We found the '='; set it to '\0', and skip
			// past it.
			//
			*ptr++ = '\0';

			//
			// Skip past any white space after the "=".
			//
			ptr = skipws(ptr);
			if (ptr == NULL)
			{
				//
				// The value is empty.
				//
				rpcapd_log(LOGPRIO_ERROR,
				    "%s, line %u has a parameter but no value",
				    loadfile, lineno);
				continue;
			}

			//
			// OK, what parameter is this?
			//
			if (strcmp(param, PARAM_ACTIVECLIENT) == 0) {
				//
				// Add this to the list of active clients.
				//
				char *address, *port;

				//
				// We can't have more than MAX_ACTIVE_LIST
				// active clients.
				//
				if (num_active_clients >= MAX_ACTIVE_LIST)
				{
					//
					// Too many entries for the active
					// client list.  Complain and
					// ignore it.
					//
					rpcapd_log(LOGPRIO_ERROR,
					    "%s, line %u has an %s parameter, but we already have %u active clients",
					    loadfile, lineno, PARAM_ACTIVECLIENT,
					    MAX_ACTIVE_LIST);
					continue;
				}

				//
				// Get the address.
				// It's terminated by a host list separator
				// *or* a #; there *shouldn't* be a #, as
				// that starts a comment, and that would
				// mean that we have no port.
				//
				address = ptr;
				toklen = strcspn(ptr, RPCAP_HOSTLIST_SEP "#");
				ptr += toklen;	// skip to the terminator
				if (toklen == 0)
				{
					if (*ptr == ' ' || *ptr == '\t' ||
					    *ptr == '\r' || *ptr == '\n' ||
					    *ptr == '#' || *ptr == '\0')
					{
						//
						// The first character it saw
						// was a whitespace character
						// or a comment character,
						// or we ran out of characters.
						// This means that there's
						// no value.
						//
						rpcapd_log(LOGPRIO_ERROR,
						    "%s, line %u has a parameter but no value",
						    loadfile, lineno);
					}
					else
					{
						//
						// This means that the first
						// character it saw was a
						// separator.  This means that
						// there's no address in the
						// value, just a port.
						//
						rpcapd_log(LOGPRIO_ERROR,
						    "%s, line %u has an %s parameter with a value containing no address",
						    loadfile, lineno, PARAM_ACTIVECLIENT);
					}
					continue;
				}

				//
				// Null-terminate the address, and skip past
				// it.
				//
				*ptr++ = '\0';

				//
				// Skip any white space following the
				// separating character.
				//
				ptr = skipws(ptr);
				if (ptr == NULL)
				{
					//
					// The value is empty, so there's
					// no port in the value.
					//
					rpcapd_log(LOGPRIO_ERROR,
					    "%s, line %u has an %s parameter with a value containing no port",
					    loadfile, lineno, PARAM_ACTIVECLIENT);
					continue;
				}

				//
				// Get the port.
				// We look for a white space character
				// or a # as a terminator; the # introduces
				// a comment that runs to the end of the
				// line.
				//
				port = ptr;
				toklen = strcspn(ptr, " \t#\r\n");
				ptr += toklen;
				if (toklen == 0)
				{
					//
					// The value is empty, so there's
					// no port in the value.
					//
					rpcapd_log(LOGPRIO_ERROR,
					    "%s, line %u has an %s parameter with a value containing no port",
					    loadfile, lineno, PARAM_ACTIVECLIENT);
					continue;
				}

				//
				// Null-terminate the port, and skip past
				// it.
				//
				*ptr++ = '\0';
				result = pcap_strlcpy(activelist[num_active_clients].address, address, sizeof(activelist[num_active_clients].address));
				if (result >= sizeof(activelist[num_active_clients].address))
				{
					//
					// It didn't fit.
					//
					rpcapd_log(LOGPRIO_ERROR,
					    "%s, line %u has an %s parameter with an address with more than %u characters",
					    loadfile, lineno, PARAM_ACTIVECLIENT,
					    (unsigned int)(sizeof(activelist[num_active_clients].address) - 1));
					continue;
				}
				if (strcmp(port, "DEFAULT") == 0) // the user choose a custom port
					result = pcap_strlcpy(activelist[num_active_clients].port, RPCAP_DEFAULT_NETPORT_ACTIVE, sizeof(activelist[num_active_clients].port));
				else
					result = pcap_strlcpy(activelist[num_active_clients].port, port, sizeof(activelist[num_active_clients].port));
				if (result >= sizeof(activelist[num_active_clients].address))
				{
					//
					// It didn't fit.
					//
					rpcapd_log(LOGPRIO_ERROR,
					    "%s, line %u has an %s parameter with an port with more than %u characters",
					    loadfile, lineno, PARAM_ACTIVECLIENT,
					    (unsigned int)(sizeof(activelist[num_active_clients].port) - 1));
					continue;
				}

				num_active_clients++;
			}
			else if (strcmp(param, PARAM_PASSIVECLIENT) == 0)
			{
				char *eos;
				char *host;

				//
				// Get the host.
				// We look for a white space character
				// or a # as a terminator; the # introduces
				// a comment that runs to the end of the
				// line.
				//
				host = ptr;
				toklen = strcspn(ptr, " \t#\r\n");
				if (toklen == 0)
				{
					//
					// The first character it saw
					// was a whitespace character
					// or a comment character.
					// This means that there's
					// no value.
					//
					rpcapd_log(LOGPRIO_ERROR,
					    "%s, line %u has a parameter but no value",
					    loadfile, lineno);
					continue;
				}
				ptr += toklen;
				*ptr++ = '\0';

				//
				// Append this to the host list.
				// Save the curren end-of-string for the
				// host list, in case the new host doesn't
				// fit, so that we can discard the partially-
				// copied host name.
				//
				eos = hostlist + strlen(hostlist);
				if (eos != hostlist)
				{
					//
					// The list is not empty, so prepend
					// a comma before adding this host.
					//
					result = pcap_strlcat(hostlist, ",", sizeof(hostlist));
					if (result >= sizeof(hostlist))
					{
						//
						// It didn't fit.  Discard
						// the comma (which wasn't
						// added, but...), complain,
						// and ignore this line.
						//
						*eos = '\0';
						rpcapd_log(LOGPRIO_ERROR,
						    "%s, line %u has a %s parameter with a host name that doesn't fit",
						    loadfile, lineno, PARAM_PASSIVECLIENT);
						continue;
					}
				}
				result = pcap_strlcat(hostlist, host, sizeof(hostlist));
				if (result >= sizeof(hostlist))
				{
					//
					// It didn't fit.  Discard the comma,
					// complain, and ignore this line.
					//
					*eos = '\0';
					rpcapd_log(LOGPRIO_ERROR,
					    "%s, line %u has a %s parameter with a host name that doesn't fit",
					    loadfile, lineno, PARAM_PASSIVECLIENT);
					continue;
				}
			}
			else if (strcmp(param, PARAM_NULLAUTHPERMIT) == 0)
			{
				char *setting;

				//
				// Get the setting.
				// We look for a white space character
				// or a # as a terminator; the # introduces
				// a comment that runs to the end of the
				// line.
				//
				setting = ptr;
				toklen = strcspn(ptr, " \t#\r\n");
				ptr += toklen;
				if (toklen == 0)
				{
					//
					// The first character it saw
					// was a whitespace character
					// or a comment character.
					// This means that there's
					// no value.
					//
					rpcapd_log(LOGPRIO_ERROR,
					    "%s, line %u has a parameter but no value",
					    loadfile, lineno);
					continue;
				}
				*ptr++ = '\0';

				//
				// XXX - should we complain if it's
				// neither "yes" nor "no"?
				//
				if (strcmp(setting, "YES") == 0)
					nullAuthAllowed = 1;
				else
					nullAuthAllowed = 0;
			}
			else
			{
				rpcapd_log(LOGPRIO_ERROR,
				    "%s, line %u has an unknown parameter %s",
				    loadfile, lineno, param);
				continue;
			}
		}

done:
		// clear the remaining fields of the active list
		for (int i = num_active_clients; i < MAX_ACTIVE_LIST; i++)
		{
			activelist[i].address[0] = 0;
			activelist[i].port[0] = 0;
			num_active_clients++;
		}

		rpcapd_log(LOGPRIO_DEBUG, "New passive host list: %s", hostlist);
		fclose(fp);
	}
}

int fileconf_save(const char *savefile)
{
	FILE *fp;

	if ((fp = fopen(savefile, "w")) != NULL)
	{
		char *token; /*, *port;*/					// temp, needed to separate items into the hostlist
		char temphostlist[MAX_HOST_LIST + 1];
		int i = 0;
		char *lasts;

		fprintf(fp, "# Configuration file help.\n\n");

		// Save list of clients which are allowed to connect to us in passive mode
		fprintf(fp, "# Hosts which are allowed to connect to this server (passive mode)\n");
		fprintf(fp, "# Format: PassiveClient = <name or address>\n\n");

		pcap_strlcpy(temphostlist, hostlist, sizeof (temphostlist));

		token = pcap_strtok_r(temphostlist, RPCAP_HOSTLIST_SEP, &lasts);
		while(token != NULL)
		{
			fprintf(fp, "%s = %s\n", PARAM_PASSIVECLIENT, token);
			token = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);
		}


		// Save list of clients which are allowed to connect to us in active mode
		fprintf(fp, "\n\n");
		fprintf(fp, "# Hosts to which this server is trying to connect to (active mode)\n");
		fprintf(fp, "# Format: ActiveClient = <name or address>, <port | DEFAULT>\n\n");


		while ((i < MAX_ACTIVE_LIST) && (activelist[i].address[0] != 0))
		{
			fprintf(fp, "%s = %s, %s\n", PARAM_ACTIVECLIENT,
			    activelist[i].address, activelist[i].port);
			i++;
		}

		// Save if we want to permit NULL authentication
		fprintf(fp, "\n\n");
		fprintf(fp, "# Permit NULL authentication: YES or NO\n\n");

		fprintf(fp, "%s = %s\n", PARAM_NULLAUTHPERMIT,
		    nullAuthAllowed ? "YES" : "NO");

		fclose(fp);
		return 0;
	}
	else
	{
		return -1;
	}

}

//
// Skip over white space.
// If we hit a CR or LF, return NULL, otherwise return a pointer to
// the first non-white space character.  Replace white space characters
// other than CR or LF with '\0', so that, if we're skipping white space
// after a token, the token is null-terminated.
//
static char *skipws(char *ptr)
{
	while (*ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n') {
		if (*ptr == '\r' || *ptr == '\n')
			return NULL;
		*ptr++ = '\0';
	}
	return ptr;
}
