/************************************************************ ** $Id: edit.c,v 0.6 2003/11/09 17:25:21 bcx Exp bcx $ ** ** 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. ** ** The is the slowedit interface for the milter. ** *************************************************************/ # define EXTERN extern # include "slow.h" extern PRIV *Priv; /* in test.c */ extern struct smfi_str Ctx; /* in test.c */ typedef struct { char *token; int mode; } EDITCOMMANDS; EDITCOMMANDS EditCommands[] = { # define EDITCOM_ADD 1 {"add", EDITCOM_ADD}, /* add an IP event */ # define EDITCOM_DELETE 2 {"delete", EDITCOM_DELETE}, /* delete an IP and all its events */ # define EDITCOM_ALIAS 3 {"alias", EDITCOM_ALIAS}, /* add an IP alias */ # define EDITCOM_WHITE 4 {"whitelist", EDITCOM_WHITE}, /* whitelist an IP address */ # define EDITCOM_TRIM 5 {"trim", EDITCOM_TRIM}, /* remove an event from an IP */ {NULL, 0}, }; bool slowedit(int opt, int argc, char **argv) { int ret, mode; EDITCOMMANDS *e; char *user; extern char *optarg; /* * Format of an edit command is "slowedit command switches IP * On entry to this routine, argv[0] is the command. */ mode = 0; for (e = EditCommands; e->token != NULL; ++e) { if (strcasecmp(argv[opt], e->token) == 0) { mode = e->mode; break; } } if (mode == 0) { printf("Usage: slowedit "); for (e = EditCommands; e->token != NULL; ++e) printf("%s%s", e == EditCommands ? "" : "|", e->token); printf("\n"); return FALSE; } test_init(TRUE); ret = 0; user = cuserid(NULL); switch(mode) { /* add IP event */ case EDITCOM_ADD: ret = slowadd(user, opt, argc, argv); break; case EDITCOM_DELETE: ret = slowdelete(user, opt, argc, argv); break; case EDITCOM_ALIAS: ret = slowalias(user, opt, argc, argv); break; case EDITCOM_WHITE: ret = slowwhite(user, opt, argc, argv); break; case EDITCOM_TRIM: ret = slowtrim(user, opt, argc, argv); break; } return ret; } bool slowadd(char *user, int opt, int argc, char **argv) { PRIMARY_DATUM ip; char *iptext; char *event_str; char logprefix[BUFSIZ]; ++opt; if ((argc - opt) < 2) { (void) printf("Usage: slowedit add IPnumber \"event,event,...\"\n"); return FALSE; } iptext = try_strdup(__FILE__, __LINE__, argv[opt]); ++opt; event_str = try_strdup(__FILE__, __LINE__, argv[opt]); if (slowsetpriv(iptext, event_str) == FALSE) return FALSE; if (user == NULL) sprintf(logprefix, "edit add: "); else sprintf(logprefix, "%s added: ", user); LogPrefix = logprefix; if (push_to_db(&Ctx, Priv) != SMFIS_CONTINUE) return FALSE; (void) free(event_str); return TRUE; } bool slowdelete(char *user, int opt, int argc, char **argv) { printf("slowedit delete\n"); return TRUE; } bool slowalias(char *user, int opt, int argc, char **argv) { printf("slowedit alias\n"); return TRUE; } bool slowwhite(char *user, int opt, int argc, char **argv) { printf("slowedit white\n"); return TRUE; } bool slowtrim(char *user, int opt, int argc, char **argv) { printf("slowedit trim\n"); return TRUE; } typedef struct { char *event; int index; } EVENT_LIST; EVENT_LIST EventList[] = { # define EVENT_ENVRCPTS 1 {"er", EVENT_ENVRCPTS}, /* envelope recipients */ # define EVENT_HDRRCPTS 2 {"hr", EVENT_HDRRCPTS}, /* header recipients */ # define EVENT_HONEYRCPTS 3 {"ho", EVENT_HONEYRCPTS}, /* honey pot recipients */ # define EVENT_BADRCPTS 4 {"br", EVENT_BADRCPTS}, /* bad envelope recipients */ # define EVENT_TOOHDR 5 {"hed", EVENT_TOOHDR}, /* too many header recipients */ # define EVENT_TOOENV 6 {"env", EVENT_TOOENV}, /* too many envelope recipients */ # define EVENT_HONEY 7 {"hon", EVENT_HONEY}, /* one or more honey pots rcpts */ # define EVENT_MSGID 8 {"mid", EVENT_MSGID}, /* bad or missing message-id header */ # define EVENT_FROMH 9 {"frm", EVENT_FROMH}, /* bad or missing message-id header */ # define EVENT_BADHO 10 {"bho", EVENT_BADHO}, /* bad or missing message-id header */ # define EVENT_RBL 11 {"rbl", EVENT_RBL}, /* bad or missing message-id header */ # define EVENT_MILT 12 {"abo", EVENT_MILT}, /* bad or missing message-id header */ # define EVENT_ADVW 13 {"pip", EVENT_ADVW}, /* bad or missing message-id header */ # define EVENT_FORGE 14 {"for", EVENT_FORGE}, /* bad or missing message-id header */ # define EVENT_FROMMX 15 {"mmx", EVENT_FROMMX}, /* bad or missing message-id header */ # define EVENT_NOTINET 16 {"net", EVENT_NOTINET}, /* bad or missing message-id header */ {NULL, 0}, }; int is_event(char *str) { EVENT_LIST *e; for (e = EventList; e->event != NULL; ++e) { if (strcasecmp(e->event, str) == 0) return e->index; } return 0; } bool slowsetpriv(char *iptext, char *estr) { char **list, **l; char **equate; char *item; int value; int index; list = mkargv(estr, ','); if (list == NULL) { (void) printf("slowedit: events missing\n"); return FALSE; } if (isdebug(BUG_EDIT)) print_list("slowsetpriv", list, stdout); for (l = list; *l != NULL; l++) { value = 0; if (strchr(*l, '=') != NULL) { equate = mkargv(*l, '='); if (equate == NULL) continue; item = try_strdup(__FILE__, __LINE__, equate[0]); if (equate[1] != NULL) value = atoi(equate[1]); else milterr(Prog, __FILE__, __LINE__, FALSE, EINVAL, item, "Expected =value"); } else item = try_strdup(__FILE__, __LINE__, *l); index = is_event(item); if (index == 0) { milterr(Prog, __FILE__, __LINE__, FALSE, EINVAL, item, "Unrecognized event keyword"); } switch(index) { /* count of envelope recipients */ case EVENT_ENVRCPTS: if (value <= 0) { milterr(Prog, __FILE__, __LINE__, FALSE, EINVAL, item, "May not have a value zero or less"); } Priv->envrcpts = value; break; case EVENT_HDRRCPTS: if (value <= 0) { milterr(Prog, __FILE__, __LINE__, FALSE, EINVAL, item, "May not have a value zero or less"); } Priv->nhdrrcpts = value; break; case EVENT_HONEYRCPTS: if (value <= 0) { milterr(Prog, __FILE__, __LINE__, FALSE, EINVAL, item, "May not have a value zero or less"); } Priv->honeyrcpts = value; break; case EVENT_BADRCPTS: if (value <= 0) { milterr(Prog, __FILE__, __LINE__, FALSE, EINVAL, item, "May not have a value zero or less"); } Priv->badrcpts = value; break; case EVENT_TOOHDR: set_bit(BIT_TOO_MANY_HDR_RCPTS, Priv->bits); break; case EVENT_TOOENV: set_bit(BIT_TOO_MANY_ENV_RCPTS, Priv->bits); break; case EVENT_HONEY: set_bit(BIT_GOT_HONEYPOT, Priv->bits); break; case EVENT_MSGID: set_bit(BIT_BAD_MSG_ID, Priv->bits); break; case EVENT_FROMH: set_bit(BIT_BAD_FROM_HEAD, Priv->bits); break; case EVENT_BADHO: set_bit(BIT_BAD_HOST, Priv->bits); break; case EVENT_RBL: set_bit(BIT_RBL_BAD, Priv->bits); break; case EVENT_MILT: set_bit(BIT_MILTER_ABORTED, Priv->bits); break; case EVENT_ADVW: set_bit(BIT_ADVANCEWRITE, Priv->bits); break; case EVENT_FORGE: set_bit(BIT_FORGED, Priv->bits); break; case EVENT_FROMMX: set_bit(BIT_FROMMX, Priv->bits); break; case EVENT_NOTINET: set_bit(BIT_NOTINET, Priv->bits); break; } (void) free(item); } Priv->iptxt = iptext; return TRUE; }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#6 | 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. |
||
#5 | 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 |
||
#4 | 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. |
||
#3 | 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. |
||
#2 | 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. |
||
#1 | 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 |