/************************************************************ ** $Id: readconf.c,v 0.4 2003/10/29 00:35:13 bcx Exp $ ** ** Copyright Bryan Costales and Perforce Software, Inc. 2003 ** ** This code is "open source" as defined by version 1.9 of ** the Open Source Definition from: ** ** http://www.opensource.org/docs/definition.php. ** ** Entry points defined in this file: ** ** setdefaults(): ** Set the defaults for all global variables. ** readconf(): ** Opens, reads, and closes the configuration file. *************************************************************/ # define EXTERN # include "slow.h" void setdefaults(void) { ListenPort = LISTENPORT; PrimaryDatabaseLoc = PRIMARYDBFILE; SecondaryDatabaseLoc = SECONDARYDBFILE; MaxHeaderRcpts = MAX_HEADER_RCPTS; MaxRcptsPerEnvelope = MAX_RCPTS_PER_ENV; CheckMessageId = TRUE; CheckFromHeader = TRUE; CheckSenderHost = TRUE; LookBackOne = TRUE; AllowWhiteListIPs = TRUE; LookupIPatRBL = TRUE; MilterAbort = TRUE; AdvanceWrite = TRUE; CheckForged = TRUE; HoneyFile = HONEYFILE; HoneyHosts = NULL; MxHosts = NULL; LocalHostName = NULL; XTrackHeader = X_TRACK_HEADER; } typedef struct { char *token; /* the config file keyword */ int index; /* for switch() statement */ bool set; /* already set from config file if TRUE */ } CFLINES; CFLINES Cflines[] = { # define I_PSOC 1 {"ListenPort", I_PSOC, 0 }, # define I_PRIDBFILE 2 {"PrimaryDatabaseLoc", I_PRIDBFILE, 0 }, # define I_SECDBFILE 3 {"SecondaryDatabaseLoc", I_SECDBFILE, 0 }, # define I_MAXRPERHDR 4 {"MaxHeaderRcpts", I_MAXRPERHDR, 0 }, # define I_MAXRPERE 5 {"MaxRcptsPerEnvelope", I_MAXRPERE, 0 }, # define I_CHK_MID 6 {"CheckMessageId", I_CHK_MID, 0 }, # define I_CHKFROMHDR 7 {"CheckFromHeader", I_CHKFROMHDR, 0 }, # define I_CHKSENDHOST 8 {"CheckSenderHost", I_CHKSENDHOST, 0 }, # define I_LOOKBACK 9 {"LookBackOne", I_LOOKBACK, 0 }, # define I_ALLOWWHITE 10 {"AllowWhiteListIPs", I_ALLOWWHITE, 0 }, # define I_DORBL 11 {"LookupIPatRBL", I_DORBL, 0 }, # define I_MILABORT 12 {"MilterAbort", I_MILABORT, 0 }, # define I_ADVWRITE 13 {"AdvanceWrite", I_ADVWRITE, 0 }, # define I_FORGED 14 {"CheckForged", I_FORGED, 0 }, # define I_HONEY 15 {"HoneyFile", I_HONEY, 0 }, # define I_MYNAME 16 {"LocalHostName", I_MYNAME, 0 }, # define I_XHEADER 17 {"XTrackHeader", I_XHEADER, 0 }, { NULL, 0, 0 }, }; static bool truefalse(char *tf) { if (tf == NULL) return TRUE; switch((int)*tf) { case 'Y': case 'y': case 'T': case 't': return TRUE; break; } return FALSE; } void readconf(char *prog, char *cffile) { FILE *fp; char buf[BUFSIZ]; CFLINES *cl; int line = 0; extern int errno; fp = fopen(cffile, "r"); if (fp == NULL) milterr(Prog, __FILE__, __LINE__, FALSE, errno, "Open config file", cffile); /* Use file(line) to show errors in the config file */ setbit(BUG_SOURCE, Debugbits); while (fgets(buf, BUFSIZ, fp) != NULL) { char *cp, *ep; int ch; ++line; cp = strrchr(buf, '\n'); if (cp != NULL) *cp = '\0'; for (cp = buf; *cp != '\0'; ++cp) { if (! isspace((int)*cp)) break; } if (*cp == '\0' || *cp == '#') continue; /* empty line */ for (ep = cp; *ep != '\0'; ++ep) { if (isspace((int)*ep) || *ep == '=') break; } if (*ep == '\0') milterr(Prog, cffile, line, FALSE, EINVAL, "Missing \"=\" from", buf); ch = *ep; *ep = '\0'; for (cl = Cflines; cl->token != NULL; ++cl) { if (strcasecmp(cl->token, cp) == 0) break; } *ep = ch; if (cl->token == NULL) milterr(Prog, cffile, line, FALSE, EINVAL, "Unrecognized token", cp); if ((cl->set)++ != 0) milterr(Prog, cffile, line, FALSE, EINVAL, "Repeated definition", buf); cp = strchr(buf, '='); if (cp == NULL) milterr(Prog, cffile, line, FALSE, EINVAL, "Missing \"=\" from", buf); for (++cp; *cp != '\0'; ++cp) { if (! isspace((int)*cp)) break; } if (*cp == '\0') milterr(Prog, cffile, line, FALSE, EINVAL, "Nothing after \"=\" in", buf); switch(cl->index) { /* * Should be in the form inet:port@host */ case I_PSOC: ListenPort = try_strdup(__FILE__, __LINE__, cp); if (ListenPort == NULL) milterr(Prog, cffile, line, FALSE, errno, "Memory allocation", cp); if (strncasecmp(ListenPort, "inet:", 5) != 0) milterr(Prog, cffile, line, FALSE, EINVAL, cp, "Must start with \"inet:\""); break; /* * For security these should be full path names. * Should we enforce that? */ case I_PRIDBFILE: PrimaryDatabaseLoc = try_strdup(__FILE__, __LINE__, cp); if (PrimaryDatabaseLoc == NULL) milterr(Prog, cffile, line, FALSE, errno, "Memory allocation", buf); break; case I_SECDBFILE: SecondaryDatabaseLoc = try_strdup(__FILE__, __LINE__, cp); if (SecondaryDatabaseLoc == NULL) milterr(Prog, cffile, line, FALSE, errno, "Memory allocation", buf); break; case I_MAXRPERHDR: MaxHeaderRcpts = atoi(cp); if (MaxHeaderRcpts <= 0) milterr(Prog, cffile, line, FALSE, EINVAL, "Must be positive", buf); break; case I_MAXRPERE: MaxRcptsPerEnvelope = atoi(cp); if (MaxRcptsPerEnvelope <= 0) milterr(Prog, cffile, line, FALSE, EINVAL, "Must be positive", buf); break; case I_CHK_MID: CheckMessageId = truefalse(cp); break; case I_CHKFROMHDR: CheckFromHeader = truefalse(cp); break; case I_CHKSENDHOST: CheckSenderHost = truefalse(cp); break; case I_LOOKBACK: LookBackOne = truefalse(cp); break; case I_ALLOWWHITE: AllowWhiteListIPs = truefalse(cp); break; case I_DORBL: LookupIPatRBL = truefalse(cp); break; case I_MILABORT: MilterAbort = truefalse(cp); break; case I_ADVWRITE: AdvanceWrite = truefalse(cp); break; case I_FORGED: CheckForged = truefalse(cp); break; /* * The list of honeypot addresses. */ case I_HONEY: HoneyFile = try_strdup(__FILE__, __LINE__, cp); if (HoneyFile == NULL) milterr(Prog, cffile, line, FALSE, errno, "Memory allocation", buf); break; case I_MYNAME: LocalHostName = try_strdup(__FILE__, __LINE__, cp); if (LocalHostName == NULL) milterr(Prog, cffile, line, FALSE, errno, "Memory allocation", buf); break; case I_XHEADER: XTrackHeader = try_strdup(__FILE__, __LINE__, cp); if (XTrackHeader == NULL) milterr(Prog, cffile, line, FALSE, errno, "Memory allocation", buf); if (strchr(XTrackHeader, ':') != NULL) milterr(Prog, cffile, line, FALSE, EINVAL, "Must not contain a colon", cp); break; } } if (ferror(fp)) milterr(Prog, __FILE__, __LINE__, FALSE, errno, "Read config file", cffile); (void) fclose(fp); Debugbits ^= BUG_SOURCE; return; }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#7 | 4222 | bryan_costales |
Massive rewrite to speed up the database writes. Using a single database now with duplicate keys where the keys are the IP numbers. Added a purge command and removed the garbage command. Fixed some leaking memory bugs and properly closed the database in a few places were it was not properly closed. Updated the docs to reflect this and bumped both the database version and release number. Running on a FreeBSD 3.x machine and a Solaris 9 machine. |
||
#6 | 4052 | bryan_costales |
Implimented: whitelisting AddMXHost for MX servers that lie Converted to thread safe DNS routines garbage collection RunAsUser and RunAsGroup for root startups rebuild the database summarize by IP number Finished all documentation. Moved release from alpha to beta |
||
#5 | 4030 | bryan_costales |
Finished documenting the configuration file Fixed a race condition and a core dump bug. Added hooks for whitelisting and IP aliasing Added support for Berkeley DB 4.2 Converted to htonl() and ntohl() Known Bugs: ip.db cannot be shared over NFS IP tracking from MX hosts can fail A RunAsUser config option is needed. |
||
#4 | 3998 | bryan_costales |
Brought the whole distribution up to V0.9 Added a huge abount of documentation. Added slowedit find Created startup scripts to launch for testing Fixed numerous bugs. Fixed a few portablity issues. Installed hooks for whitelisting and IP aliases. |
||
#3 | 3957 | bryan_costales |
Added rbl lookup support and testing for same. Folded in support for smfi_stop(). Added lots of slowedit commands Fixed a serious bug in MX lookups. Added to documentation. |
||
#2 | 3890 | bryan_costales |
This is the 0.6 release. The following have been added with the uses indicated: Source files: edit.c -- the slowedit functions compat.c -- missing system files Autoconf: configure.ac, makefile.am config.h aclocal.m4 acinclude.m4 build/ Documents: doc/ -- html and man(1) documents Testing: tests/ -- regressive testing TODO: -- revised to show actual progress |
||
#1 | 3838 | bryan_costales |
This is pre-release 0.5 (rcs numbering) which includes: The milter source files and Makefile A regressive testing subdirectory with Makefile and /bin/sh scripts. A patches subdirectory with a patch file for V8.13 sendmail All have been compiled and tested on a 64bit Sun Solaris 9 machine. |