summaryrefslogtreecommitdiff
path: root/src/clstate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/clstate.c')
-rw-r--r--src/clstate.c322
1 files changed, 0 insertions, 322 deletions
diff --git a/src/clstate.c b/src/clstate.c
deleted file mode 100644
index 2c74e11..0000000
--- a/src/clstate.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Copyright (c) 2004, Nate Nielsen
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the
- * following disclaimer.
- * * 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.
- * * The names of contributors to this software may not be
- * used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
- * COPYRIGHT OWNER 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.
- *
- *
- * CONTRIBUTORS
- * Nate Nielsen <nielsen@memberwebs.com>
- * Yamamoto Takao <takao@oakat.org>
- */
-
-#include <paths.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <err.h>
-#include <pthread.h>
-#include <syslog.h>
-
-#include "usuals.h"
-#include "compat.h"
-#include "clamsmtpd.h"
-#include "util.h"
-
-/* -----------------------------------------------------------------------
- * DIRECTIONS FOR ADDING A CONFIGURATION OPTION
- *
- * - Add field to clstate_t structure in clamsmtpd.h
- * - Add default and set in clstate_init (below)
- * - Add config keyword (below)
- * - Parsing of option in clstate_parse_config (below)
- * - Validation of option in clstate_validate (below)
- * - Document in the sample doc/clamsmtpd.conf
- * - Document in doc/clamsmtpd.conf.5
- */
-
-/* -----------------------------------------------------------------------
- * DEFAULT SETTINGS
- */
-
-#define DEFAULT_SOCKET "10025"
-#define DEFAULT_PORT 10025
-#define DEFAULT_CLAMAV "/var/run/clamav/clamd"
-#define DEFAULT_MAXTHREADS 64
-#define DEFAULT_TIMEOUT 180
-#define DEFAULT_HEADER "X-AV-Checked: ClamAV using ClamSMTP"
-
-/* -----------------------------------------------------------------------
- * CONFIG KEYWORDS
- */
-
-#define CFG_MAXTHREADS "MaxConnections"
-#define CFG_TIMEOUT "TimeOut"
-#define CFG_OUTADDR "OutAddress"
-#define CFG_LISTENADDR "Listen"
-#define CFG_CLAMADDR "ClamAddress"
-#define CFG_HEADER "ScanHeader"
-#define CFG_DIRECTORY "TempDirectory"
-#define CFG_BOUNCE "Bounce"
-#define CFG_QUARANTINE "Quarantine"
-#define CFG_DEBUGFILES "DebugFiles"
-#define CFG_TRANSPARENT "TransparentProxy"
-
-/* The set of delimiters that can be present between config and value */
-#define CFG_DELIMS ": \t"
-
-/* -----------------------------------------------------------------------
- * CODE
- */
-
-/* String to bool helper function */
-static int strtob(const char* str)
-{
- if(strcasecmp(str, "0") == 0 ||
- strcasecmp(str, "no") == 0 ||
- strcasecmp(str, "false") == 0 ||
- strcasecmp(str, "f") == 0 ||
- strcasecmp(str, "off") == 0)
- return 0;
-
- if(strcasecmp(str, "1") == 0 ||
- strcasecmp(str, "yes") == 0 ||
- strcasecmp(str, "true") == 0 ||
- strcasecmp(str, "t") == 0 ||
- strcasecmp(str, "on") == 0)
- return 1;
-
- return -1;
-}
-
-void clstate_init(clstate_t* state)
-{
- ASSERT(state);
- memset(state, 0, sizeof(*state));
-
- /* Setup the defaults */
- state->debug_level = -1;
- state->max_threads = DEFAULT_MAXTHREADS;
- state->timeout.tv_sec = DEFAULT_TIMEOUT;
- state->clamname = DEFAULT_CLAMAV;
- state->listenname = DEFAULT_SOCKET;
- state->header = DEFAULT_HEADER;
- state->directory = _PATH_TMP;
-
- /* Create the main mutex and condition variable */
- if(pthread_mutexattr_init(&(state->_mtxattr)) != 0 ||
- pthread_mutexattr_settype(&(state->_mtxattr), MUTEX_TYPE) ||
- pthread_mutex_init(&(state->mutex), &(state->_mtxattr)) != 0)
- errx(1, "threading problem. can't create mutex or condition var");
-}
-
-int clstate_parse_config(clstate_t* state, const char* configfile)
-{
- FILE* f = NULL;
- long len;
- int r;
- char* p;
- char* t;
- char* n;
-
- ASSERT(state);
- ASSERT(configfile);
- ASSERT(!state->_p);
-
- f = fopen(configfile, "r");
- if(f == NULL)
- {
- /* Soft errors when default config file and not found */
- if((errno == ENOENT || errno == ENOTDIR))
- return -1;
- else
- err(1, "couldn't open config file: %s", configfile);
- }
-
- if(fseek(f, 0, SEEK_END) == -1 || (len = ftell(f)) == -1 || fseek(f, 0, SEEK_SET) == -1)
- err(1, "couldn't seek config file: %s", configfile);
-
- if((state->_p = (char*)malloc(len + 2)) == NULL)
- errx(1, "out of memory");
-
- if(fread(state->_p, 1, len, f) != len)
- err(1, "couldn't read config file: %s", configfile);
-
- fclose(f);
- messagex(NULL, LOG_DEBUG, "opened config file: %s", configfile);
-
- /* Double null terminate the data */
- p = state->_p;
- p[len] = 0;
- p[len + 1] = 0;
-
- n = state->_p;
-
- /* Go through lines and process them */
- while((t = strchr(n, '\n')) != NULL)
- {
- *t = 0;
- p = n; /* Do this before cleaning below */
- n = t + 1;
-
- p = trim_space(p);
-
- /* Comments and empty lines */
- if(*p == 0 || *p == '#')
- continue;
-
- /* Save some code typing below */
- #define PARSE(o) \
- (r = check_first_word(p, (o), KL(o), CFG_DELIMS))
- #define VAL \
- (p + r)
-
- /*
- * Note that we don't validate here. If something's wrong
- * set it to an invalid value.
- */
-
- if(PARSE(CFG_MAXTHREADS))
- {
- state->max_threads = strtol(VAL, &t, 10);
- if(*t) /* parse failed */
- state->max_threads = -1;
- }
-
- else if(PARSE(CFG_TIMEOUT))
- {
- state->timeout.tv_sec = strtol(VAL, &t, 10);
- if(*t) /* parse failed */
- state->timeout.tv_sec = -1;
- }
-
- else if(PARSE(CFG_OUTADDR))
- state->outname = VAL;
-
- else if(PARSE(CFG_LISTENADDR))
- state->listenname = VAL;
-
- else if(PARSE(CFG_CLAMADDR))
- state->clamname = VAL;
-
- else if(PARSE(CFG_HEADER))
- state->header = VAL;
-
- else if(PARSE(CFG_DIRECTORY))
- state->directory = VAL;
-
- else if(PARSE(CFG_BOUNCE))
- state->bounce = strtob(VAL);
-
- else if(PARSE(CFG_QUARANTINE))
- state->quarantine = strtob(VAL);
-
- else if(PARSE(CFG_DEBUGFILES))
- state->debug_files = strtob(VAL);
-
- else if(PARSE(CFG_TRANSPARENT))
- state->transparent = strtob(VAL);
-
- /* Unrecognized option */
- else
- errx(2, "invalid config line: %s", p);
-
- messagex(NULL, LOG_DEBUG, "parsed line: %s", p);
- }
-
- return 0;
-}
-
-void clstate_validate(clstate_t* state)
-{
- ASSERT(state);
- messagex(NULL, LOG_DEBUG, "validating configuration options");
-
- if(!(state->debug_level == -1 || state->debug_level <= LOG_DEBUG))
- errx(2, "invalid debug log level (must be between 1 and 4)");
-
- if(state->max_threads <= 1 || state->max_threads >= 1024)
- errx(2, "invalid setting: " CFG_MAXTHREADS " (must be between 1 and 1024)");
-
- if(state->timeout.tv_sec <= 0)
- errx(2, "invalid setting: " CFG_TIMEOUT);
-
- if(state->bounce == -1)
- errx(2, "invalid value for " CFG_BOUNCE);
- if(state->quarantine == -1)
- errx(2, "invalid value for " CFG_QUARANTINE);
- if(state->debug_files == -1)
- errx(2, "invalid value for " CFG_DEBUGFILES);
-
- /* This option has no default, but is required */
- if(state->outname == NULL && !state->transparent)
- errx(2, "no " CFG_OUTADDR " specified.");
-
- /* Parse all the addresses */
- if(state->outname != NULL)
- {
- if(state->transparent)
- warnx("the " CFG_OUTADDR " option will be ignored when " CFG_TRANSPARENT " is enabled");
- else
- if(sock_any_pton(state->outname, &(state->outaddr), SANY_OPT_DEFPORT(25)) == -1)
- errx(2, "invalid " CFG_OUTADDR " socket name or ip: %s", state->outname);
- }
-
- if(sock_any_pton(state->listenname, &(state->listenaddr), SANY_OPT_DEFANY | SANY_OPT_DEFPORT(DEFAULT_PORT)) == -1)
- errx(2, "invalid " CFG_LISTENADDR " socket name or ip: %s", state->listenname);
- if(sock_any_pton(state->clamname, &(state->clamaddr), SANY_OPT_DEFLOCAL) == -1)
- errx(2, "invalid " CFG_CLAMADDR " socket name: %s", state->clamname);
-
- if(strlen(state->directory) == 0)
- errx(2, "invalid setting: " CFG_DIRECTORY);
-
- if(state->header)
- {
- /*
- * This is for when it comes from the command-line.
- * Once command line args are phased out this can be removed
- */
- state->header = (const char*)trim_space((char*)state->header);
-
- if(strlen(state->header) == 0)
- state->header = NULL;
- }
-}
-
-void clstate_cleanup(clstate_t* state)
-{
- /* Close the mutex */
- pthread_mutex_destroy(&(state->mutex));
- pthread_mutexattr_destroy(&(state->_mtxattr));
-
- if(state->_p)
- free(state->_p);
-
- memset(state, 0, sizeof(*state));
-}