mailfront-1.16/0000775000076400007640000000000011356700500012776 5ustar bruceguentermailfront-1.16/plugin-reject.c0000664000076400007640000000102211356700500015705 0ustar bruceguenter#include #include "mailfront.h" static response resp; static const response* sender(str* s) { const char* sr; if ((sr = getenv("SMTPREJECT")) != 0 || (sr = getenv("REJECT")) != 0) { if (sr[0] == '-') { ++sr; resp.number = 553; } else resp.number = 451; resp.message = (sr[0] != 0) ? sr : "You are not allowed to use this mail server."; return &resp; } return 0; (void)s; } struct plugin plugin = { .version = PLUGIN_VERSION, .sender = sender, }; mailfront-1.16/backend-echo.c0000664000076400007640000000353011356700500015446 0ustar bruceguenter#include #include #include #include #include #include "mailfront.h" static response resp = { 250, 0 }; static str tmp; static unsigned long databytes = 0; static const response* reset(void) { databytes = 0; return 0; } static const response* sender(str* s) { str_copys(&tmp, "Sender='"); str_cat(&tmp, s); str_cats(&tmp, "'."); resp.message = tmp.s; return &resp; } static const response* recipient(str* r) { str_copys(&tmp, "Recipient='"); str_cat(&tmp, r); str_cats(&tmp, "'."); resp.message = tmp.s; return &resp; } static const response* data_block(const char* bytes, unsigned long len) { if (databytes == 0) { /* First line is always Received, log the first two lines. */ const char* ch; ch = strchr(bytes, '\n'); str_copyb(&tmp, bytes, ch-bytes); bytes = ch + 1; if ((ch = strchr(bytes, '\n')) != 0) str_catb(&tmp, bytes, ch-bytes); msg1(tmp.s); } databytes += len; return 0; } static const response* message_end(int fd) { struct stat st; char buf[1024]; long rd; char* lf; char* ptr; if (fd >= 0) { /* Log the first two lines of the message, usually a Received: header */ lseek(fd, 0, SEEK_SET); rd = read(fd, buf, sizeof buf - 1); buf[rd] = 0; if ((lf = strchr(buf, LF)) != 0) { str_copyb(&tmp, buf, lf-buf); ptr = lf + 1; if ((lf = strchr(ptr, LF)) != 0) str_catb(&tmp, ptr, lf-ptr); msg1(tmp.s); } fstat(fd, &st); databytes = st.st_size; } str_copys(&tmp, "Received "); str_catu(&tmp, databytes); str_cats(&tmp, " bytes."); resp.message = tmp.s; return &resp; (void)fd; } struct plugin backend = { .version = PLUGIN_VERSION, .reset = reset, .sender = sender, .recipient = recipient, .data_block = data_block, .message_end = message_end, }; mailfront-1.16/plugin-template.html0000664000076400007640000000057511356700500017002 0ustar bruceguenter

mailfront

Plugin: accept


This plugin ...

Configuration

None

(defaults to )

Sender Action

None

Recipient Action

None

Data Action

None

Message Action

None

mailfront-1.16/FILES0000664000076400007640000000310311356700500013560 0ustar bruceguenterANNOUNCEMENT AUTOFILES COPYING ChangeLog FILES INSTHIER Makefile NEWS README SRCFILES TARGETS TODO VERSION backend-echo.c backend-echo.html backend-qmail.c backend-qmail.html builtins.c conf-bgincs conf-bglibs conf-bin conf-cc conf-ccso conf-include conf-ld conf-modules conf-qmail constants.h getprotoenv.c imapfront-auth.c imapfront.html iobytes.c mailfront-1.16.spec mailfront-internal.h mailfront.c mailfront.h mailfront.html mailrules.html mailrulesx.html modules.c msa.html netstring.c plugin-accept-recipient.html plugin-accept-sender.html plugin-accept.html plugin-add-received.c plugin-add-received.html plugin-api.html plugin-check-fqdn.c plugin-check-fqdn.html plugin-clamav.c plugin-clamav.html plugin-counters.c plugin-counters.html plugin-cvm-validate.c plugin-cvm-validate.html plugin-force-file.c plugin-force-file.html plugin-mailrules.c plugin-mailrules.html plugin-patterns.c plugin-patterns.html plugin-qmail-validate.c plugin-qmail-validate.html plugin-reject.c plugin-reject.html plugin-relayclient.c plugin-relayclient.html plugin-require-auth.c plugin-require-auth.html plugin-spamassassin.c plugin-spamassassin.html plugin-template.c plugin-template.html pop3-capa.c pop3-mainloop.c pop3-response.c pop3.h pop3front-auth.c pop3front-maildir.c pop3front.html protocol-qmqp.c protocol-qmqp.html protocol-qmtp.c protocol-qmtp.html protocol-smtp.c protocol-smtp.html qmqpfront-echo.sh qmqpfront-qmail.sh qmtp-respond.c qmtp.h qmtpfront-echo.sh qmtpfront-qmail.sh responses.c responses.h session.c smtpfront-echo.sh smtpfront-qmail.sh std-handle.html tests.sh timeout.c warn-auto.sh mailfront-1.16/NEWS0000664000076400007640000004664411356700500013513 0ustar bruceguenter------------------------------------------------------------------------------- Changes in version 1.16 - Added missing plugin-spamassassin.so to installation. - Fix bug in handling invalid message numbers in retrieving messages in pop3front-maildir. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 1.15 - Added a SpamAssassin scanning plugin. - Optimized pop3front-maildir to avoid stat'ing each message twice, and to use sizes recorded in the filename to avoid stat'ing entirely. See pop3front.html for details on the filenames. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 1.12 - Fixed problem with overwriting existing session data items. - Fixed several problems with handling of databytes in rules. - Fixed crash in plugin cvm-validate when the lookup secret was unset. - pop3front-auth now supports a no-argument variant on the AUTH command, used by KMail to test for authentication modes, and documented in http://www.tools.ietf.org/html/draft-myers-sasl-pop3-05 Thanks Bernhard Graf for the initial patch - pop3front-auth and -maildir now support the CAPA command. Thanks Bernhard Graf for the initial patch - Made imapfront-auth more compatible with Courier IMAP by adding extra bits to the CAPABILITY command. Thanks Bernhard Graf. - plugin-cvm-validate handles modules that provide an "out of scope" fact by passing to the next plugin. - Fixed handling of addresses without a domain in @file rules. Thanks Jorge Valdes Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 1.11 - Fixed the main mailfront program to clean up temporary files properly. - Modified the SMTP protocol module to export the SASL authentication information internally. - Modified the check-fqdn plugin to append $DEFAULTHOST and $DEFAULTDOMAIN to addresses if necessary. - Added separate connect and send timeouts and a maximum message size to the ClamAV plugin, and fixed a bug with handling port numbers when using multiple IPs. - Modified the ClamAV plugin to prefer $CLAMAV_* settings over $CLAMD_* - Added plugin API documentation. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 1.10 - Added a ClamAV virus scanner plugin. Note: Using this plugin will cause mailfront to save messages to temporary files. See mailfront.html for details. - Modified the plugin API to add a version code, a flags word, and to (optionally) save messages to a temporary file. - Fixed a few cases where the UCSPI-TCP protocol was assumed. - Fixed pop3front-maildir breakage on dietlibc/uClibc and empty maildirs. Thanks Wayne Marshall. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 1.01 - Fixed a bug in the counters plugin that triggered a problem in the SMTP protocol when handling the SIZE=# parameter. - Reversed the order of cvm-validate and qmail-validate in the wrapper scripts (and documentation) due to the semantics of the two plugins. - Added a list of built-in plugins. The list currently contains the three accept* plugins, which are extremely trivial. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 1.0 Mailfront has been rewritten to be totally modular. The core mailfront program loads the protocol, backend, and all plugin behaviors at run time from shared objects. The previous commands, such as smtpfront-qmail, are now shell script wrappers for the main "mailfront" command, and as such are depricated in favor of using "mailfront" directly. The *front-qmail wrappers preload all the plugins that were previously compiled into the corresponding programs: check-fqdn counters mailrules relayclient cvm-validate qmail-validate add-received patterns accept-sender NOTE: The *front-reject backends have been dropped in favor of a plugin. In addition, the $REQUIRE_AUTH feature has been moved to another plugin. If you used this backend or feature you will need to adjust your configuration accordingly. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.98.1 - Fixed the $REQUIRE_AUTH feature to properly check for $RELAYCLIENT being set. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.98 - Added enhanced mail system status codes (RFC 1893/2034). - Added support for rejecting all mail unless client is authenticated (either as a relay client or with SMTP authentication) if $REQUIRE_AUTH is set. - Full domain names are now required in all addresses except for the null sender. - Removed the "bounce must have a single recipient" rule, as it is currently causing more problems (with address checkers) than it is solving (spammers no longer use this technique). - Fixed one-off bug in counting recipients for $MAXRCPTS. - Truncate UIDL responses to 70 characters as per RFC 1939. - Added QMQP and QMTP "reject" front ends, for completeness. The enhanced mail system status codes together with the $REQUIRE_AUTH change should make smtpfront compliant with RFC 2476's requirements for a "message submission agent", suitable for use on TCP port 587. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.97 - Add support to the qmail backend for custom qmail-queue error messages taken from $QQERRMSG_#. - Clear session timeouts (via alarm) before executing authenticated commands in imapfront-auth and pop3front-auth. - Fixed typo in the CVM lookup code that would prevent the proper operation of lookup secrets. Thanks Dale Woolridge. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.96 - Switched Pattern matching from the simpler mechanism (originated in multilog) to standard shell glob. - Fixed the SMTP front-end's inability to handle quoted or escaped characters, or to strip source routing addresses. - Fixed smtpfront-reject crashing on receipt of EHLO. Thanks Janos Farkas. - Fixed extern/static conflict in smtp-respond.c. Thanks Gerrit Pape. NOTE: The pattern matching change has the (small) potential to break existing rules' behavior, if the rules were depending on specific behavior of the more simplistic pattern matching used previously. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.95 - Fixed bug in header pattern matching that made it only look at the first header line. Thanks Janos Farkas. - Fixed bug in handling of environment variables when applying multiple rules to the same message. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.94 - Switched to CVM 2 support. - Added support for restricting patterns to match only in headers. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.93 - Fixed bug in pattern matching where the pattern was longer than the line that would other match. - Fixed bug in parsing the databytes column in mail rules. - Fixed omission of not resetting maxdatabytes, which could be set by a rule, after checking for sender rules. - Fixed bug in handling multiple sender or recipient specific rules. - Modified the CVM lookup secret handling to use $CVM_LOOKUP_SECRET just like the latest CVM code, falling back to $LOOKUP_SECRET if that isn't set. - Added seperate $AUTH_TIMEOUT and $AUTH_SESSION_TIMEOUT overrides for the authentication front-ends (imapfront-auth and pop3front-auth). Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.92 - Fixed bug in QMQP front-end that prevented it from accepting relayed messages (relayclient wasn't getting set properly). - Added qmqpfront-echo and qmtpfront-echo test front-ends, for completeness. - Fixed bug in pattern handling that would cause a bogus "out of memory" error if the patterns file had a blank line. - Fixed bug: Only set $MAILDIR in imapfront-auth if the CVM set it. Thanks Charlie Brady. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.91 - Fixed a bug in the CVM lookup code that would cause failures if $LOOKUP_SECRET was not set. Thanks Bernhard Graf. - Explicitly set $MAILDIR in imapfront-auth, to provide the variable for Courier-IMAP's imapd. Thanks Bernhard Graf. - Fixed the generated Received: headers to always put the remote host name in the comment if tcpserver looked it up. This fixes problems with SpamAssassin flagging messages as having forged sender addresses. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.90 - Added support for explicit application of mail rules to senders or recipients, as well as negation of rule patterns. - Fixed a bug in handling patterns that are not after a blank line. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.89 - Added support for content pattern rejection. - Added a new "no-op" mail rule type. - Defer looking up $MAXRCPTS and $RELAYCLIENT as well so that they can be set in the mailrules. - Drop connections after $MAXNOTIMPL unimplemented commands are given. - The qmail home directory may be overridden with $QMAILHOME. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.88 - Fixed handling of "@domain" entries in mailrules lists and CDB files. - Added patch from Marcelo Augusto to allow for limits on the maximum number of recipients per message. - Defer looking up $MAXHOPS and $HEADER_ADD so that they can be set in the mailrules. - Added support for IMAP string literals in imapfront-auth. - smtpfront now exports CVM environment variables after authentication. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.87 - Fixed a bug that prevented looping email detection from working. - Fixed the Received: header generation to match the syntax described in RFC 2821. - Added the link protocol (ie TCP or TCP6) to the Received: header. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.86 - Allow for addition of user-specified headers with $HEADER_ADD. - SMTP front end now logs invalid commands. - Added a hook for CVM validation of recipient addresses. - Added support for RFC 1870 ESMTP SIZE extension. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.85 - Added a QMTP front-end, with many features in common with the SMTP front-end (excluding authentication, of course). - Added a QMQP front-end. - The front-ends optionally add an extra "fixup" Received: header if $FIXUP_RECEIVED_HOST and $FIXUP_RECEIVED_IP are set and differ from $TCPLOCALHOST and $TCPLOCALIP. - Fixed internal variable transposition bug in smtp-commands.c. - Switched to bglibs 1.006 library scheme. - Fixed bug: aborting DATA command does not work, must only give responses once all the data is received. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.81 - Fixed bug: the qmail backend didn't honour $QMAILQUEUE. - Fixed bug: environment variables set multiple times in mail rules would use the first value. - Fixed bug: databytes would not be set internally if $DATABYTES was not set. - Fixed bug: all bounces following the first in a single connection would be rejected. - Fixed bug: The "*" pattern failed to match the empty string. - Abort the DATA command immediately if the databytes limit is reached. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.80 - Fixed bug: setting $SMTPGREETING caused smtpfront to crash when issued HELO or EHLO commands. - Fixed bug: lookups in badmailfrom in smtpfront-qmail did not properly lowercase the address. - Fixed bug: qmail-validate didn't handle wildcards in rcpthosts or morercpthosts.cdb. - Added sender and recipient pattern matching to all SMTP front-ends. See mailrules.html for full details. Development of this version has been sponsored by Mitel Networks Corporation. http://www.mitel.com/ http://www.e-smith.com/ ------------------------------------------------------------------------------- Changes in version 0.77 - Added missing imapfront-auth to insthier. - Made smtpfront-qmail handle wildcards in badrcptto. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.76 - Fixed missing "OK" bug in imapfront-auth. - Log SASL authenticated credentials and failures. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.75 - Modified pop3front to log all commands and responses. - Added support for $SMTPGREETING to smtpfront. - Added an IMAP front end. Works with Courier IMAP presently. - Switched to using external bglibs. - smtpfront rejects bounce messages with multiple recipients. See http://www.ornl.gov/its/archives/mailing-lists/qmail/2001/12/msg00405.html - Added a session timeout, controlled by $SESSION_TIMEOUT, defaults to 24 hours. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.74 - Modified quit code in pop3front to properly tag only read messages as "read". - Implemented the obsolete LAST command. - Messages are now sorted in numerical order of their UID. - Added an exit hook to both pop3front and smtpfront to print the number of bytes input and output. - Fixed a one-off bug in handling "@domain" entries in badmailfrom in smtpfront-qmail. - pop3front-auth now logs the user name. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.73 - Fixed bugs in the RETR/TOP function of pop3front-maildir which would cause message corruption. - Fixed bugs in the DELE/STAT functions of pop3front-maildir which neglected to remove the deleted message count/bytes from the totals reported by STAT. - Added a "maximum message count" option to pop3front-maildir, which limits the number of visible messages. - Added timeouts to pop3front. - All POP3 error responses are now printed to stderr. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.72 - This version includes a one-off bug fix in the CVM client code. - Added the missing pop3front-* targets in insthier.c - Added missing Solaris/SysV -lsocket -lnsl linker flags. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.71 - Log the parameters to the MAIL and RCPT commands in smtpfront. - Fixed missing lowercase conversion when handling validating domain names against rcpthosts and company. - Fixed a number of bugs in the SASL implementation. SMTP AUTH PLAIN and/or LOGIN have now been tested with Mozilla Mail (PLAIN), Pegasus (PLAIN I think), PMMail (LOGIN), The Bat (PLAIN), Eudora (LOGIN), and Outlook Express (LOGIN). Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.70 - Added a POP3 authenticator and maildir handler, complete with support for the RFC 1734 AUTH command. If you can believe it, the maildir portion is actually smaller than qmail-pop3d, and just as functional! - Fixed the AUTH PLAIN mechanism in the cvm-sasl library. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.60 - Adds support for the SMTP AUTH command, supporting LOGIN, PLAIN, and CRAM-MD5 mechanisms via CVM. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- mailfront-1.16/responses.c0000664000076400007640000000046311356700500015166 0ustar bruceguenter#include "responses.h" RESPONSE(accepted, 250, "2.6.0 Message accepted."); RESPONSE(internal, 451, "4.3.0 Internal error."); RESPONSE(oom, 451, "4.3.0 Out of memory."); int number_ok(const response* r) { return r->number < 400; } int response_ok(const response* r) { return r == 0 || number_ok(r); } mailfront-1.16/plugin-counters.c0000664000076400007640000000665311356700500016312 0ustar bruceguenter#include "mailfront.h" static RESPONSE(too_long, 552, "5.2.3 Sorry, that message exceeds the maximum message length."); static RESPONSE(hops, 554, "5.6.0 This message is looping, too many hops."); static RESPONSE(manyrcpt, 550, "5.5.3 Too many recipients"); static unsigned rcpt_count = 0; static unsigned long data_bytes; /* Total number of data bytes */ static unsigned count_rec; /* Count of the Received: headers */ static unsigned count_dt; /* Count of the Delivered-To: headers */ static int in_header; /* True until a blank line is seen */ static unsigned linepos; /* The number of bytes since the last LF */ static int in_rec; /* True if we might be seeing Received: */ static int in_dt; /* True if we might be seeing Delivered-To: */ static unsigned long minenv(const char* sname, const char* name) { unsigned long u; unsigned long value = session_getenvu(name); u = 0; if (value > 0) if (!session_hasnum(sname, &u) || u > value) { session_setnum(sname, value); return value; } return u; } static const response* init(void) { /* This MUST be done in the init section to make sure the SMTP * greeting displays the current value. */ minenv("maxdatabytes", "DATABYTES"); return 0; } static const response* reset(void) { minenv("maxdatabytes", "DATABYTES"); rcpt_count = 0; return 0; } static const response* sender(str* r) { /* This MUST be done as a sender match to make sure SMTP "MAIL FROM" * commands with a SIZE parameter can be rejected properly. */ minenv("maxdatabytes", "DATABYTES"); minenv("maxrcpts", "MAXRCPTS"); (void)r; return 0; } static const response* recipient(str* r) { unsigned long maxrcpts = minenv("maxrcpts", "MAXRCPTS"); minenv("maxdatabytes", "DATABYTES"); ++rcpt_count; if (maxrcpts > 0 && rcpt_count > maxrcpts) return &resp_manyrcpt; return 0; (void)r; } static const response* start(int fd) { unsigned long maxhops; minenv("maxdatabytes", "DATABYTES"); if ((maxhops = session_getenvu("MAXHOPS")) == 0) maxhops = 100; session_setnum("maxhops", maxhops); data_bytes = 0; count_rec = 0; count_dt = 0; in_header = 1; linepos = 0; in_rec = 1; in_dt = 1; return 0; (void)fd; } static const response* block(const char* bytes, unsigned long len) { unsigned i; const char* p; const unsigned long maxdatabytes = session_getnum("maxdatabytes", ~0UL); const unsigned long maxhops = session_getnum("maxhops", 100); data_bytes += len; if (maxdatabytes > 0 && data_bytes > maxdatabytes) return &resp_too_long; for (i = 0, p = bytes; in_header && i < len; ++i, ++p) { char ch = *p; if (ch == LF) { if (linepos == 0) in_header = 0; linepos = 0; in_rec = in_dt = in_header; } else { if (in_header && linepos < 13) { if (in_rec) { if (ch != "received:"[linepos] && ch != "RECEIVED:"[linepos]) in_rec = 0; else if (linepos >= 8) { in_dt = in_rec = 0; if (++count_rec > maxhops) return &resp_hops; } } if (in_dt) { if (ch != "delivered-to:"[linepos] && ch != "DELIVERED-TO:"[linepos]) in_dt = 0; else if (linepos >= 12) { in_dt = in_rec = 0; if (++count_dt > maxhops) return &resp_hops; } } ++linepos; } } } return 0; } struct plugin plugin = { .version = PLUGIN_VERSION, .init = init, .reset = reset, .sender = sender, .recipient = recipient, .data_start = start, .data_block = block, }; mailfront-1.16/tests.sh0000664000076400007640000015640711356700500014511 0ustar bruceguenter#!/bin/sh src=`pwd` tmp=$src/tests-tmp rm -rf $tmp mkdir -p $tmp PATH="$src:/bin:/usr/bin:/usr/local/bin" tests_failed=0 tests_count=0 _UID=`id -u` _GID=`id -g` usage() { echo "usage: sh $0 [-v]" } vecho() { :; } while getopts v flag do case $flag in v) vecho() { echo "$*"; } ;; *) usage; exit 1 ;; esac done sfecho() { $src/mailfront smtp echo "$@" 2>/dev/null \ | grep -v '^220 local.host mailfront ESMTP' } pfauth() { $src/pop3front-auth "$@" echo Yes. 2>/dev/null \ | tail -n +2 } ifauth() { $src/imapfront-auth sh -c 'echo Yes: $IMAPLOGINTAG' 2>/dev/null \ | grep -v '^\* OK imapfront ready.' } pfmaildir() { $src/pop3front-maildir "$@" 2>/dev/null \ | tail -n +2 } maildir=$tmp/Maildir maildir() { rm -rf $maildir mkdir -p $maildir/cur mkdir -p $maildir/new mkdir -p $maildir/tmp } tstmsg() { fn=$1 { echo "Header: foo" echo echo "body" } >$maildir/$fn } PROTO=TEST TESTLOCALIP=1.2.3.4 TESTREMOTEIP=5.6.7.8 TESTLOCALHOST=local.host TESTREMOTEHOST=remote.host CVM_PWFILE_PATH=$tmp/pwfile MODULE_PATH=$src PLUGINS=accept export PROTO TESTLOCALIP TESTREMOTEIP TESTLOCALHOST TESTREMOTEHOST export CVM_PWFILE_PATH MAILRULES DATABYTES MAXHOPS PATTERNS MAXNOTIMPL export PLUGINS MODULE_PATH echo testuser:testpass:$_UID:$_GID:Test User:$tmp:/bin/false >$CVM_PWFILE_PATH ln -s `which cvm-pwfile` $tmp/cvm run_compare_test() { local name=$1 shift sed -e "s:@SOURCE@:$src:g" -e "s:@TMPDIR@:$tmp:g" -e "s:@UID@:$_UID:" -e "s:@GID@:$_GID:" >$tmp/expected ( runtest "$@" 2>&1 ) 2>&1 >$tmp/actual-raw cat -v $tmp/actual-raw >$tmp/actual if ! cmp $tmp/expected $tmp/actual >/dev/null 2>&1 then echo "Test $name $@ failed:" ( cd $tmp; diff -U 9999 expected actual | tail -n +3; echo; ) tests_failed=$(($tests_failed+1)) fi rm -f $tmp/expected $tmp/actual tests_count=$(($tests_count+1)) } ##### Test tests/smtpfront-looping-received ##### runtest() { PLUGINS=counters:accept MAXHOPS=1 sfecho < RCPT TO: DATA Received: foo . EOF echo sfecho < RCPT TO: DATA Received: foo Received: foo . EOF } vecho Running test tests/smtpfront-looping-received run_compare_test tests/smtpfront-looping-received </dev/null < RCPT TO: EOF } vecho Running test tests/plugins-remove 'reject' run_compare_test tests/plugins-remove 'reject' </dev/null ls $maildir/cur ls $maildir/new echo UIDL | pfmaildir $maildir echo LIST | pfmaildir $maildir } vecho Running test tests/pop3front-maildir-size run_compare_test tests/pop3front-maildir-size <$tmp/rules < RCPT TO: EOF rm -f $tmp/rules } vecho Running test tests/rules-noop run_compare_test tests/rules-noop <$tmp/patterns < RCPT TO: DATA header1: data header2: another field not also . EOF echo cat >$tmp/patterns < RCPT TO: DATA header not also . EOF rm -f $tmp/patterns } vecho Running test tests/patterns-header run_compare_test tests/patterns-header < $maildir/new/1.2.3 </dev/null USER testuser PASS testpass EOF pfauth $tmp/cvm </dev/null USER testuser PASS testpasx EOF } vecho Running test tests/pop3front-auth-userpass run_compare_test tests/pop3front-auth-userpass <$tmp/rules < SIZE=10000 RCPT TO: DATA testing . EHLO hostname MAIL FROM: SIZE=10000 RCPT TO: RCPT TO: DATA testing . EHLO hostname MAIL FROM: SIZE=10000 RCPT TO: RCPT TO: RCPT TO: DATA testing . EOF rm -f $tmp/rules } vecho Running test tests/rules-databytes2 run_compare_test tests/rules-databytes2 <$tmp/rules < RCPT TO: MAIL FROM: RCPT TO: RCPT TO: MAIL FROM: RCPT TO: RCPT TO: EOF rm -f $tmp/rules } vecho Running test tests/rules-both run_compare_test tests/rules-both <$tmp/rules < MAIL FROM: MAIL FROM: EOF rm -f $tmp/rules } vecho Running test tests/rules-multiline run_compare_test tests/rules-multiline </dev/null < RCPT TO: EOF } vecho Running test tests/plugin-reject 'rej' run_compare_test tests/plugin-reject 'rej' < RCPT TO: DATA . EOF unset TMPDIR } vecho Running test tests/plugin-force-file '/tmp' '' run_compare_test tests/plugin-force-file '/tmp' '' < RCPT TO: DATA Subject: test foo .. bar . MAIL FROM: RCPT TO: DATA Subject: test foo .. bar . EOF } vecho Running test tests/smtpfront-content run_compare_test tests/smtpfront-content </dev/null echo } vecho Running test tests/qmtpfront-echo run_compare_test tests/qmtpfront-echo < RCPT TO: AUTH PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M= MAIL FROM: RCPT TO: EOF unset CVM_SASL_PLAIN unset REQUIRE_AUTH } vecho Running test tests/smtpfront-require-auth run_compare_test tests/smtpfront-require-auth < RCPT TO: RCPT TO: EOF CVM_LOOKUP_SECRET=test export CVM_LOOKUP_SECRET echo sfecho < RCPT TO: RCPT TO: EOF unset CVM_LOOKUP CVM_LOOKUP_SECRET } vecho Running test tests/plugin-cvm-validate run_compare_test tests/plugin-cvm-validate </dev/null $tmp/rules < RCPT TO: RCPT TO: MAIL FROM: RCPT TO: RCPT TO: EOF rm -f $tmp/rules } vecho Running test tests/rules-selector run_compare_test tests/rules-selector </dev/null echo } vecho Running test tests/qmqpfront-echo run_compare_test tests/qmqpfront-echo < RCPT TO: RCPT TO: RCPT TO: RCPT TO: EOF unset MAXRCPTS } vecho Running test tests/smtpfront-maxrcpts run_compare_test tests/smtpfront-maxrcpts </dev/null < RCPT TO: EOF } vecho Running test tests/plugins-prepend run_compare_test tests/plugins-prepend <$tmp/rules <$tmp/list <$tmp/atlist </dev/null | tail -n +2 MAIL FROM: RCPT TO: RCPT TO: RCPT TO: RCPT TO: RCPT TO: RCPT TO: RCPT TO: EOF rm -f $tmp/rules $tmp/list $tmp/atlist } vecho Running test tests/rules-rcptlist run_compare_test tests/rules-rcptlist < RCPT TO: DATA Delivered-To: foo . EOF echo sfecho < RCPT TO: DATA Delivered-To: foo Delivered-To: foo . EOF } vecho Running test tests/smtpfront-looping-delivered-to run_compare_test tests/smtpfront-looping-delivered-to <$tmp/rules < MAIL FROM: SIZE MAIL FROM: SIZE= MAIL FROM: SIZE=100 MAIL FROM: SIZE=123 MAIL FROM: SIZE=124 RCPT TO: MAIL FROM: RCPT TO: DATA datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata . EHLO hostname MAIL FROM: RCPT TO: DATA datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata . EOF rm -f $tmp/rules } vecho Running test tests/rules-databytes3 run_compare_test tests/rules-databytes3 <&1 >/dev/null < RCPT TO: DATA . EOF } vecho Running test tests/received '' '' '' '' '' run_compare_test tests/received '' '' '' '' '' <$tmp/rules < MAIL FROM: SIZE MAIL FROM: SIZE= MAIL FROM: SIZE=100 MAIL FROM: SIZE=123 MAIL FROM: SIZE=124 RCPT TO: EOF rm -f $tmp/rules } vecho Running test tests/rules-databytes run_compare_test tests/rules-databytes <$tmp/patterns < RCPT TO: DATA before after . EOF rm -f $tmp/patterns } vecho Running test tests/patterns-message run_compare_test tests/patterns-message < RCPT TO: AUTH LOGIN dGVzdHVzZXI= dGVzdHBhc3x= AUTH LOGIN dGVzdHVzZXI= dGVzdHBhc3M= AUTH LOGIN MAIL FROM: RCPT TO: EOF sfecho << EOF AUTH LOGIN dGVzdHVzZXI= dGVzdHBhc3M= EOF sfecho < RCPT TO: EOF unset CVM_SASL_PLAIN } vecho Running test tests/smtpfront-auth-login run_compare_test tests/smtpfront-auth-login < RCPT TO:<"you, yourself, and you"@example.com> RCPT TO: RCPT TO:<@somewhere,@elsewhere:two@example.com> EOF } vecho Running test tests/smtpfront-quotes run_compare_test tests/smtpfront-quotes <$tmp/patterns < RCPT TO: DATA before after . EOF rm -f $tmp/patterns } vecho Running test tests/patterns-normal run_compare_test tests/patterns-normal <$tmp/rules < RCPT TO: RCPT TO: RCPT TO: RCPT TO: RCPT TO: EOF rm -f $tmp/rules } vecho Running test tests/rules-recip run_compare_test tests/rules-recip <$tmp/rules < MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM:<> MAIL FROM:<1@2@example.com@example.com> EOF rm -f $tmp/rules } vecho Running test tests/rules-asterisk run_compare_test tests/rules-asterisk <$tmp/rules < MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: EOF rm -f $tmp/rules } vecho Running test tests/rules-sender run_compare_test tests/rules-sender <$tmp/rules < RCPT TO: DATA Received: hop1 Received: hop2 . EOF MAILRULES=$tmp/rules sfecho < RCPT TO: DATA Received: hop1 Received: hop1 . EOF rm -f $tmp/rules } vecho Running test tests/rules-maxhops run_compare_test tests/rules-maxhops <$tmp/rules < MAIL FROM: EOF rm -f $tmp/rules } vecho Running test tests/rules-empty run_compare_test tests/rules-empty <$tmp/rules < MAIL FROM: MAIL FROM: RCPT TO: RCPT TO: RCPT TO: EOF rm -f $tmp/rules } vecho Running test tests/rules-defaultmsg run_compare_test tests/rules-defaultmsg <$QMAILHOME/control/badmailfrom echo @badfrom.com >>$QMAILHOME/control/badmailfrom echo rcpthost.com >$QMAILHOME/control/rcpthosts echo .subrcpthost.com >>$QMAILHOME/control/rcpthosts echo badrcpt@example.com >$QMAILHOME/control/badrcptto echo @badrcpt.com >>$QMAILHOME/control/badrcptto cdbmake $QMAILHOME/control/morercpthosts.cdb $QMAILHOME/tmp < +20,0:.submorercpthost.com-> EOF sfecho < MAIL FROM: MAIL FROM: RCPT TO: RCPT TO: RCPT TO: RCPT TO: RCPT TO: RCPT TO: RCPT TO: EOF rm -r $QMAILHOME unset QMAILHOME } vecho Running test tests/plugin-qmail-validate run_compare_test tests/plugin-qmail-validate <$tmp/rules <$tmp/list <$tmp/atlist < MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: EOF rm -f $tmp/rules $tmp/list $tmp/atlist } vecho Running test tests/rules-list run_compare_test tests/rules-list <$tmp/patterns < RCPT TO: DATA Subject: $subject . EOF rm -f $tmp/patterns } vecho Running test tests/patterns-general 'xwordx' run_compare_test tests/patterns-general 'xwordx' </dev/null QUIT NO QUIT QUIT AGAIN EOF } vecho Running test tests/pop3front-auth run_compare_test tests/pop3front-auth < MAIL FROM: SIZE MAIL FROM: SIZE= MAIL FROM: SIZE=100 EOF DATABYTES=123 export DATABYTES sfecho < MAIL FROM: SIZE MAIL FROM: SIZE= MAIL FROM: SIZE=100 MAIL FROM: SIZE=123 MAIL FROM: SIZE=124 RCPT TO: EOF } vecho Running test tests/smtpfront-databytes run_compare_test tests/smtpfront-databytes <$tmp/rules < RCPT TO: DATA . EOF sfecho < RCPT TO: DATA . EOF rm -f $tmp/rules } vecho Running test tests/rules-header-add run_compare_test tests/rules-header-add < RCPT TO: RCPT TO: DATA . EOF sfecho < RCPT TO: DATA . EOF sfecho < RCPT TO: RCPT TO: DATA . EOF } vecho Running test tests/smtpfront-bad-bounce run_compare_test tests/smtpfront-bad-bounce < RCPT TO: AUTH PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3x= AUTH PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M= AUTH PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M= MAIL FROM: RCPT TO: EOF sfecho << EOF AUTH PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M= EOF sfecho < RCPT TO: EOF sfecho << EOF AUTH PLAIN XXXXdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M= EOF unset CVM_SASL_PLAIN } vecho Running test tests/smtpfront-auth-plain run_compare_test tests/smtpfront-auth-plain <$tmp/rules < +12,0:@example.com-> EOF cat < EOF MAILRULES=$tmp/rules sfecho < MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: EOF rm -f $tmp/rules $tmp/list.cdb $tmp/atlist.cdb } vecho Running test tests/rules-cdb run_compare_test tests/rules-cdb <$tmp/rules < MAIL FROM: EOF rm -f $tmp/rules } vecho Running test tests/rules-negate run_compare_test tests/rules-negate <$tmp/patterns < RCPT TO: DATA before after . EOF echo cat >$tmp/patterns < RCPT TO: DATA before after . EOF rm -f $tmp/patterns } vecho Running test tests/patterns-after run_compare_test tests/patterns-after <

MailFront

Plugin: qmail-validate


Configuration

$QMAILHOME
The directory in which qmail resides (defaults to the contents of conf-qmail, which is typically "/var/qmail") The control files listed below are all located in the control subdirectory of this path.

Sender Action

If the sender address is listed in the badmailfrom control file, the sender is rejected. Otherwise no action.

Recipient Action

If the recipient is listed in the badrcptto control file, it is rejected. If the domain of the recipient address is not listed in either the rcpthosts or morercpthosts.cdb control files, the recipient is rejected. Otherwise no action.

Data Action

None

Message Action

None

mailfront-1.16/conf-bin0000664000076400007640000000007611356700500014417 0ustar bruceguenter/usr/local/bin Programs will be installed in this directory. mailfront-1.16/plugin-patterns.c0000664000076400007640000000673511356700500016311 0ustar bruceguenter#include #include #include #include #include #include #include "mailfront.h" struct pattern { int mode; str s; const char* message; }; #define T_AFTER_BLANK ('\\') #define T_RESPONSE ('=') #define T_COMMENT ('#') #define T_HEADER (':') #define T_NORMAL (0) static response resp_patmatch = { 554, 0 }; static struct pattern* pattern_list; static str responses; static unsigned pattern_count; static int linemode; static unsigned linepos; static unsigned linemax = 256; static char* linebuf; static int patterns_read(const char* filename) { ibuf in; int mode; unsigned i; unsigned count; str line = {0,0,0}; const char* currmsg = "This message contains prohibited content"; if (!ibuf_open(&in, filename, 0)) return 0; count = 0; /* Count the number of non-comment lines. */ while (ibuf_getstr(&in, &line, LF)) { str_rstrip(&line); if (line.len > 0 && line.s[0] != T_COMMENT) { if (line.s[0] == T_RESPONSE) /* Pre-allocate room for the responses */ wrap_str(str_catb(&responses, line.s+1, line.len)); else ++count; } } responses.len = 0; /* Allocate the lines. */ if ((pattern_list = malloc(count * sizeof *pattern_list)) == 0) die_oom(111); if (!ibuf_rewind(&in)) die1sys(111, "Could not rewind patterns file"); memset(pattern_list, 0, count * sizeof *pattern_list); for (i = 0; i < count && ibuf_getstr(&in, &line, LF); ) { str_rstrip(&line); if (line.len > 0) { switch (mode = line.s[0]) { case T_COMMENT: continue; case T_RESPONSE: currmsg = responses.s + responses.len; str_catb(&responses, line.s+1, line.len); continue; case T_AFTER_BLANK: case T_HEADER: break; default: mode = T_NORMAL; } pattern_list[i].mode = mode; wrap_str(str_copyb(&pattern_list[i].s, line.s+1, line.len-1)); pattern_list[i].message = currmsg; ++i; } } pattern_count = i; ibuf_close(&in); str_free(&line); return 1; } static const response* init(int fd) { const char* tmp; unsigned u; if ((tmp = session_getenv("PATTERNS")) != 0) if (!patterns_read(tmp)) warn3sys("Could not read patterns file '", tmp, "'"); if ((tmp = session_getenv("PATTERNS_LINEMAX")) != 0) if ((u = strtoul(tmp, (char**)&tmp, 10)) > 0 && *tmp == 0) linemax = u; if ((linebuf = malloc(linemax+1)) == 0) die_oom(111); linemode = T_HEADER; linepos = 0; return 0; (void)fd; } static const response* check_line(void) { unsigned i; struct pattern* p; const str fakeline = { linebuf, linepos, 0 }; linebuf[linepos] = 0; for (p = pattern_list, i = 0; i < pattern_count; ++i, ++p) { if ((p->mode == T_NORMAL || p->mode == linemode) && str_glob(&fakeline, &p->s)) { resp_patmatch.message = p->message; return &resp_patmatch; } } return 0; } static const response* check(const char* bytes, unsigned long len) { const char* p; const char* const end = bytes + len; const response* r; if (linebuf == 0) return 0; for (p = bytes; p < end; ++p) { const char ch = *p; if (ch == LF) { if (linepos > 0) { if ((r = check_line()) != 0) return r; if (linemode != T_HEADER) linemode = T_NORMAL; } else linemode = T_AFTER_BLANK; linepos = 0; } else { if (linepos < linemax) linebuf[linepos++] = ch; } } return 0; } struct plugin plugin = { .version = PLUGIN_VERSION, .data_start = init, .data_block = check, }; mailfront-1.16/conf-cc0000664000076400007640000000013111356700500014224 0ustar bruceguentergcc -W -Wall -Wshadow -O -g -I/usr/local/include This will be used to compile .c files. mailfront-1.16/imapfront-auth.c0000664000076400007640000002251411356700500016104 0ustar bruceguenter/* imapfront-auth.c - IMAP authentication front-end * Copyright (C) 2008 Bruce Guenter or FutureQuest, Inc. * Development of this program was sponsored by FutureQuest, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact information: * FutureQuest Inc. * PO BOX 623127 * Oviedo FL 32762-3127 USA * http://www.FutureQuest.net/ * ossi@FutureQuest.net */ #include #include #include #include #include #include #include #include #include const char program[] = "imapfront-auth"; const int msg_show_pid = 1; #define MAX_ARGC 16 #define QUOTE '"' #define ESCAPE '\\' #define LBRACE '{' #define RBRACE '}' static const char NOTAG[] = "*"; static const char CONT[] = "+"; static const char* capability; static const char* cvm; static const char* domain; static char** nextcmd; static str tag; static str line; static str cmd; static str line_args[MAX_ARGC]; static int line_argc; static struct sasl_auth saslauth = { .prefix = "+ " }; void log_start(const char* tagstr) { obuf_puts(&errbuf, program); obuf_putc(&errbuf, '['); obuf_putu(&errbuf, getpid()); obuf_puts(&errbuf, "]: "); if (tagstr) { obuf_puts(&errbuf, tagstr); obuf_putc(&errbuf, ' '); } } void log_str(const char* msg) { obuf_puts(&errbuf, msg); } void log_end(void) { obuf_putsflush(&errbuf, "\n"); } void logmsg(const char* tagstr, const char* msg) { log_start(tagstr); log_str(msg); log_end(); } void respond_start(const char* tagstr) { if (tagstr == 0) tagstr = tag.s; log_start(tagstr); if (!obuf_puts(&outbuf, tagstr) || !obuf_putc(&outbuf, ' ')) exit(1); } void respond_str(const char* msg) { log_str(msg); if (!obuf_puts(&outbuf, msg)) exit(1); } void respond_end(void) { log_end(); if (!obuf_putsflush(&outbuf, CRLF)) exit(1); } void respond(const char* tagstr, const char* msg) { respond_start(tagstr); respond_str(msg); respond_end(); } #if 0 static int isctl(char ch) { return (ch > 0x1f) && (ch < 0x7f); } static int isquotedspecial(char ch) { return (ch == QUOTE) || (ch == ESCAPE); } static int isatomspecial(char ch) { switch (ch) { case '(': case ')': case '{': case ' ': case '%': case '*': return 0; } return !isctl(ch) && !isquotedspecial(ch); } static int isatom(char ch) { return !isatomspecial(ch); } static int istag(char ch) { return isatom(ch) && (ch != '+'); } #endif /* This parser is rather liberal in what it accepts: The IMAP standard mandates seperate character sets for tags, commands, unquoted strings. Since they all must be seperated by spaces, this parser allows all non-whitespace characters for each of the above. */ static int parse_line(void) { #define RESPOND(T,S) do{ respond(T,S); return 0; }while(0) unsigned i; unsigned len; const char* ptr; str* arg; /* Parse out the command tag */ str_truncate(&tag, 0); for (i = 0, ptr = line.s; i < line.len && isspace(*ptr); ++i, ++ptr) ; for (; i < line.len && !isspace(*ptr); ++i, ++ptr) str_catc(&tag, line.s[i]); if (!tag.len) RESPOND(NOTAG, "BAD Syntax error"); if (i >= line.len) RESPOND(0, "BAD Syntax error"); /* Parse out the command itself */ str_truncate(&cmd, 0); for (; i < line.len && isspace(*ptr); ++i, ++ptr) ; for (; i < line.len && !isspace(*ptr); ++i, ++ptr) str_catc(&cmd, line.s[i]); if (!cmd.len) RESPOND(0, "BAD Syntax error"); /* Parse out the command-line args */ for (line_argc = 0; line_argc < MAX_ARGC; ++line_argc) { arg = &line_args[line_argc]; str_truncate(arg, 0); for (; i < line.len && isspace(*ptr); ++i, ++ptr) ; if (i >= line.len) break; switch (*ptr) { case LBRACE: /* Handle a string literal */ ++i, ++ptr; if (!isdigit(*ptr)) RESPOND(0, "BAD Syntax error: missing integer"); for (len = 0; i < line.len && *ptr != RBRACE; ++i, ++ptr) { if (!isdigit(*ptr)) RESPOND(0, "BAD Syntax error: invalid integer"); len = len * 10 + *ptr - '0'; } ++i, ++ptr; if (*ptr != 0) RESPOND(0, "BAD Syntax error: missing LF after integer"); str_ready(arg, len); respond(CONT, "OK"); if (len > 0) ibuf_read(&inbuf, arg->s, len); arg->s[arg->len = len] = 0; ibuf_getstr_crlf(&inbuf, &line); i = 0; ptr = line.s; break; case QUOTE: /* Handle a quoted string */ for (++i, ++ptr; i < line.len && *ptr != QUOTE; ++i, ++ptr) { if (*ptr == ESCAPE) { if (++i >= line.len) break; ++ptr; } str_catc(arg, *ptr); } if (i >= line.len || *ptr != QUOTE) RESPOND(0, "BAD Syntax error: unterminated quoted string"); ++i, ++ptr; break; default: /* Normal case is very simple */ for (; i < line.len && !isspace(*ptr); ++i, ++ptr) str_catc(arg, *ptr); } } for (; i < line.len && isspace(*ptr); ++i, ++ptr) ; if (i < line.len) RESPOND(0, "BAD Too many command arguments"); return 1; } void cmd_noop(void) { respond(0, "OK NOOP completed"); } void cmd_logout(void) { respond(NOTAG, "Logging out"); respond(0, "OK LOGOUT completed"); exit(0); } void cmd_capability(void) { const char *p; respond_start(NOTAG); respond_str("CAPABILITY IMAP4rev1"); if (*capability != 0) { respond_str(" "); respond_str(capability); } if ((p = getenv("IMAP_ACL")) && atoi(p)) respond_str(" ACL ACL2=UNION"); if ((p = getenv("OUTBOX")) && *p) { respond_str(" XCOURIEROUTBOX=INBOX"); respond_str(p); } if ((p = getenv("IMAP_MOVE_EXPUNGE_TO_TRASH")) && atoi(p)) respond_str(" XMAGICTRASH"); respond_end(); respond(0, "OK CAPABILITY completed"); } void do_exec(void) { if (!cvm_setugid()) respond(0, "NO Internal error: could not set UID/GID"); else if (!cvm_setenv() || (cvm_fact_mailbox != 0 && setenv("MAILDIR", cvm_fact_mailbox, 1) == -1) || setenv("IMAPLOGINTAG", tag.s, 1) == -1 || setenv("AUTHENTICATED", cvm_fact_username, 1) == -1) respond(0, "NO Internal error: could not set environment"); else { alarm(0); execvp(nextcmd[0], nextcmd); respond(0, "NO Could not execute second stage"); } exit(1); } void cmd_login(int argc, str* argv) { int cr; if (argc != 2) respond(0, "BAD LOGIN command requires exactly two arguments"); else { if ((cr = cvm_authenticate_password(cvm, argv[0].s, domain, argv[1].s, 1)) == 0) do_exec(); else respond(0, "NO LOGIN failed"); } } void cmd_authenticate(int argc, str* argv) { int i; if (argc == 1) i = sasl_auth2(&saslauth, argv[0].s, 0); else if (argc == 2) i = sasl_auth2(&saslauth, argv[0].s, argv[1].s); else { respond(0, "BAD AUTHENTICATE command requires only one or two arguments"); return; } if (i == 0) do_exec(); respond_start(0); respond_str("NO AUTHENTICATE failed: "); respond_str(sasl_auth_msg(&i)); respond_end(); } struct command { const char* name; void (*fn0)(void); void (*fn1)(int argc, str* argv); }; struct command commands[] = { { "CAPABILITY", cmd_capability, 0 }, { "NOOP", cmd_noop, 0 }, { "LOGOUT", cmd_logout, 0 }, { "LOGIN", 0, cmd_login }, { "AUTHENTICATE", 0, cmd_authenticate }, { 0, 0, 0 } }; static void dispatch_line(void) { struct command* c; str_upper(&cmd); for (c = commands; c->name != 0; ++c) { if (str_diffs(&cmd, c->name) == 0) { if (line_argc == 0) { if (c->fn0 == 0) respond(0, "BAD Syntax error: command requires arguments"); else c->fn0(); } else { if (c->fn1 == 0) respond(0, "BAD Syntax error: command requires no arguments"); else c->fn1(line_argc, line_args); } return; } } respond(0, "BAD Unimplemented command"); } static int startup(int argc, char* argv[]) { if (argc < 2) { respond(NOTAG, "NO Usage: imapfront-auth imapd [args ...]"); return 0; } if ((domain = cvm_ucspi_domain()) == 0) domain = "unknown"; nextcmd = argv + 1; if ((cvm = getenv("CVM_SASL_PLAIN")) == 0) { respond(NOTAG, "NO $CVM_SASL_PLAIN is not set"); return 0; } if (!sasl_auth_init(&saslauth)) { respond(NOTAG, "NO Could not initialize SASL AUTH"); return 0; } if ((capability = getenv("IMAP_CAPABILITY")) == 0 && (capability = getenv("CAPABILITY")) == 0) capability = ""; if (strncasecmp(capability, "IMAP4rev1", 9) == 0) capability += 9; while (isspace(*capability)) ++capability; return 1; } const int authenticating = 1; extern void set_timeout(void); int main(int argc, char* argv[]) { set_timeout(); if (!startup(argc, argv)) return 0; respond(NOTAG, "OK imapfront ready."); while (ibuf_getstr_crlf(&inbuf, &line)) { if (parse_line()) dispatch_line(); } if (ibuf_timedout(&inbuf)) respond(NOTAG, "NO Connection timed out"); return 0; } mailfront-1.16/protocol-smtp.html0000664000076400007640000000333011356700500016505 0ustar bruceguenter

MailFront

Protocol: smtp


The SMTP protocol module has the following features:

  • Handles RFC 2554 SMTP authentication. Note that the require-auth plugin and/or the relayclient plugin will need to be loaded to make use of this authentication.
  • Automatically handles either bare NL or RFC 821 / RFC 2821 compliant CR/NL end-of-line conventions.
  • Times out connections after $TIMEOUT seconds of inactivity (defaults to 1200 seconds or 20 minutes), or $SESSION_TIMEOUT seconds after the connection was established (defaults to 86400 seconds or 24 hours).
  • All error responses are logged.
  • Handles (ignores) RFC 1869 extended parameters on the RCPT TO: and MAIL FROM: commands.
  • Initial greeting message is configureable by $SMTPGREETING. If that is not set, the greeting is generated based on the domain name in ${$PROTO}LOCALHOST set by the invoking UCSPI server such as tcpserver.
  • Supports RFC 1870 SMTP Service Extension for Message Size Declaration.
  • If $MAXNOTIMPL is set, clients are disconnected if they send more than the specified number of commands that result in a "500 Not implemented." error.
mailfront-1.16/std-handle.html0000664000076400007640000000442111356700500015710 0ustar bruceguenter

MailFront

Standard Handlers


Overview

The most useful protocol front-ends and delivery back-ends are joined by a set of standard handlers. These handlers integrate the operation of mail rules, pattern matching, several miscellaneous options and back-end validation and delivery functions.

Features

The following features are common to all front-ends that use the standard handlers:

  • Validates senders and recipients according to mail rules processing.
  • Requires all addresses except the null sender to contain a fully qualified domain name.
  • If $RELAYCLIENT is set, all recipient addresses not rejected by mail rules are allowed, and its contents are appended to each recipient address. Back-end validation is omitted.
  • Rejects messages that exceed $DATABYTES bytes in length.
  • Counts the number of "Received:" and "Delivered-To:" headers, and rejects the message if more than $MAXHOPS of either are seen (defaults to 100).
  • Optionally adds a fixup "Received:" header for hosts that have different incoming and outgoing hostnames or IPs. Set $FIXUP_RECEIVED_HOST and $FIXUP_RECEIVED_IP if you want this header added.
  • Optional user-specified headers may be added by setting $HEADER_ADD.
  • If $CVM_LOOKUP is set, recipients are sent to the named CVM to see if they are valid. If CVM_LOOKUP_SECRET or $LOOKUP_SECRET are set and not empty, the value is sent as a single credential to the CVM.
  • If $MAXRCPTS is set, the number of recipients allowed per message is limited to that number.
  • Support for pattern matching in the message data.
  • Support for adding additional plugins at run time. Set $PLUGINS to a colon separated list of plugin names, and optionally set $MODULE_PATH to the directory in which those plugins are contained.
  • If $PLUGINS includes require-auth, all mail is rejected unless either $RELAYCLIENT is set or the sender authenticates.

mailfront-1.16/mailfront-1.16.spec0000664000076400007640000000230311356700500016226 0ustar bruceguenterName: mailfront Summary: Mail server network protocol front-ends Version: 1.16 Release: 1 License: GPL Group: Utilities/System Source: http://untroubled.org/mailfront/mailfront-1.16.tar.gz BuildRoot: %{_tmppath}/mailfront-buildroot BuildRequires: bglibs >= 1.101 BuildRequires: cvm-devel >= 0.81 URL: http://untroubled.org/mailfront/ Packager: Bruce Guenter %description This is mailfront, a package containing customizeable network front-ends for mail servers. Handles POP3, QMQP, QMTP, SMTP, and IMAP (authentication only). %package devel Summary: Mailfront development bits Group: Development/Libraries %description devel Headers for building modules (front-ends, plugins, and back-ends) for mailfront. %prep %setup echo "gcc %{optflags}" >conf-cc echo "gcc %{optflags} -fPIC -shared" >conf-ccso echo "gcc -s -rdynamic" >conf-ld echo %{_bindir} >conf-bin echo %{_libdir}/mailfront >conf-modules echo %{_includedir} >conf-include %build make %install rm -fr %{buildroot} make install_prefix=%{buildroot} install %clean rm -rf %{buildroot} %files %defattr(-,root,root) %doc ANNOUNCEMENT COPYING NEWS README *.html %{_bindir}/* %{_libdir}/mailfront %files devel %{_includedir}/mailfront mailfront-1.16/plugin-spamassassin.html0000664000076400007640000000520711356700500017671 0ustar bruceguenter

mailfront

Plugin: spamassassin


This plugin scans messages against a SpamAssassin server. The original message is replaced with the rewritten message sent by the scanner, which will contain the results of the SpamAssassin scan in the headers. This plugin can communicate with a scanner over TCP/IP or local UNIX domain sockets.

Note: This plugin causes mailfront to save messages to temporary files.

Configuration

$SPAMD_CONNECT_TIMEOUT
The maximum amount of time to wait for a response when connecting to a SpamAssassin scanner, in milliseconds. (defaults to $SPAMD_TIMEOUT below)
$SPAMD_MAXSIZE
The maximum message size to be scanned, in bytes. This limit is useful for avoiding overloading the scanning system(s). If the incoming message is larger than this threshold, a warning is printed and no scanning is done. If unset or set to "0", there is no limit.
$SPAMD_HOST
The hostname of the SpamAssassin scanner. This setting only applies if $SPAMD_PATH is not set. If this name resolves to multiple IP addresses, all of them are tried in sequence (starting at a random point) until one scans the message.
$SPAMD_PATH
The file path to the local SpamAssassin server socket. Overrides the setting of $SPAMD_HOST.
$SPAMD_PORT
Use this TCP port number for the command/response data. (defaults to 783)
$SPAMD_REJECT
If this is set, the plugin will reject all messages that are flagged as spam. If $SPAMD_REJECT is not an empty string, that string will be used as the reject message.
$SPAMD_SEND_TIMEOUT
The maximum amount of time to wait for the output buffer to clear when sending data to a SpamAssassin scanner, in milliseconds. (defaults to $SPAMD_TIMEOUT below)
$SPAMD_TIMEOUT
The maximum amount of time to wait for a response from the SpamAssassin scanner, in milliseconds. (defaults to 5000)
$SPAMD_USER
If set, the plugin will tell the scanner to use the configuration for the named user instead of a default configuration.

Sender Action

None

Recipient Action

None

Data Action

None

Message Action

The message is scanned when all the data has been completely transmitted (to prevent timeout issues with sending data to the SpamAssassin server).

mailfront-1.16/qmtpfront-qmail.sh0000664000076400007640000000023111356700500016461 0ustar bruceguenterexec "$(dirname $0)"/mailfront qmtp qmail check-fqdn counters mailrules relayclient cvm-validate qmail-validate add-received patterns accept-sender "$@" mailfront-1.16/conf-ld0000664000076400007640000000012711356700500014243 0ustar bruceguentergcc -g -L/usr/local/lib This will be used to link .o and .a files into an executable. mailfront-1.16/smtpfront-echo.sh0000664000076400007640000000005611356700500016303 0ustar bruceguenterexec "$(dirname $0)"/mailfront smtp echo "$@" mailfront-1.16/plugin-api.html0000664000076400007640000002317511356700500015741 0ustar bruceguenter

mailfront

Plugin API


Overview

Plugins hook into the mail system at 5 main points:

  1. when the system is started or reset,
  2. when the sender address is received,
  3. when a recipient address is received,
  4. when data is received, and
  5. when the message is completed.

At each of these events, mailfront goes through the list of loaded plugins. For each plugin that has a handler for such an event, mailfront calls that handler. If the handler returns no response, control passes to the next handler, otherwise no further handlers are called. If the returned code was an error, it is passed back to the protocol immediately, which will present it to the client. If the sender or recipient handlers of all the plugins return no response, the address is considered rejected, and it is not passed on to the back end. This is done to prevent the default configuration from being an open relay. Plugins may modify the sender or recipient address, as well as the message body.

A template plugin is included as a starting point for developing new plugins.

Plugin Structure

A mailfront plugin needs to define exactly one public symbol, "plugin". All other public symbols are ignored. That symbol is to be defined as follows:

struct plugin plugin = {
  .version = PLUGIN_VERSION,
  .flags = 0,
  .init = init,
  .helo = helo,
  .reset = reset,
  .sender = sender,
  .recipient = recipient,
  .data_start = data_start,
  .data_block = data_block,
  .message_end = message_end,
};

All items in this structure except for .version may be omitted if they are not needed. The .version field is a constant set to prevent loading of plugins that were built for an incompatible API. The .flags field controls how certain parts of the plugin are called, and may be zero or more flags values (see below) ored together. The remainder of the fields are hook functions which, if present, are called at the appropriate times in the message handling process.

Note that backend modules have identical structure to plugins described here, except that the single required public symbol is named backend instead of plugin. The backend hook functions are also always the last ones called (with the exception of data_start described below). Protocol modules have an entirely different structure.

Flags

FLAG_NEED_FILE
If set, a temporary file is created and all message data is written to it. The file descriptor for this temporary file is passed to the .data_start and .message_end hooks.

Hook Functions

All hook functions return a response pointer or NULL. This structure consists of two elements: an unsigned SMTP response code number and an ASCII message. If the plugin returns a NULL response, processing continues to the next plugin in the chain (ie pass-through). If the plugin returns a response and either the response number is greater than or equal to 400 (ie an error) or the hook is short-circuiting (as indicated below), then no further hooks in the chain are called. Response numbers less than 400 are treated as acceptance. If the response was an error, the error is passed back through the protocol, otherwise processing continues to the backend. Protocols that do not use the SMTP numbers (such as QMTP) will translate the number into something appropriate. Error numbers between 400 and 499 inclusive are considered "temporary" errors. All others are considered "permanent" failures (ie reject).

All string parameters are passed as type str* and are modifiable. If their value is changed, all subsequent plugins and the backend will see the modified form, as will the protocol module. See the bglibs str documentation module for functions to use in manipulating these objects.

Be aware that the sender and recipient hooks may be called before the message data is handled (as with the SMTP protocol) or after (as with the QMQP and QMTP protocol). In either case, the reset hook will always be called at least once before the message is started, and the message_end hook is called after the message has been completely transmitted.

const response* init(void)
This hook is called once after all the plugins have been loaded.
const response* reset(void)
This hook is called when preparing to start a new message, with the intent that all modules will flush any data specific to the message, as well as after error responses to the sender address or data, and after the SMTP HELO command.
const response* helo(str* hostname)
This hook is called when the SMTP HELO or EHLO commands are issued. As yet nothing actually uses the hostname string. Other protocols will not call this hook.
const response* sender(str* address)
This hook is called after a sender email address is transmitted by the client, and is called exactly once per message. This chain short-circuits on non-error response.
const response* recipient(str* address)
This hook is called after a sender email address is transmitted by the client, and may be called zero or more times per message. This chain short-circuits on non-error responses.
const response* data_start(int fd)
This hook is called when the sender starts transmitting the message data. Note that the backend is initialized before calling the plugin hooks, in order that plugins may send extra header data to the backend in this hook.
const response* data_block(const char* bytes, unsigned long len)
This hook is called as blocks of data are received from the sender.
const response* message_end(int fd)
This hook is called when the message has been completely transmitted by the sender.

Session Data

The session structure contains all the current session data, including pointers to the protocol module, the backend module, environment variables, temporary message file descriptor, and internal named strings and numbers. Plugins may use these internal named data items to store information for internal use or to pass to other plugins with the following functions. Note that the string and number tables are independent and may contain items with the same names without conflicts. The named strings work like environment variables but are not exposed when subprograms are executed. The numbers work similarly, but the data type is unsigned long instead of a string pointer.

const char* session_protocol(void)
Returns the name of the protocol front end module.
void session_delnum(const char* name)
Delete the named number from the session.
void session_delstr(const char* name)
Delete the named string from the session.
unsigned long session_getnum(const char* name, unsigned long dflt)
Get the named number from the session. If the name is not present, dflt is returned.
int session_hasnum(const char* name, unsigned long* num)
Returns true if the named number is present in the session.
const char* session_getstr(const char* name)
Fetch the named string from the session. If the name is not present, NULL is returned.
void session_setnum(const char* name, unsigned long value)
Set the named number in the session.
void session_setstr(const char* name, const char* value)
Set the named string in the session.

Library Functions

const response* backend_data_block(const char* data, unsigned long len)
This routine writes a block of data directly to the backend. It takes care of handling both writing to the temporary file if it was created or writing directly to the backend module.
const char* getprotoenv(const char* name)
Fetch the environment variable with the given name prefixed by the value of $PROTO. For example, if $PROTO is set to "TCP" (as with tcpserver), then getprotoenv("LOCALIP") will get the environment variable named "TCPLOCALIP".
int scratchfile(void)
Create a new temporary file descriptor opened for reading and writing. The temporary filename is unlinked before returning so that the temporary file will be deleted as soon as it is closed (by the plugin or when mailfront exits).

Hints

Rewriting the message body

Plugins that need to rewrite the message of the body should do so in the message_end hook. Create a new temporary file descriptor with scratchfile() and write the complete new message to it. Then move the new temporary file over to the existing one with the following sequence:

dup2(tmpfd, fd);
close(tmpfd);

Be sure to rewind the original file descriptor with lseek(fd,SEEK_SET,0) before using it, since the file position will normally be at the very end of the data.

mailfront-1.16/netstring.c0000664000076400007640000000125111356700500015156 0ustar bruceguenter#include #include #include "mailfront.h" int get_netstring_len(ibuf* in, unsigned long* i) /* Returns: 1 good number, 0 format error, -1 EOF */ { char c; *i = 0; for (*i = 0; ibuf_getc(in, &c); *i = (*i * 10) + (c - '0')) { if (c == ':') return 1; if (c < '0' || c > '9') return 0; } return -1; } int get_netstring(ibuf* in, str* s) { unsigned long len; char ch; switch (get_netstring_len(in, &len)) { case -1: return -1; case 0: return 0; } if (!str_ready(s, len)) return -1; s->s[len] = 0; if (!ibuf_read(in, s->s, len)) return -1; s->len = len; if (!ibuf_getc(in, &ch)) return -1; return ch == ','; } mailfront-1.16/plugin-accept.html0000664000076400007640000000106711356700500016423 0ustar bruceguenter

mailfront

Plugin: accept


This plugin is used to explicitly accept all senders and recipients. As such, it only makes sense to place this module following all others that may reject senders or recipients. This plugin is primarily of use in testing.

Configuration

None

Sender Action

Accepts all senders.

Recipient Action

Accepts all recipients.

Data Action

None

Message Action

None

mailfront-1.16/pop3front.html0000664000076400007640000000407311356700500015622 0ustar bruceguenter

MailFront

POP3 Front End


The POP3 front end is composed of two pieces: an authentication front end and a transfer back-end.

Connections are timed out after $TIMEOUT seconds of inactivity (defaults to 1200 seconds or 20 minutes), or $SESSION_TIMEOUT seconds after the connection was established (defaults to 86400 seconds or 24 hours).

pop3front-auth

Usage: pop3front-auth CVM PROGRAM [ ARGS ... ]

pop3front-auth authenticates the username and password sent by the client using the named CVM. If successful, it sets up the environment and executes PROGRAM. It also offers RFC 1734 complient AUTH support through cvm-sasl.

If $AUTH_TIMEOUT or $AUTH_SESSION_TIMEOUT are set, they override $TIMEOUT and $SESSION_TIMEOUT respectively.

pop3front-maildir

Usage: pop3front-maildir [ DEFAULT-MAILDIR ]

pop3front-maildir serves messages via POP3 out of a maildir. If $MAILBOX is set, its contents are used as the path to the mailbox, otherwise the DEFAULT-MAILDIR argument must be present. If $MAX_MESSAGES is set, the total number of accessable messages will be limited to that number. In addition, if either of $MAX_CUR_MESSAGES or $MAX_NEW_MESSAGES are set, the total number of accessable messages in the cur and new subdirectories respectively will each be limited to that number.

If the filenames in the maildir contain a size indicator, as specified here for Courier IMAP and here for Dovecot, this program will avoid using stat to calculate the file size. This is a significant performance optimization on systems with either very large or very many mailboxes.

mailfront-1.16/mailrulesx.html0000664000076400007640000002300411356700500016050 0ustar bruceguenter

MailFront

SMTP Front Ends

Mail Rules Specification

Mail Rules Specification vX


The current mail rules specification is lacking in several areas:

  • There is no way to select rules based on the state of environment variables (such as $RELAYCLIENT or $TCPREMOTEIP.
  • There is no way to select rules based on the SMTP authentication state.
  • It is difficult to seperate sender processing from recipient processing.
  • The dictionary and CDB lookups don't support wildcarding (minor).
This document proposes an improved mail rules specification that addresses these problems.

Selection

The use of mail rules is controlled by the environment variable $MAILRULES. This variable specifies the path to the compiled mail rules file. If $MAILRULES is set but the path that it points to cannot be opened, processing will fail with a temporary error. There is no default value -- if it is not set, mail rules processing is disabled.

The rules listed are applied before any other sender or recipient processing is done (such as checking against qmail's badmailfrom file).

Compiled File Format

The mail rules must be compiled to a binary format. The binary file contains a signature header followed by rules, and terminated with a 32-bit CRC check code of all the data in the file. All numbers are unsigned 32-bit LSB unless otherwise indicated. A string consisists of a length number followed by that many bytes of data.

Signature Header

  1. Unique signature string.
  2. Rule count.

Rule

  1. Rule size: total number of bytes in this rule.
  2. Rule type: single byte code indicating what type of rule this is and when it should get executed. The format of remainder of the data in the rule is dependant on this value.
    • 0: Connection/Setup
    • 1: Sender validation
    • 2: Recipient validation
  3. Conditions: count of the number of conditions (C).
  4. (C) conditions containing:
    1. Negation flag: single byte boolean
    2. Comparison type: single byte code:
      • 0: Is defined
      • 1: Exact match
      • 2: Pattern match
      • 3: File lookup, whole string
      • 4: File lookup, domain portion
      • 5: CDB lookup, whole string
      • 6: CDB lookup, domain portion
    3. Variable name: string
    4. Comparison value: string
  5. Assignments: count of the number of assignments (A).
  6. (A) assignments containing:
    1. Set (1) / unset (0) flag byte
    2. Variable name
    3. Assigned value
  7. Action: single byte code indicating the action this rule is to take:
    • 0: NO-OP
    • 1: PASS
    • 2: ACCEPT, followed by message string.
    • 3: DEFER, followed by message string.
    • 4: REJECT, followed by message string.
    • 5: DEFER-ALL, followed by message string.
    • 6: REJECT-ALL, followed by message string.
  8. Message: string containing the response message.

Variables

The following variables are internally defined.

  • authenticated: Defined if SMTP authentication has succeeded.
  • sender: The envelope sender address.
  • recipient: The current envelope recipient address.
  • databytes: The current maximum message size.
All other variable names are taken from environment variables.

Variable Substitution

Response messages and assignment values undergo variable substition. All instances of $NAME or ${NAME} in these strings are replaced with the contents of the named variable.

Pattern Syntax

A pattern is a string of stars and non-stars. It matches any concatenation of strings matched by all the stars and non-stars in the same order. A non-star matches itself. A star before the end of pattern matches any string that does not include the next character in pattern. A star at the end of pattern matches any string. Patterns containing only "*" match anything. Note: An empty pattern matches only the empty string.

Semantics

Each rule is applied in the order they are listed in the rules file until one matches. At that point, the command that triggered the rule search is accepted, deferred, or rejected depending on the rule type. If the sender is not accepted, no recipients can be accepted, as usual. As long as at least one recipient is accepted the message data may be accepted.

Text File Format

Syntax

Rules are seperated into sections by one of the following lines:

[connect]
Connection validation
[sender]
Sender validation
[recipient]
Recipient validation

Each rule in the file occupies a series of lines. Empty lines are used to seperate rules within the file. Lines starting with "#" are ignored. The rule contains the following sections:

  1. Conditions: a list of zero or more conditions. Each condition has a format from the following list. All conditions must be true for the rule to execute. A rule with no conditions always matches.
    • !CONDITION True if the condition (one of the below) is false.
    • VAR=VALUE True if the variable named VAR is defined and matches "VALUE" exactly.
    • VAR~PATTERN True if the variable VAR is defined and matches the pattern "PATTERN".
    • VAR True if the variable VAR is defined (even if it has been assigned an empty string).
    Sender-only rules must contain the condition "!recipient".
  2. Action: One of the following:
    :ACCEPT
    Accept the sender or recipient.
    :DEFER
    Reject the sender or recipient with a temporary error code.
    :REJECT
    Reject the sender or recipient with a permanent error code.
    :DEFER-ALL
    Reject the message with a temporary error (rejects all past and future recipients, and resets the state).
    :REJECT-ALL
    Reject the message with a permanent error.
    :PASS
    Pass the sender or recipient on to the next processing state (ie $RELAYCLIENT or back-end validation).
    The action may be followed by another colon (":") and a response message that will be given to the client. The default for this message depends on the action.
  3. Assignments: A list of environment variables to set or unset as a result of matching this rule, one per line. Each assignment is formatted as NAME=VALUE (note, no quotes, the value ends at the end of the line). The special names databytes, sender, and recipient are handled specially. Assignment to recipient when handling a sender, and vice versa has no effect.

Escaping

The following escape sequences are recognized in all the fields:

  • \n newline (replaced with a CR+LF pair on output)
  • \### character with octal value ### (exactly 3 digits)
  • \\ backslash
  • \: colon

Special Patterns

The following patterns are treated specially:

[[@filename]]
Matches the domain portion of the address against the control file named filename. Typical uses would be "recipient~[[@rcpthosts]]" and "recipient~[[@morercpthosts.cdb]]".
[[filename]]
Matches the entire address against the control file named filename. A typical use would be "sender~[[badmailfrom]]".
If filename ends with .cdb, the control file is opened as a CDB file. Addresses are translated to lower-case before doing CDB lookups. Otherwise, control files are plain text lists, with one entry per line. Empty lines and lines starting with "#" are ignored. Lines starting with "@" match only the domain portion of the address. All comparisons are case insensitive. Missing CDB files are silently ignored. Missing text files cause an error message at startup.

Examples

qmail Rules

The following rules provide the functionality available in qmail-smtpd:

[sender]
sender~[[/var/qmail/control/badmailfrom]]
:REJECT:Sorry, your envelope sender is in my badmailfrom list (#5.7.1)

[recipient]
$RELAYCLIENT
:ACCEPT:Accepted
recipient=${recipient}$RELAYCLIENT

authenticated
:ACCEPT:Accepted

recipient~[[@/var/qmail/control/rcpthosts]]
:ACCEPT:Accepted

recipient~[[@/var/qmail/control/morercpthosts.cdb]]
:ACCEPT:Accepted

:REJECT:Sorry, that domain isn't in my list of allowed rcpthosts

Missing Features

The following features are absent from this description, and could be added:

  • Extended variable expansion: Borrow the following parameter/variable expansion features from bash:
    ${parameter:-word}
    ${parameter:+word}
    ${parameter:offset}
    ${parameter:offset:length}
    ${#parameter}
    ${parameter#word}
    ${parameter##word}
    ${parameter%word}
    ${parameter%%word}
    ${parameter/pattern/string}
    ${parameter//pattern/string}

mailfront-1.16/plugin-cvm-validate.c0000664000076400007640000000460511356700500017017 0ustar bruceguenter#include #include #include "mailfront.h" #include #include static const char* lookup_secret; static const char* cvm_lookup; static int cred_count; static RESPONSE(norcpt,553,"5.1.1 Sorry, that recipient does not exist."); static RESPONSE(failed,451,"4.1.0 Sorry, I could not verify that recipient (internal temporary error)."); static const response* validate_init(void) { if ((cvm_lookup = getenv("CVM_LOOKUP")) != 0) { if ((lookup_secret = getenv("CVM_LOOKUP_SECRET")) == 0) lookup_secret = getenv("LOOKUP_SECRET"); /* Invoking CVMs in cvm-command mode without $CVM_LOOKUP_SECRET set * will fail, since the CVM will be expecting additional credentials * to validate. To prevent this failure, set $CVM_LOOKUP_SECRET to * an empty string. */ if (lookup_secret == 0) { if (putenv("CVM_LOOKUP_SECRET=") != 0) return &resp_oom; /* Also set the lookup secret to an empty string internally to * avoid NULL pointer issues later. */ lookup_secret = ""; } /* Match the behavior of the current CVM code base: If * $CVM_LOOKUP_SECRET is set to an empty string, treat it as if no * lookup secret is required. */ cred_count = (*lookup_secret == 0) ? 2 : 3; } return 0; } static const response* validate_recipient(str* recipient) { struct cvm_credential creds[3]; unsigned i; unsigned long u; const response* r = &resp_failed; if (cvm_lookup == 0) return 0; if ((i = str_findlast(recipient, '@')) == (unsigned)-1) return 0; memset(creds, 0, sizeof creds); creds[0].type = CVM_CRED_ACCOUNT; creds[1].type = CVM_CRED_DOMAIN; creds[2].type = CVM_CRED_SECRET; if (str_copyb(&creds[0].value, recipient->s, i) && str_copyb(&creds[1].value, recipient->s+i+1, recipient->len-i-1) && str_copys(&creds[2].value, lookup_secret)) { switch (cvm_authenticate(cvm_lookup, cred_count, creds)) { case 0: r = 0; break; case CVME_PERMFAIL: /* Return a "pass" result if the CVM declared the address to be * out of scope. */ r = (cvm_client_fact_uint(CVM_FACT_OUTOFSCOPE, &u) == 0 && u == 1) ? 0 : &resp_norcpt; } } str_free(&creds[0].value); str_free(&creds[1].value); str_free(&creds[2].value); return r; } struct plugin plugin = { .version = PLUGIN_VERSION, .init = validate_init, .recipient = validate_recipient, }; mailfront-1.16/conf-bgincs0000664000076400007640000000003211356700500015104 0ustar bruceguenter/usr/local/bglibs/include mailfront-1.16/pop3front-auth.c0000664000076400007640000000676411356700500016050 0ustar bruceguenter/* pop3front-auth.c -- POP3 authentication front-end * Copyright (C) 2008 Bruce Guenter or FutureQuest, Inc. * Development of this program was sponsored by FutureQuest, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact information: * FutureQuest Inc. * PO BOX 623127 * Oviedo FL 32762-3127 USA * http://www.FutureQuest.net/ * ossi@FutureQuest.net */ #include #include #include #include #include #include #include #include #include "pop3.h" const char program[] = "pop3front-auth"; const int authenticating = 1; static const char* cvm; static char** nextcmd; static const char* domain; static str user; static struct sasl_auth saslauth = { .prefix = "+ " }; static void do_exec(void) { if (!cvm_setugid() || !cvm_setenv()) respond(err_internal); else { alarm(0); execvp(nextcmd[0], nextcmd); respond("-ERR Could not execute second stage"); } _exit(1); } static void cmd_auth_none(void) { static str auth_resp; striter i; switch (sasl_auth_caps(&auth_resp)) { case 0: respond(ok); break; case 1: if (auth_resp.len <= 5) { respond(err_internal); return; } respond(ok); str_lcut(&auth_resp, 5); str_strip(&auth_resp); striter_loop(&i, &auth_resp, ' ') { obuf_write(&outbuf, i.startptr, i.len); obuf_puts(&outbuf, CRLF); } break; default: respond(err_internal); return; } respond("."); } static void cmd_auth(const str* s) { int i; if ((i = sasl_auth1(&saslauth, s)) == 0) do_exec(); obuf_write(&outbuf, "-ERR ", 5); respond(sasl_auth_msg(&i)); } static void cmd_user(const str* s) { if (!str_copy(&user, s)) respond(err_internal); else respond(ok); } static void cmd_pass(const str* s) { if (user.len == 0) respond("-ERR Send USER first"); else { int cr; if ((cr = cvm_authenticate_password(cvm, user.s, domain, s->s, 1)) == 0) do_exec(); str_truncate(&user, 0); if (cr == CVME_PERMFAIL) respond("-ERR Authentication failed"); else respond(err_internal); } } static void cmd_quit(void) { respond(ok); exit(0); } command commands[] = { { "CAPA", cmd_capa, 0, 0 }, { "AUTH", cmd_auth_none, cmd_auth, 0 }, { "PASS", 0, cmd_pass, "PASS XXXXXXXX" }, { "QUIT", cmd_quit, 0, 0 }, { "USER", 0, cmd_user, 0 }, { 0, 0, 0, 0 } }; int startup(int argc, char* argv[]) { static const char usage[] = "usage: pop3front-auth cvm program [args...]\n"; if ((domain = cvm_ucspi_domain()) == 0) domain = "unknown"; if (argc < 3) { obuf_putsflush(&errbuf, usage); return 0; } cvm = argv[1]; nextcmd = argv+2; if (!sasl_auth_init(&saslauth)) { respond("-ERR Could not initialize SASL AUTH"); return 0; } return 1; } mailfront-1.16/plugin-accept-sender.html0000664000076400007640000000074211356700500017700 0ustar bruceguenter

mailfront

Plugin: accept-sender


This plugin is used to explicitly accept all senders. As such, it only makes sense to place this module following all others that may reject senders.

Configuration

None

Sender Action

Accepts all senders.

Recipient Action

None

Data Action

None

Message Action

None

mailfront-1.16/mailfront.c0000664000076400007640000001345411356700500015144 0ustar bruceguenter#include #include #include #include #include #include #include #include "mailfront-internal.h" static RESPONSE(no_sender,550,"5.1.0 Mail system is not configured to accept that sender"); static RESPONSE(no_rcpt,550,"5.1.0 Mail system is not configured to accept that recipient"); const char UNKNOWN[] = "unknown"; const int msg_show_pid = 1; const char program[] = "mailfront"; const int authenticating = 0; extern void set_timeout(void); extern void report_io_bytes(void); static str tmp_prefix; #define MODULE_CALL(NAME,PARAMS,SHORT,RESET) do{ \ struct plugin* plugin; \ const response* tmp; \ for (plugin = session.plugin_list; plugin != 0; plugin = plugin->next) { \ if (plugin->NAME != 0) { \ if ((tmp = plugin->NAME PARAMS) != 0) { \ resp = tmp; \ if (!response_ok(resp)) { \ if (RESET) \ handle_reset(); \ return resp; \ } \ else if (SHORT) \ break; \ } \ } \ } \ } while(0) const response* handle_init(void) { const response* resp; atexit(report_io_bytes); set_timeout(); MODULE_CALL(init, (), 0, 0); if (session.backend->init != 0) return session.backend->init(); return 0; } const response* handle_helo(str* host) { const response* resp; MODULE_CALL(helo, (host), 0, 0); session_setstr("helo_domain", host->s); return 0; } const response* handle_reset(void) { const response* resp = 0; if (session.fd >= 0) { close(session.fd); session.fd = -1; } if (session.backend->reset != 0) session.backend->reset(); MODULE_CALL(reset, (), 0, 0); return resp; } const response* handle_sender(str* sender) { const response* resp = 0; const response* tmpresp = 0; MODULE_CALL(sender, (sender), 1, 0); if (resp == 0) return &resp_no_sender; if (session.backend->sender != 0) if (!response_ok(tmpresp = session.backend->sender(sender))) return tmpresp; if (resp == 0 || resp->message == 0) resp = tmpresp; return resp; } const response* handle_recipient(str* recip) { const response* resp = 0; const response* hresp = 0; MODULE_CALL(recipient, (recip), 1, 0); if (resp == 0) return &resp_no_rcpt; if (session.backend->recipient != 0) if (!response_ok(hresp = session.backend->recipient(recip))) return hresp; if (resp == 0 || resp->message == 0) resp = hresp; return resp; } static const response* data_response; const response* handle_data_start(void) { const response* resp = 0; if (session.fd >= 0) { close(session.fd); session.fd = -1; } if (session.flags & FLAG_NEED_FILE) { if ((session.fd = scratchfile()) == -1) return &resp_internal; } data_response = 0; if (session.backend->data_start != 0) resp = session.backend->data_start(session.fd); if (response_ok(resp)) MODULE_CALL(data_start, (session.fd), 0, 1); if (!response_ok(resp)) { handle_reset(); data_response = resp; } return resp; } void handle_data_bytes(const char* bytes, unsigned len) { const response* r; struct plugin* plugin; if (!response_ok(data_response)) return; for (plugin = session.plugin_list; plugin != 0; plugin = plugin->next) if (plugin->data_block != 0) if ((r = plugin->data_block(bytes, len)) != 0 && !response_ok(r)) { handle_reset(); data_response = r; return; } if (session.backend->data_block != 0) session.backend->data_block(bytes, len); if (session.fd >= 0) if (write(session.fd, bytes, len) != (ssize_t)len) { handle_reset(); data_response = &resp_internal; } } const response* handle_message_end(void) { const response* resp = 0; if (!response_ok(data_response)) return data_response; MODULE_CALL(message_end, (session.fd), 0, 1); if (session.backend->message_end != 0) resp = session.backend->message_end(session.fd); if (session.fd >= 0) close(session.fd); session.fd = -1; if (!response_ok(resp)) handle_reset(); return resp; } int respond_line(unsigned number, int final, const char* msg, unsigned long len) { static str line; if (number >= 400) { line.len = 0; str_catu(&line, number); str_catc(&line, ' '); str_catb(&line, msg, len); msg1(line.s); } if (!session.protocol->respond_line(number, final, msg, len)) return 0; if (final) if (!obuf_flush(&outbuf)) return 0; return 1; } int respond(const response* resp) { const char* msg; const char* nl; for (msg = resp->message; (nl = strchr(msg, '\n')) != 0; msg = nl + 1) respond_line(resp->number, 0, msg, nl-msg); return respond_line(resp->number, 1, msg, strlen(msg)); } const response* backend_data_block(const char* data, unsigned long len) { return (session.fd >= 0) ? ( (write(session.fd, data, len) != (ssize_t)len) ? &resp_internal : 0 ) : ( (session.backend->data_block != 0) ? session.backend->data_block(data, len) : 0 ); } int scratchfile(void) { str filename = {0,0,0}; int fd; if ((fd = path_mktemp(tmp_prefix.s, &filename)) != -1) unlink(filename.s); str_free(&filename); return fd; } int main(int argc, char* argv[]) { const response* resp; const char* tmp; if (argc < 3) die1(111, "Protocol or backend name are missing from the command line"); if ((tmp = getenv("TMPDIR")) == 0) tmp = "/tmp"; if (!str_copy2s(&tmp_prefix, tmp, "/mailfront.tmp.")) die_oom(111); session_init(); if ((resp = load_modules(argv[1], argv[2], (const char**)(argv+3))) != 0 || (resp = handle_init()) != 0) { if (session.protocol != 0) { respond(resp); return 1; } else die1(1, resp->message); } if (session.protocol->init != 0) if (session.protocol->init()) return 1; return session.protocol->mainloop(); } mailfront-1.16/plugin-counters.html0000664000076400007640000000165311356700500017027 0ustar bruceguenter

mailfront

Plugin: counters


This plugin maintains and enforces several counters.

Configuration

$MAXRCPTS
The maximum recipient limit
$MAXHOPS
The maximum hop limit (defaults to 100)
$DATABYTES
The maximum message size limit

Sender Action

None

Recipient Action

If at least the maximum recipient limit has been reached for the current message, this recipient is rejected. Otherwise no action.

Data Action

If the message is larger than the maximum message size, it is rejected. If more than the maximum hop limit of either "Received:" or "Delivered-To:" headers are present in the message, it is rejected. Otherwise no action.

Message Action

None

mailfront-1.16/plugin-relayclient.html0000664000076400007640000000136211356700500017475 0ustar bruceguenter

mailfront

Plugin: relayclient


This plugin is used to explicitly accept recipients if the sender is considered authenticated, either by having $RELAYCLIENT set or by using SMTP authentication.

Configuration

$RELAYCLIENT
See below.

Sender Action

None

Recipient Action

If $RELAYCLIENT is set, its value is appended to the recipient and the recipient is accepted. If the sender has completed SMTP authentication, the recipient is left unchanged and is accepted. Otherwise no action.

Data Action

None

Message Action

None

mailfront-1.16/plugin-force-file.html0000664000076400007640000000077711356700500017206 0ustar bruceguenter

mailfront

Plugin: force-file


This plugin forces mailfront to save messages to a temporary file, even if no other plugin may require it. This is primarily only useful for debugging.

Configuration

None

Sender Action

None

Recipient Action

None

Data Action

Reports an error if no temporary file was created.

Message Action

None

mailfront-1.16/backend-qmail.c0000664000076400007640000001336711356700500015644 0ustar bruceguenter#include #include #include #include #include #include #include #include #include #include "mailfront.h" #include "conf_qmail.c" static RESPONSE(no_write,451,"4.3.0 Writing data to qmail-queue failed."); static RESPONSE(no_pipe,451,"4.3.0 Could not open pipe to qmail-queue."); static RESPONSE(no_fork,451,"4.3.0 Could not start qmail-queue."); static RESPONSE(no_chdir,451,"4.3.0 Could not change to the qmail directory."); static RESPONSE(qq_crashed,451,"4.3.0 qmail-queue crashed."); static str buffer; static unsigned long databytes; static const char* qqargs[2] = { 0, 0 }; static int qqpid = -1; static int qqepipe[2] = { -1, -1 }; static int qqmpipe[2] = { -1, -1 }; static void close_qqpipe(void) { if (qqepipe[0] != -1) close(qqepipe[0]); if (qqepipe[1] != -1) close(qqepipe[1]); if (qqmpipe[0] != -1) close(qqmpipe[0]); if (qqmpipe[1] != -1) close(qqmpipe[1]); qqepipe[0] = qqepipe[1] = qqmpipe[0] = qqmpipe[1] = -1; } static const response* reset(void) { close_qqpipe(); str_truncate(&buffer, 0); return 0; } static const response* do_sender(str* sender) { if (!str_catc(&buffer, 'F') || !str_cat(&buffer, sender) || !str_catc(&buffer, 0)) return &resp_oom; return 0; } static const response* do_recipient(str* recipient) { if (!str_catc(&buffer, 'T') || !str_cat(&buffer, recipient) || !str_catc(&buffer, 0)) return &resp_oom; return 0; } static int start_qq(int msgfd, int envfd) { if ((qqpid = fork()) == -1) { close_qqpipe(); return -1; } if (qqpid == 0) { if (!session_exportenv()) exit(51); if (dup2(msgfd, 0) == -1) exit(120); if (dup2(envfd, 1) == -1) exit(120); close_qqpipe(); execvp(qqargs[0], (char**)qqargs); exit(120); } return 0; } static const response* data_start(int fd) { const char* qh; qqargs[0] = session_getenv("QMAILQUEUE"); if (qqargs[0] == 0) qqargs[0] = "bin/qmail-queue"; if ((qh = session_getenv("QMAILHOME")) == 0) qh = conf_qmail; if (chdir(qh) == -1) return &resp_no_chdir; sig_pipe_block(); if (pipe(qqepipe) == -1) return &resp_no_pipe; if (fd < 0) { if (pipe(qqmpipe) == -1) { close_qqpipe(); return &resp_no_pipe; } if (start_qq(qqmpipe[0], qqepipe[0]) == -1) return &resp_no_fork; } databytes = 0; return 0; (void)fd; } static int retry_write(int fd, const char* bytes, unsigned long len) { while (len) { unsigned long written = write(fd, bytes, len); if (written == (unsigned long)-1) return 0; len -= written; bytes += written; } return 1; } static const response* data_block(const char* bytes, unsigned long len) { if (qqmpipe[1] >= 0) { if (!retry_write(qqmpipe[1], bytes, len)) return &resp_no_write; databytes += len; } return 0; } static void parse_status(int status, response* resp) { char var[20]; const char* message; resp->number = (status <= 40 && status >= 11) ? 554 : 451; memcpy(var, "QQERRMSG_", 9); strcpy(var+9, utoa(status)); if ((message = session_getenv(var)) == 0) { switch (status) { case 11: message = "5.1.3 Address too long."; break; case 31: message = "5.3.0 Message refused."; break; case 51: message = "4.3.0 Out of memory."; break; case 52: message = "4.3.0 Timeout."; break; case 53: message = "4.3.0 Write error (queue full?)."; break; case 54: message = "4.3.0 Unable to read the message or envelope."; break; case 55: message = "4.3.0 Unable to read a configuration file."; break; case 56: message = "4.3.0 Network problem."; break; case 61: message = "4.3.0 Problem with the qmail home directory."; break; case 62: message = "4.3.0 Problem with the qmail queue directory."; break; case 63: message = "4.3.0 Problem with queue/pid."; break; case 64: message = "4.3.0 Problem with queue/mess."; break; case 65: message = "4.3.0 Problem with queue/intd."; break; case 66: message = "4.3.0 Problem with queue/todo."; break; case 71: message = "4.3.0 Message refused by mail server."; break; case 72: message = "4.3.0 Connection to mail server timed out."; break; case 73: message = "4.3.0 Connection to mail server rejected."; break; case 74: message = "4.3.0 Communication with mail server failed."; break; case 81: message = "4.3.0 Internal qmail-queue bug."; break; case 91: message = "4.3.0 Envelope format error."; break; default: message = (resp->number >= 500) ? "5.3.0 Message rejected by qmail-queue." : "4.3.0 Temporary qmail-queue failure."; } } resp->message = message; } static const response* message_end(int fd) { static response resp; int status; struct stat st; if (fd < 0) { close(qqmpipe[1]); qqmpipe[1] = -1; } else { if (lseek(fd, 0, SEEK_SET) != 0) return &resp_internal; if (fstat(fd, &st) != 0) return &resp_internal; databytes = st.st_size; if (start_qq(fd, qqepipe[0]) == -1) return &resp_no_fork; } if (!retry_write(qqepipe[1], buffer.s, buffer.len+1)) return &resp_no_write; close_qqpipe(); if (waitpid(qqpid, &status, WUNTRACED) == -1) return &resp_qq_crashed; if (!WIFEXITED(status)) return &resp_qq_crashed; if ((status = WEXITSTATUS(status)) != 0) parse_status(status, &resp); else { str_copys(&buffer, "2.6.0 Accepted message qp "); str_catu(&buffer, qqpid); str_cats(&buffer, " bytes "); str_catu(&buffer, databytes); msg1(buffer.s); resp.number = 250; resp.message = buffer.s; } return &resp; (void)fd; } struct plugin backend = { .version = PLUGIN_VERSION, .reset = reset, .sender = do_sender, .recipient = do_recipient, .data_start = data_start, .data_block = data_block, .message_end = message_end, }; mailfront-1.16/plugin-add-received.html0000664000076400007640000000304611356700500017477 0ustar bruceguenter

mailfront

Plugin: add-received


This plugin adds headers to the start of the message as detailed below.

Configuration

$FIXUP_RECEIVED_HOST
Received host to match
$FIXUP_RECEIVED_IP
Received IP to match
$HEADER_ADD
Additional headers
$PROTO
This and the following four environment variables are inserted into their respective parts in the standard Received: header described below.
${$PROTO}LOCALHOST
${$PROTO}LOCALIP
${$PROTO}REMOTEHOST
${$PROTO}REMOTEIP

Sender Action

None

Recipient Action

None

Data Action

If $FIXUP_RECEIVED_HOST and $FIXUP_RECEIVED_IP are set and do not exactly match the current local host and IP, a Received: header is added to show a transition from one to the other. Then a standard Received: header is added. Finally, if $HEADER_ADD is set, its contents are added to the message headers.

The standard Received: header has the following format:

Received: from helo_domain (remotehost [remoteip]
        by localhost ([remoteip])
        with protocol via transport; date

Message Action

None

mailfront-1.16/session.c0000664000076400007640000000616011356700500014630 0ustar bruceguenter#include #include #include #include #include "mailfront-internal.h" struct session session = { .protocol = 0, }; const char* session_protocol(void) { return session.protocol->name; } const char* session_getenv(const char* name) { const char* s; if ((s = envstr_get(&session.env, name)) == 0) s = getenv(name); return s; } static unsigned long min_u_s(unsigned long u, const char* s) { unsigned long newu; if (s != 0) { if ((newu = strtoul(s, (char**)&s, 10)) != 0 && *s == 0 && (u == 0 || newu < u)) u = newu; } return u; } /* Returns the smallest non-zero value set */ unsigned long session_getenvu(const char* name) { unsigned i; const unsigned namelen = strlen(name); unsigned long val; val = min_u_s(0, getenv(name)); for (i = 0; i < session.env.len; i += strlen(session.env.s + i) + 1) { if (memcmp(session.env.s + i, name, namelen) == 0 && session.env.s[i + namelen] == '=') val = min_u_s(val, session.env.s + i + namelen + 1); } return val; } int session_exportenv(void) { unsigned i; for (i = 0; i < session.env.len; i += strlen(session.env.s + i) + 1) if (putenv(session.env.s + i) != 0) return 0; return 1; } int session_putenv(const char* s) { if (session.env.len > 0) if (!str_catc(&session.env, 0)) return 0; return str_catb(&session.env, s, strlen(s) + 1); } int session_setenv(const char* name, const char* value, int overwrite) { return envstr_set(&session.env, name, value, overwrite); } void session_resetenv(void) { session.env.len = 0; } GHASH_DEFN(session_strs,const char*,const char*, adt_hashsp,adt_cmpsp,0,adt_copysp,0,adt_freesp); GHASH_DEFN(session_nums,const char*,unsigned long, adt_hashsp,adt_cmpsp,0,0,0,0); void session_delnum(const char* name) { session_nums_remove(&session.nums, &name); } void session_delstr(const char* name) { session_strs_remove(&session.strs, &name); } const char* session_getstr(const char* name) { struct session_strs_entry* p; if ((p = session_strs_get(&session.strs, &name)) == 0) return 0; return p->data; } void session_setstr(const char* name, const char* value) { /* FIXME: use _set when bglibs 1.103 is released */ session_strs_remove(&session.nums, &name); if (session_strs_add(&session.strs, &name, &value) == 0) die_oom(111); } int session_hasnum(const char* name, unsigned long* num) { struct session_nums_entry* p; if ((p = session_nums_get(&session.nums, &name)) == 0) return 0; if (num != 0) *num = p->data; return 1; } unsigned long session_getnum(const char* name, unsigned long dflt) { struct session_nums_entry* p; if ((p = session_nums_get(&session.nums, &name)) == 0) return dflt; return p->data; } void session_setnum(const char* name, unsigned long value) { /* FIXME: use _set when bglibs 1.103 is released */ session_nums_remove(&session.nums, &name); if (session_nums_add(&session.nums, &name, &value) == 0) die_oom(111); } void session_init(void) { memset(&session, 0, sizeof session); session.fd = -1; session_strs_init(&session.strs); session_nums_init(&session.nums); } mailfront-1.16/plugin-check-fqdn.html0000664000076400007640000000161411356700500017165 0ustar bruceguenter

mailfront

Plugin: check-fqdn


Configuration

$DEFAULTDOMAIN
If set, the contents of this variable are appended to all sender or recipient addresses that have a partial host name (missing at least one "."). (no default)
$DEFAULTHOST
If set, the contents of this variable are appended to all sender or recipient addresses that are missing a host name. (no default)

Sender Action

If the sender address is not empty and it either contains no "@" or contains no "." in the part of the address following the "@", the address is rejected. Otherwise no action.

Recipient Action

Same as the sender action.

Data Action

None

Message Action

None

mailfront-1.16/qmtp-respond.c0000664000076400007640000000132011356700500015567 0ustar bruceguenter#include #include "responses.h" #include "qmtp.h" #include #include int qmtp_respond_line(unsigned num, int final, const char* msg, unsigned long len) { static str resp; char c; if (resp.len > 0) if (!str_catc(&resp, '\n')) return 0; if (!str_catb(&resp, msg, len)) return 0; if (final) { c = (num >= 500) ? 'D' : (num >= 400 || num < 200) ? 'Z' : 'K'; if (!obuf_putu(&outbuf, resp.len + 1)) return 0; if (!obuf_putc(&outbuf, ':')) return 0; if (!obuf_putc(&outbuf, c)) return 0; if (!obuf_write(&outbuf, resp.s, resp.len)) return 0; if (!obuf_putc(&outbuf, ',')) return 0; resp.len = 0; } return 1; } mailfront-1.16/protocol-qmqp.html0000664000076400007640000000101111356700500016472 0ustar bruceguenter

MailFront

Protocol: qmqp


The QMQP protocol module implements the Quick Mail Queueing Protocol created by D. J. Bernstein, the creator of qmail. The protocol is designed for the specific situation where one system (without a mail queue) sends its mail to another system for queueing (distinct from relaying).

mailfront-1.16/imapfront.html0000664000076400007640000000174111356700500015666 0ustar bruceguenter

MailFront

IMAP Front End


imapfront-auth

Usage: imapfront-auth PROGRAM [ ARGS ... ]

imapfront-auth provides IMAP authentication using CVM modules. The LOGIN command is authenticated via the CVM named by $CVM_SASL_PLAIN. If authentication succeeds, it sets up the environment and executes PROGRAM. It also offers RFC 1734 compliant AUTH support through cvm-sasl. The environment is set up for use with Courier IMAP.

Connections are timed out after $AUTH_TIMEOUT (or $TIMEOUT if that is not set) seconds of inactivity (defaults to 1200 seconds or 20 minutes), or $AUTH_SESSION_TIMEOUT (or $SESSION_TIMEOUT if that is not set) seconds after the connection was established (defaults to 86400 seconds or 24 hours).

mailfront-1.16/plugin-relayclient.c0000664000076400007640000000067511356700500016761 0ustar bruceguenter#include #include "mailfront.h" static RESPONSE(ok, 250, 0); static const response* do_recipient(str* recipient) { const char* relayclient = session_getenv("RELAYCLIENT"); if (relayclient != 0) { str_cats(recipient, relayclient); return &resp_ok; } else if (session_getnum("authenticated", 0)) return &resp_ok; return 0; } struct plugin plugin = { .version = PLUGIN_VERSION, .recipient = do_recipient, }; mailfront-1.16/plugin-reject.html0000664000076400007640000000157311356700500016442 0ustar bruceguenter

mailfront

Plugin: reject


This plugin optionally rejects all senders with a configurable message.

Configuration

$SMTPREJECT
The reject message to issue to clients (defaults to the value of $REJECT)
$REJECT
The reject message to issue to clients

Sender Action

If either $SMTPREJECT or $REJECT are set, all addresses are rejected with the given message. If the text of the message starts with a "-", it is skipped and the rejection uses a permanent failure code (ie bounce); otherwise a temporary failure code is used. If neither are set, no action.

Recipient Action

None

Data Action

None

Message Action

None

mailfront-1.16/ChangeLog0000664000076400007640000052723311356700500014564 0ustar bruceguenter------------------------------------------------------------------------ r554 | bruce | 2007-09-27 15:23:24 -0600 (Thu, 27 Sep 2007) | 2 lines Changed paths: M /trunk/NEWS Added note about API documentation. ------------------------------------------------------------------------ r553 | bruce | 2007-09-27 15:20:52 -0600 (Thu, 27 Sep 2007) | 2 lines Changed paths: A /trunk/EXTRADIST M /trunk/makedist.py M /trunk/plugin-api.html D /trunk/plugin-prototype.c D /trunk/plugin-prototype.html A /trunk/plugin-template.c (from /trunk/plugin-prototype.c:542) A /trunk/plugin-template.html (from /trunk/plugin-prototype.html:542) Small reorganization of the template plugin and links. ------------------------------------------------------------------------ r552 | bruce | 2007-09-27 14:19:06 -0600 (Thu, 27 Sep 2007) | 2 lines Changed paths: M /trunk/TODO M /trunk/mailfront.c M /trunk/plugin-api.html Made mailfront call the reset hooks early on message permanent errors. ------------------------------------------------------------------------ r551 | bruce | 2007-09-27 09:47:22 -0600 (Thu, 27 Sep 2007) | 2 lines Changed paths: M /trunk/TODO A /trunk/tests/plugin-qmail-validate Added tests for plugin-qmail-validate. ------------------------------------------------------------------------ r550 | bruce | 2007-09-27 09:16:21 -0600 (Thu, 27 Sep 2007) | 2 lines Changed paths: M /trunk/tests.inc Tweaked the tests to report unexpected startup messages. ------------------------------------------------------------------------ r549 | bruce | 2007-09-27 00:08:52 -0600 (Thu, 27 Sep 2007) | 2 lines Changed paths: M /trunk/tests/smtpfront-auth-login M /trunk/tests/smtpfront-auth-plain M /trunk/tests/smtpfront-require-auth Removed dependancy on qmail-validate in tests. ------------------------------------------------------------------------ r548 | bruce | 2007-09-27 00:01:29 -0600 (Thu, 27 Sep 2007) | 3 lines Changed paths: M /trunk/backend-echo.c Restored the ability of backend-echo.c to report data bytes when a temporary file is in use. ------------------------------------------------------------------------ r547 | bruce | 2007-09-26 15:47:16 -0600 (Wed, 26 Sep 2007) | 2 lines Changed paths: M /trunk/plugin-api.html Missed a paragraph in the API document. ------------------------------------------------------------------------ r546 | bruce | 2007-09-26 14:52:29 -0600 (Wed, 26 Sep 2007) | 3 lines Changed paths: M /trunk/mailfront.html A /trunk/plugin-api.html Wrote a plugin API document, moving some technical information out of the main page. ------------------------------------------------------------------------ r545 | bruce | 2007-09-25 15:38:33 -0600 (Tue, 25 Sep 2007) | 4 lines Changed paths: M /trunk/TODO M /trunk/backend-echo.c M /trunk/backend-qmail.c M /trunk/builtins.c A /trunk/mailfront-internal.h (from /trunk/mailfront.h:544) M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/modules.c M /trunk/plugin-add-received.c M /trunk/plugin-mailrules.c M /trunk/protocol-smtp.c M /trunk/session.c Moved all internal implementation declarations into their own header, and purged all modules of references to those internals (most notably direct access to the session structure). ------------------------------------------------------------------------ r544 | bruce | 2007-09-25 14:51:58 -0600 (Tue, 25 Sep 2007) | 4 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/modules.c Moved several global variables into the session structure. They have been added to the end of the structure to retain ABI compatibility with existing plugins. ------------------------------------------------------------------------ r543 | bruce | 2007-09-25 12:36:30 -0600 (Tue, 25 Sep 2007) | 3 lines Changed paths: M /trunk/plugin-add-received.html M /trunk/protocol-smtp.html Document use of ${PROTO}LOCALHOST (and others) in the SMTP protocol and the add-received plugin. ------------------------------------------------------------------------ r542 | bruce | 2007-09-24 17:20:01 -0600 (Mon, 24 Sep 2007) | 2 lines Changed paths: M /trunk/makedist.py A /trunk/plugin-prototype.c (from /trunk/plugin.c:534) A /trunk/plugin-prototype.html (from /trunk/plugin.html:534) D /trunk/plugin.c D /trunk/plugin.html Renamed the prototype to plugin-prototype.c and added it to the web site files. ------------------------------------------------------------------------ r541 | bruce | 2007-09-03 12:02:39 -0600 (Mon, 03 Sep 2007) | 2 lines Changed paths: M /trunk/NEWS M /trunk/plugin-clamav.c M /trunk/plugin-clamav.html Modified the ClamAV plugin to prefer $CLAMAV_* settings over $CLAMD_* ------------------------------------------------------------------------ r540 | bruce | 2007-01-22 15:38:27 -0600 (Mon, 22 Jan 2007) | 2 lines Changed paths: M /trunk/NEWS M /trunk/plugin-clamav.c M /trunk/plugin-clamav.html Added a maximum message size scanning limit to the clamav plugin. ------------------------------------------------------------------------ r539 | bruce | 2007-01-22 15:08:25 -0600 (Mon, 22 Jan 2007) | 2 lines Changed paths: M /trunk/NEWS M /trunk/plugin-clamav.c M /trunk/plugin-clamav.html Added a separate send timeout to the virus scanner. ------------------------------------------------------------------------ r538 | bruce | 2007-01-22 10:18:01 -0600 (Mon, 22 Jan 2007) | 3 lines Changed paths: M /trunk/NEWS M /trunk/plugin-clamav.c Fixed a bug in the ClamAV plugin with handling port numbers when using multiple IPs. ------------------------------------------------------------------------ r537 | bruce | 2007-01-22 10:13:00 -0600 (Mon, 22 Jan 2007) | 2 lines Changed paths: M /trunk/NEWS M /trunk/plugin-clamav.c M /trunk/plugin-clamav.html Added a separate connect timeout to the ClamAV plugin. ------------------------------------------------------------------------ r536 | bruce | 2007-01-04 15:27:37 -0600 (Thu, 04 Jan 2007) | 3 lines Changed paths: M /trunk/NEWS M /trunk/plugin-check-fqdn.c M /trunk/plugin-check-fqdn.html Modified the check-fqdn plugin to append $DEFAULTHOST and $DEFAULTDOMAIN to addresses if necessary. ------------------------------------------------------------------------ r535 | bruce | 2007-01-04 15:23:23 -0600 (Thu, 04 Jan 2007) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.c M /trunk/session.c Fixed the main mailfront program to clean up temporary files properly. ------------------------------------------------------------------------ r534 | bruce | 2006-12-18 18:05:49 -0600 (Mon, 18 Dec 2006) | 3 lines Changed paths: M /trunk/NEWS M /trunk/protocol-smtp.c Modified the SMTP protocol module to export the SASL authentication information internally. ------------------------------------------------------------------------ r533 | bruce | 2006-12-18 17:23:51 -0600 (Mon, 18 Dec 2006) | 3 lines Changed paths: M /trunk/tests/pop3front-maildir-state Sort the results of find in a test to compensate for filesystems that record filenames out of order. ------------------------------------------------------------------------ r532 | bruce | 2006-12-18 16:53:26 -0600 (Mon, 18 Dec 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 1.11 ------------------------------------------------------------------------ r531 | bruce | 2006-11-15 15:43:25 -0600 (Wed, 15 Nov 2006) | 1 line Changed paths: A /tags/1.10 (from /trunk:530) Tagged version 1.10 ------------------------------------------------------------------------ r530 | bruce | 2006-11-15 15:27:30 -0600 (Wed, 15 Nov 2006) | 3 lines Changed paths: M /trunk/tests/plugin-reject M /trunk/tests/plugins-prepend M /trunk/tests/plugins-remove M /trunk/tests/rules-databytes M /trunk/tests/rules-databytes2 M /trunk/tests/smtpfront-databytes Adjusted tests to account for mailfront properly picking up ${PROTO}LOCALHOST now. ------------------------------------------------------------------------ r529 | bruce | 2006-11-12 23:06:50 -0600 (Sun, 12 Nov 2006) | 3 lines Changed paths: M /trunk/NEWS M /trunk/pop3front-maildir.c Fixed pop3front-maildir breakage on dietlibc/uClibc and empty maildirs. Thanks Wayne Marshall ------------------------------------------------------------------------ r528 | bruce | 2006-11-12 22:39:29 -0600 (Sun, 12 Nov 2006) | 2 lines Changed paths: M /trunk/INSTHIER M /trunk/spec Added the header files to the installed image. ------------------------------------------------------------------------ r527 | bruce | 2006-11-12 21:59:55 -0600 (Sun, 12 Nov 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/imapfront-auth.c M /trunk/pop3front-auth.c Fixed two more cases where the UCSPI-TCP protocol was assumed. ------------------------------------------------------------------------ r526 | bruce | 2006-11-12 21:58:48 -0600 (Sun, 12 Nov 2006) | 3 lines Changed paths: A /trunk/getprotoenv.c M /trunk/mailfront.h M /trunk/mailfront=x M /trunk/plugin-add-received.c M /trunk/protocol-smtp.c Made the getprotoenv function global, and use it in the SMTP protocol instead of only looking for $TCPLOCALHOST. ------------------------------------------------------------------------ r525 | bruce | 2006-11-12 15:20:01 -0600 (Sun, 12 Nov 2006) | 2 lines Changed paths: M /trunk/plugin.c Added some comments to the prototype plugin file. ------------------------------------------------------------------------ r524 | bruce | 2006-11-12 15:11:02 -0600 (Sun, 12 Nov 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.html M /trunk/plugin-clamav.html Fixed up some documentation for the temporary file change. ------------------------------------------------------------------------ r523 | bruce | 2006-11-12 15:09:13 -0600 (Sun, 12 Nov 2006) | 3 lines Changed paths: M /trunk/mailfront.c M /trunk/tests/plugin-force-file Use $TMPDIR instead of $TMPPATH for the temporary file base path, as most other programs also use this variable. ------------------------------------------------------------------------ r522 | bruce | 2006-11-12 14:59:47 -0600 (Sun, 12 Nov 2006) | 2 lines Changed paths: M /trunk/mailfront.html A /trunk/plugin-force-file.c A /trunk/plugin-force-file.html A /trunk/plugin-force-file=so A /trunk/tests/plugin-force-file Added a plugin to force creation of a temporary file. ------------------------------------------------------------------------ r521 | bruce | 2006-11-12 14:42:40 -0600 (Sun, 12 Nov 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/backend-echo.c M /trunk/backend-qmail.c M /trunk/mailfront.h M /trunk/modules.c M /trunk/plugin-add-received.c M /trunk/plugin-check-fqdn.c M /trunk/plugin-clamav.c M /trunk/plugin-counters.c M /trunk/plugin-cvm-validate.c M /trunk/plugin-mailrules.c M /trunk/plugin-patterns.c M /trunk/plugin-qmail-validate.c M /trunk/plugin-reject.c M /trunk/plugin-relayclient.c M /trunk/plugin-require-auth.c M /trunk/plugin.c M /trunk/protocol-qmqp.c M /trunk/protocol-qmtp.c M /trunk/protocol-smtp.c Added a version number to the plugin ABI to prevent semantic mismatches. ------------------------------------------------------------------------ r520 | bruce | 2006-11-12 14:39:16 -0600 (Sun, 12 Nov 2006) | 2 lines Changed paths: M /trunk/backend-echo.c Adapted the backend to work both with and without a temporary file. ------------------------------------------------------------------------ r519 | bruce | 2006-11-11 22:35:27 -0600 (Sat, 11 Nov 2006) | 3 lines Changed paths: M /trunk/backend-qmail.c M /trunk/plugin-add-received.c Modified the qmail backend and the add-received plugin to work both with or without a temporary file. ------------------------------------------------------------------------ r518 | bruce | 2006-11-11 22:22:37 -0600 (Sat, 11 Nov 2006) | 2 lines Changed paths: M /trunk/mailfront.c Fixed some parts of the optional temporary file semantics. ------------------------------------------------------------------------ r517 | bruce | 2006-11-11 21:58:15 -0600 (Sat, 11 Nov 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/backend-qmail.c M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/modules.c M /trunk/plugin-clamav.c M /trunk/plugin.c Reverted change 513, making the temporary file optional again. ------------------------------------------------------------------------ r516 | bruce | 2006-11-09 00:22:57 -0600 (Thu, 09 Nov 2006) | 3 lines Changed paths: M /trunk/backend-echo.c Modified the echo backend to get its data from the temporary file and not use the data_block call. ------------------------------------------------------------------------ r515 | bruce | 2006-11-09 00:21:49 -0600 (Thu, 09 Nov 2006) | 3 lines Changed paths: M /trunk/plugin-add-received.c Modified the add-received plugin to write the headers directly to the temporary file instead of calling the data_block backend plugin. ------------------------------------------------------------------------ r514 | bruce | 2006-11-09 00:03:57 -0600 (Thu, 09 Nov 2006) | 2 lines Changed paths: M /trunk/backend-qmail.c M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/plugin-add-received.c M /trunk/plugin-counters.c M /trunk/plugin-patterns.c M /trunk/plugin.c Added the temporary file descriptor to the data_start plugin call. ------------------------------------------------------------------------ r513 | bruce | 2006-11-08 23:56:29 -0600 (Wed, 08 Nov 2006) | 3 lines Changed paths: M /trunk/NEWS M /trunk/backend-qmail.c M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/modules.c M /trunk/plugin-clamav.c M /trunk/plugin.c Made the temporary file semantics mandatory and dropped the flags field from the plugins. ------------------------------------------------------------------------ r512 | bruce | 2006-11-08 23:06:47 -0600 (Wed, 08 Nov 2006) | 3 lines Changed paths: M /trunk/backend-qmail.c Modified the qmail backend to use the temporary file provided by mailfront instead of piping the message to qmail-queue piecemeal. ------------------------------------------------------------------------ r511 | bruce | 2006-11-08 16:37:54 -0600 (Wed, 08 Nov 2006) | 2 lines Changed paths: M /trunk/INSTHIER Added the ClamAV plugin to the installer. ------------------------------------------------------------------------ r510 | bruce | 2006-11-08 16:29:00 -0600 (Wed, 08 Nov 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO A /trunk/plugin-clamav.c A /trunk/plugin-clamav.html A /trunk/plugin-clamav=so Added a ClamAV virus scanner plugin. ------------------------------------------------------------------------ r509 | bruce | 2006-11-08 15:45:16 -0600 (Wed, 08 Nov 2006) | 2 lines Changed paths: M /trunk/mailfront.c Free the temporary file name string after it is used. ------------------------------------------------------------------------ r508 | bruce | 2006-11-08 15:00:14 -0600 (Wed, 08 Nov 2006) | 2 lines Changed paths: A /trunk/plugin.c A /trunk/plugin.html Added the prototype plugin files to svn. ------------------------------------------------------------------------ r507 | bruce | 2006-11-08 14:51:39 -0600 (Wed, 08 Nov 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.c M /trunk/mailfront.h Added a flag bit to make the creation of a temporary file optional. ------------------------------------------------------------------------ r506 | bruce | 2006-11-08 14:47:46 -0600 (Wed, 08 Nov 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.h M /trunk/modules.c Added a flags word to the plugin API. ------------------------------------------------------------------------ r505 | bruce | 2006-11-08 14:41:28 -0600 (Wed, 08 Nov 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/backend-echo.c M /trunk/backend-qmail.c M /trunk/mailfront.c M /trunk/mailfront.h Modified the plugin API to save messages to a temporary file. ------------------------------------------------------------------------ r504 | bruce | 2006-11-08 14:22:17 -0600 (Wed, 08 Nov 2006) | 3 lines Changed paths: M /trunk/backend-echo.c M /trunk/backend-qmail.c M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/mailfront.html M /trunk/plugin-accept-recipient.html M /trunk/plugin-accept-sender.html M /trunk/plugin-accept.html M /trunk/plugin-add-received.html M /trunk/plugin-check-fqdn.html M /trunk/plugin-counters.html M /trunk/plugin-cvm-validate.html M /trunk/plugin-mailrules.html M /trunk/plugin-patterns.html M /trunk/plugin-qmail-validate.html M /trunk/plugin-reject.html M /trunk/plugin-relayclient.html M /trunk/plugin-require-auth.html M /trunk/protocol-qmqp.c M /trunk/protocol-qmtp.c M /trunk/protocol-smtp.c Renamed the "data_end" event to "message_end", and added a plugin documentation note about it. ------------------------------------------------------------------------ r503 | bruce | 2006-11-08 13:57:03 -0600 (Wed, 08 Nov 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped up the version to 1.10 in anticipation of a plugin API change. ------------------------------------------------------------------------ r502 | bruce | 2006-09-07 15:49:14 -0600 (Thu, 07 Sep 2006) | 1 line Changed paths: A /tags/1.01 (from /trunk:501) Tagged version 1.01 ------------------------------------------------------------------------ r501 | bruce | 2006-09-07 14:12:45 -0600 (Thu, 07 Sep 2006) | 3 lines Changed paths: M /trunk/NEWS M /trunk/plugin-counters.c M /trunk/tests/smtpfront-databytes Fixed a bug in the counters plugin that triggered a problem in the SMTP protocol when handling the SIZE=# parameter. ------------------------------------------------------------------------ r500 | bruce | 2006-09-01 23:29:12 -0600 (Fri, 01 Sep 2006) | 5 lines Changed paths: M /trunk/NEWS M /trunk/TODO M /trunk/backend-echo.c M /trunk/backend-qmail.c M /trunk/builtins.c M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/plugin-check-fqdn.c M /trunk/plugin-counters.c M /trunk/plugin-cvm-validate.c M /trunk/plugin-mailrules.c M /trunk/plugin-qmail-validate.c M /trunk/plugin-reject.c M /trunk/plugin-relayclient.c M /trunk/plugin-require-auth.c M /trunk/protocol-qmqp.c M /trunk/protocol-qmtp.c M /trunk/protocol-smtp.c M /trunk/tests/plugin-reject Reverted revisions 496:HEAD. These changes were aimed at moving SMTP SIZE= handling into counters. This is effectively impossible since it needs to handle when a mail rule matches and sets the size, which short cuts the counters out. ------------------------------------------------------------------------ r499 | bruce | 2006-09-01 23:02:56 -0600 (Fri, 01 Sep 2006) | 2 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/protocol-smtp.c Moved the find_param function from the SMTP protocol into mailfront.c ------------------------------------------------------------------------ r498 | bruce | 2006-09-01 22:48:10 -0600 (Fri, 01 Sep 2006) | 2 lines Changed paths: M /trunk/plugin-counters.c M /trunk/protocol-smtp.c M /trunk/tests/plugin-reject Moved generation of the SIZE=# EHLO response into plugin-counters ------------------------------------------------------------------------ r497 | bruce | 2006-09-01 22:36:40 -0600 (Fri, 01 Sep 2006) | 2 lines Changed paths: M /trunk/TODO M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/protocol-smtp.c Added SMTP EHLO response generation to handle_helo. ------------------------------------------------------------------------ r496 | bruce | 2006-08-30 23:53:00 -0600 (Wed, 30 Aug 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO M /trunk/backend-echo.c M /trunk/backend-qmail.c M /trunk/builtins.c M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/plugin-check-fqdn.c M /trunk/plugin-counters.c M /trunk/plugin-cvm-validate.c M /trunk/plugin-mailrules.c M /trunk/plugin-qmail-validate.c M /trunk/plugin-reject.c M /trunk/plugin-relayclient.c M /trunk/plugin-require-auth.c M /trunk/protocol-qmqp.c M /trunk/protocol-qmtp.c M /trunk/protocol-smtp.c Modified the plugin API to pass down SMTP parameters. ------------------------------------------------------------------------ r495 | bruce | 2006-08-30 23:52:28 -0600 (Wed, 30 Aug 2006) | 2 lines Changed paths: A /trunk/tests/pop3front-auth-split Added a test for pop3front-auth splitting the username properly. ------------------------------------------------------------------------ r494 | bruce | 2006-08-30 21:40:53 -0600 (Wed, 30 Aug 2006) | 2 lines Changed paths: M /trunk/INSTHIER M /trunk/NEWS A /trunk/builtins.c M /trunk/mailfront.h M /trunk/mailfront=x M /trunk/modules.c D /trunk/plugin-accept-recipient.c D /trunk/plugin-accept-recipient=so D /trunk/plugin-accept-sender.c D /trunk/plugin-accept-sender=so D /trunk/plugin-accept.c D /trunk/plugin-accept=so Moved the accept* plugins to a list of builtins. ------------------------------------------------------------------------ r493 | bruce | 2006-08-30 11:11:04 -0600 (Wed, 30 Aug 2006) | 3 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.html M /trunk/qmqpfront-qmail.sh M /trunk/qmtpfront-qmail.sh M /trunk/smtpfront-qmail.sh Reversed the order of cvm-validate and qmail-validate in the wrapper scripts (and documentation) due to the semantics of the two plugins. ------------------------------------------------------------------------ r492 | bruce | 2006-08-30 11:09:26 -0600 (Wed, 30 Aug 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 1.01 ------------------------------------------------------------------------ r491 | bruce | 2006-08-30 00:50:18 -0600 (Wed, 30 Aug 2006) | 2 lines Changed paths: A /trunk/tests/plugin-cvm-validate Added a test for the CVM validate plugin. ------------------------------------------------------------------------ r490 | bruce | 2006-08-29 09:39:00 -0600 (Tue, 29 Aug 2006) | 2 lines Changed paths: M /trunk/README.in Updated email address and version requirements in the README. ------------------------------------------------------------------------ r489 | bruce | 2006-08-29 09:38:07 -0600 (Tue, 29 Aug 2006) | 1 line Changed paths: A /tags/1.0 (from /trunk:488) Tagged version 1.0 ------------------------------------------------------------------------ r488 | bruce | 2006-08-29 09:27:19 -0600 (Tue, 29 Aug 2006) | 2 lines Changed paths: M /trunk/spec Updated the spec for the new conf files and requirements. ------------------------------------------------------------------------ r487 | bruce | 2006-08-29 09:24:19 -0600 (Tue, 29 Aug 2006) | 2 lines Changed paths: M /trunk/INSTHIER Add the missing accept*.so modules to the installed image. ------------------------------------------------------------------------ r486 | bruce | 2006-08-29 09:23:59 -0600 (Tue, 29 Aug 2006) | 3 lines Changed paths: M /trunk/protocol-smtp.c Moved variable declaration line above function statements to fix a problem with older compilers. ------------------------------------------------------------------------ r485 | bruce | 2006-08-29 09:22:34 -0600 (Tue, 29 Aug 2006) | 2 lines Changed paths: M /trunk/TODO Removed done item from the TODO list. ------------------------------------------------------------------------ r484 | bruce | 2006-08-28 21:25:25 -0600 (Mon, 28 Aug 2006) | 4 lines Changed paths: M /trunk/TODO M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/plugin-add-received.c M /trunk/plugin-counters.c M /trunk/plugin-mailrules.c M /trunk/plugin-relayclient.c M /trunk/plugin-require-auth.c M /trunk/protocol-smtp.c M /trunk/session.c Converted all of the session numbers and strings to dictionaries to allow plugins to exchange data without needing to define new fields in the session structure. ------------------------------------------------------------------------ r483 | bruce | 2006-08-28 07:23:53 -0600 (Mon, 28 Aug 2006) | 2 lines Changed paths: M /trunk/protocol-qmqp.c M /trunk/protocol-qmtp.c Converted all silent dies into a response function in QMQP and QMTP. ------------------------------------------------------------------------ r482 | bruce | 2006-08-25 18:09:34 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/TODO Updated the TODO list. ------------------------------------------------------------------------ r481 | bruce | 2006-08-25 18:04:45 -0600 (Fri, 25 Aug 2006) | 3 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.html M /trunk/qmqpfront-qmail.sh M /trunk/qmtpfront-qmail.sh M /trunk/smtpfront-qmail.sh Modified the *front-qmail wrapper scripts to included the expected list of plugins, and modified the documentation to make note of this fact. ------------------------------------------------------------------------ r480 | bruce | 2006-08-25 17:51:30 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/modules.c Fixed a few bugs in the new plugin loading implementation. ------------------------------------------------------------------------ r479 | bruce | 2006-08-25 17:32:25 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/mailfront.html M /trunk/modules.c A /trunk/tests/plugin-reject (from /trunk/tests/smtpfront-reject:467) A /trunk/tests/plugins-prepend A /trunk/tests/plugins-remove D /trunk/tests/smtpfront-reject Added support for prepending and removing plugins from the list. ------------------------------------------------------------------------ r478 | bruce | 2006-08-25 16:27:05 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/modules.c Tag all modules with their loaded name. ------------------------------------------------------------------------ r477 | bruce | 2006-08-25 15:04:01 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/protocol-smtp=so D /trunk/sasl-stub.c D /trunk/smtp-respond.c D /trunk/smtp.h Removed some unused files. ------------------------------------------------------------------------ r476 | bruce | 2006-08-25 14:59:34 -0600 (Fri, 25 Aug 2006) | 3 lines Changed paths: M /trunk/protocol-smtp.c Eliminate the use of the temporary response and string manipulations in the SMTP protocol. ------------------------------------------------------------------------ r475 | bruce | 2006-08-25 14:58:53 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/mailfront.c Move output flushing after final into respond_line. ------------------------------------------------------------------------ r474 | bruce | 2006-08-25 14:51:27 -0600 (Fri, 25 Aug 2006) | 3 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/protocol-qmqp.c M /trunk/protocol-qmtp.c M /trunk/protocol-smtp.c M /trunk/qmtp-respond.c M /trunk/qmtp.h Moved all response line splitting code into mailfront, leaving the protocol modules to implement a single respond_line function. ------------------------------------------------------------------------ r473 | bruce | 2006-08-25 14:22:43 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/protocol-qmqp.c M /trunk/protocol-qmtp.c M /trunk/protocol-smtp.c M /trunk/smtp-respond.c Move logging of error messages into a common respond function. ------------------------------------------------------------------------ r472 | bruce | 2006-08-25 14:15:15 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/smtp-respond.c A further simplification of smtp_respond. ------------------------------------------------------------------------ r471 | bruce | 2006-08-25 14:13:56 -0600 (Fri, 25 Aug 2006) | 3 lines Changed paths: M /trunk/protocol-smtp.c M /trunk/smtp-respond.c M /trunk/smtp.h Dropped the smtp_respond_part function, resulting in a simplification of smtp_respond. ------------------------------------------------------------------------ r470 | bruce | 2006-08-25 13:48:12 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/protocol-smtp.c M /trunk/smtp-respond.c M /trunk/smtp.h Renamed the SMTP respond functions as well. ------------------------------------------------------------------------ r469 | bruce | 2006-08-25 13:44:23 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/protocol-qmqp.c M /trunk/protocol-qmtp.c M /trunk/qmtp-respond.c M /trunk/qmtp.h Greatly simplified (and renamed) the QM[QT]P respond function. ------------------------------------------------------------------------ r468 | bruce | 2006-08-25 12:54:05 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/mailfront.c Moved the session_init call to a much less stupid location. ------------------------------------------------------------------------ r467 | bruce | 2006-08-25 12:21:44 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/session.c Added a (for now) trivial session initialization function. ------------------------------------------------------------------------ r466 | bruce | 2006-08-24 12:42:42 -0600 (Thu, 24 Aug 2006) | 3 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/plugin-add-received.c Moved several session variables used only in the add-received plugin into that plugin. ------------------------------------------------------------------------ r465 | bruce | 2006-08-23 14:59:43 -0600 (Wed, 23 Aug 2006) | 2 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/protocol-smtp.c Added a plugin hook to capture the SMTP HELO/EHLO commands. ------------------------------------------------------------------------ r464 | bruce | 2006-08-03 14:54:36 -0600 (Thu, 03 Aug 2006) | 2 lines Changed paths: M /trunk/mailfront.html Reformatted the PLUGIN line. ------------------------------------------------------------------------ r463 | bruce | 2006-08-01 23:35:50 -0600 (Tue, 01 Aug 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/plugin-accept-recipient.c M /trunk/plugin-accept-sender.c M /trunk/plugin-accept.c M /trunk/plugin-add-received.c M /trunk/plugin-check-fqdn.c M /trunk/plugin-counters.c M /trunk/plugin-cvm-validate.c M /trunk/plugin-mailrules.c M /trunk/plugin-patterns.c M /trunk/plugin-qmail-validate.c M /trunk/plugin-reject.c M /trunk/plugin-relayclient.c M /trunk/plugin-require-auth.c Removed the useless STRUCT_PLUGIN macro. ------------------------------------------------------------------------ r462 | bruce | 2006-08-01 23:31:30 -0600 (Tue, 01 Aug 2006) | 3 lines Changed paths: M /trunk/smtp-respond.c Fixed the SMTP response system to flush output only after all of a set of lines have been output, instead of after each line. ------------------------------------------------------------------------ r461 | bruce | 2006-07-31 21:46:54 -0600 (Mon, 31 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.c Fixed a couple corner cases in response handling. ------------------------------------------------------------------------ r460 | bruce | 2006-07-31 21:41:00 -0600 (Mon, 31 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.c Added missing call to backend->init ------------------------------------------------------------------------ r459 | bruce | 2006-07-31 15:47:52 -0600 (Mon, 31 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.c Make sure not to short-circuit calls to plugins' init and reset functions. ------------------------------------------------------------------------ r458 | bruce | 2006-07-31 09:57:32 -0600 (Mon, 31 Jul 2006) | 2 lines Changed paths: M /trunk/qmqpfront-echo.sh M /trunk/qmqpfront-qmail.sh M /trunk/qmtpfront-echo.sh M /trunk/qmtpfront-qmail.sh M /trunk/smtpfront-echo.sh M /trunk/smtpfront-qmail.sh Forgot the "$@" trailing argument to the commands. ------------------------------------------------------------------------ r457 | bruce | 2006-07-30 14:32:26 -0600 (Sun, 30 Jul 2006) | 2 lines Changed paths: M /trunk/TODO M /trunk/mailfront.html M /trunk/plugin-add-received.html M /trunk/plugin-counters.html A /trunk/plugin-cvm-validate.html A /trunk/plugin-mailrules.html M /trunk/plugin-patterns.html M /trunk/plugin-qmail-validate.html A /trunk/plugin-reject.html M /trunk/plugin-relayclient.html A /trunk/plugin-require-auth.html Finished the plugin documentation. ------------------------------------------------------------------------ r456 | bruce | 2006-07-30 13:43:29 -0600 (Sun, 30 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/plugin-relayclient.c M /trunk/plugin-require-auth.c M /trunk/protocol-qmqp.c Removed the session.relayclient variable. ------------------------------------------------------------------------ r455 | bruce | 2006-07-30 00:39:06 -0600 (Sun, 30 Jul 2006) | 2 lines Changed paths: M /trunk/TODO M /trunk/mailfront.html M /trunk/plugin-accept-recipient.html M /trunk/plugin-accept-sender.html M /trunk/plugin-accept.html A /trunk/plugin-add-received.html A /trunk/plugin-check-fqdn.html A /trunk/plugin-counters.html M /trunk/plugin-patterns.html M /trunk/plugin-qmail-validate.html M /trunk/plugin-relayclient.html More documentation reworking. ------------------------------------------------------------------------ r454 | bruce | 2006-07-29 22:58:38 -0600 (Sat, 29 Jul 2006) | 3 lines Changed paths: M /trunk/backend-echo.html M /trunk/backend-qmail.html M /trunk/mailfront.html M /trunk/plugin-accept-recipient.html M /trunk/plugin-accept-sender.html M /trunk/plugin-accept.html M /trunk/plugin-patterns.html M /trunk/plugin-qmail-validate.html M /trunk/plugin-relayclient.html M /trunk/protocol-qmqp.html M /trunk/protocol-qmtp.html M /trunk/protocol-smtp.html Renamed the titles in the HTML files to make it more obvious what the actual protocol/plugin/backend name is. ------------------------------------------------------------------------ r453 | bruce | 2006-07-29 22:54:30 -0600 (Sat, 29 Jul 2006) | 3 lines Changed paths: M /trunk/mailfront.html A /trunk/plugin-accept-recipient.html A /trunk/plugin-accept-sender.html A /trunk/plugin-accept.html Added documentation for the 3 new accept plugins, and a note about configuration to match the previous built-in configuration. ------------------------------------------------------------------------ r452 | bruce | 2006-07-29 22:47:20 -0600 (Sat, 29 Jul 2006) | 5 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.c M /trunk/mailfront.html M /trunk/plugin-qmail-validate.c M /trunk/tests/patterns-after M /trunk/tests/patterns-general M /trunk/tests/patterns-header M /trunk/tests/patterns-message M /trunk/tests/patterns-normal M /trunk/tests/received M /trunk/tests/rules-asterisk M /trunk/tests/rules-both M /trunk/tests/rules-cdb M /trunk/tests/rules-databytes M /trunk/tests/rules-databytes2 M /trunk/tests/rules-defaultmsg M /trunk/tests/rules-empty M /trunk/tests/rules-header-add M /trunk/tests/rules-list M /trunk/tests/rules-maxhops M /trunk/tests/rules-multiline M /trunk/tests/rules-negate M /trunk/tests/rules-noop M /trunk/tests/rules-rcptlist M /trunk/tests/rules-recip M /trunk/tests/rules-selector M /trunk/tests/rules-sender M /trunk/tests/smtpfront-auth-login M /trunk/tests/smtpfront-auth-plain M /trunk/tests/smtpfront-databytes M /trunk/tests/smtpfront-looping-delivered-to M /trunk/tests/smtpfront-looping-received M /trunk/tests/smtpfront-maxrcpts M /trunk/tests/smtpfront-reject M /trunk/tests/smtpfront-require-auth M /trunk/tests.inc Modified mailfront to "fail closed". That is, if no plugin explicitly accepts a sender or recipient, mailfront considers it rejected. This prevents default configurations from becoming open relays, at the expense of slightly more confusing configuration. ------------------------------------------------------------------------ r451 | bruce | 2006-07-29 22:42:25 -0600 (Sat, 29 Jul 2006) | 3 lines Changed paths: A /trunk/plugin-accept-recipient.c (from /trunk/plugin-accept.c:448) A /trunk/plugin-accept-recipient=so (from /trunk/plugin-accept=so:448) A /trunk/plugin-accept-sender.c (from /trunk/plugin-accept.c:448) A /trunk/plugin-accept-sender=so (from /trunk/plugin-accept=so:448) Added trivial plugins to accept only the sender or recipient address, which will be needed for normal qmail installations. ------------------------------------------------------------------------ r450 | bruce | 2006-07-29 22:31:00 -0600 (Sat, 29 Jul 2006) | 2 lines Changed paths: M /trunk/INSTHIER A /trunk/qmqpfront-echo.sh A /trunk/qmqpfront-echo=sh A /trunk/qmqpfront-qmail.sh A /trunk/qmqpfront-qmail=sh A /trunk/qmtpfront-echo.sh A /trunk/qmtpfront-echo=sh A /trunk/qmtpfront-qmail.sh A /trunk/qmtpfront-qmail=sh A /trunk/smtpfront-echo.sh A /trunk/smtpfront-echo=sh A /trunk/smtpfront-qmail.sh A /trunk/smtpfront-qmail=sh Added wrapper shell scripts in place of the old program names. ------------------------------------------------------------------------ r449 | bruce | 2006-07-29 22:23:41 -0600 (Sat, 29 Jul 2006) | 3 lines Changed paths: M /trunk/plugin-reject=so M /trunk/plugin-require-auth=so The reject and require-auth plugins don't actually need libbg, so don't specify that library in the linkage. ------------------------------------------------------------------------ r448 | bruce | 2006-07-29 22:23:11 -0600 (Sat, 29 Jul 2006) | 2 lines Changed paths: A /trunk/plugin-accept.c A /trunk/plugin-accept=so Added a trivial 'accept' plugin, which accepts all senders and recipients. ------------------------------------------------------------------------ r447 | bruce | 2006-07-29 22:22:33 -0600 (Sat, 29 Jul 2006) | 4 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/mailfront.html M /trunk/modules.c D /trunk/tests/module-detect Simplified the command line handling in mailfront to always require protocol and backend names on the command line, and added the option to also specify plugins. ------------------------------------------------------------------------ r446 | bruce | 2006-07-29 22:09:59 -0600 (Sat, 29 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront=x A /trunk/modules.c (from /trunk/plugins.c:442) D /trunk/plugins.c Renamed plugins.c to modules.c ------------------------------------------------------------------------ r445 | bruce | 2006-07-29 21:49:38 -0600 (Sat, 29 Jul 2006) | 2 lines Changed paths: M /trunk/TODO A /trunk/backend-echo.html A /trunk/backend-qmail.html (from /trunk/qmail-backend.html:412) M /trunk/mailfront.html D /trunk/patterns.html A /trunk/plugin-patterns.html (from /trunk/patterns.html:412) A /trunk/plugin-qmail-validate.html (from /trunk/qmail-validate.html:412) A /trunk/plugin-relayclient.html A /trunk/protocol-qmqp.html A /trunk/protocol-qmtp.html A /trunk/protocol-smtp.html (from /trunk/smtpfront.html:412) D /trunk/qmail-backend.html D /trunk/qmail-validate.html D /trunk/smtpfront.html Started rewriting the documentation for the new modular architecture. ------------------------------------------------------------------------ r444 | bruce | 2006-07-29 21:49:14 -0600 (Sat, 29 Jul 2006) | 3 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 1.0, adding a note about the major changes in this release. ------------------------------------------------------------------------ r443 | bruce | 2006-07-29 21:48:39 -0600 (Sat, 29 Jul 2006) | 2 lines Changed paths: M /trunk/INSTHIER Fixed up installation instructions. ------------------------------------------------------------------------ r442 | bruce | 2006-07-28 16:49:40 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/plugin-add-received.c M /trunk/plugins.c M /trunk/protocol-smtp.c Moved the "protocol" and "backend" into the "session" structure. ------------------------------------------------------------------------ r441 | bruce | 2006-07-28 16:18:25 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: M /trunk/INSTHIER Add the protocol modules to INSTHIER and make all modules executable. ------------------------------------------------------------------------ r440 | bruce | 2006-07-28 13:29:29 -0600 (Fri, 28 Jul 2006) | 3 lines Changed paths: M /trunk/mailfront.c A /trunk/tests/module-detect Fixed up the logic for determining which protocol and backend based on command line arguments, and added a test for it. ------------------------------------------------------------------------ r439 | bruce | 2006-07-28 13:09:20 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h D /trunk/mailfront=l A /trunk/mailfront=x (from /trunk/mailfront=l:433) M /trunk/plugins.c A /trunk/protocol-qmqp.c (from /trunk/qmqp-mainloop.c:436) A /trunk/protocol-qmqp=so A /trunk/protocol-qmtp.c (from /trunk/qmtp-mainloop.c:436) A /trunk/protocol-qmtp=so A /trunk/protocol-smtp.c (from /trunk/smtp-commands.c:421) A /trunk/protocol-smtp=so D /trunk/qmqp-mainloop.c D /trunk/qmqp=l D /trunk/qmqpfront.c D /trunk/qmqpfront=x D /trunk/qmtp-mainloop.c M /trunk/qmtp-respond.c M /trunk/qmtp.h D /trunk/qmtp=l D /trunk/qmtpfront.c D /trunk/qmtpfront=x D /trunk/smtp-commands.c D /trunk/smtp-mainloop.c M /trunk/smtp-respond.c M /trunk/smtp.h D /trunk/smtp=l D /trunk/smtpfront.c D /trunk/smtpfront=x M /trunk/tests/qmqpfront-echo M /trunk/tests/qmtpfront-echo M /trunk/tests/received M /trunk/tests/rules-rcptlist M /trunk/tests/smtpfront-reject M /trunk/tests/smtpgreeting M /trunk/tests.inc Moved all protocols into dynamically loaded modules. ------------------------------------------------------------------------ r438 | bruce | 2006-07-28 11:57:28 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: M /trunk/tests/received Modified the received test to use spac-tests's loops. ------------------------------------------------------------------------ r437 | bruce | 2006-07-28 11:29:51 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: M /trunk/INSTHIER M /trunk/backend-echo.c A /trunk/backend-echo=so (from /trunk/plugin-counters=so:426) M /trunk/backend-qmail.c A /trunk/backend-qmail=so (from /trunk/plugin-counters=so:426) M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/plugin-add-received.c M /trunk/plugins.c D /trunk/qmail=l D /trunk/qmqpfront-echo.c D /trunk/qmqpfront-echo=x D /trunk/qmqpfront-qmail.c D /trunk/qmqpfront-qmail=x A /trunk/qmqpfront.c (from /trunk/qmqpfront-echo.c:435) A /trunk/qmqpfront=x (from /trunk/qmqpfront-echo=x:435) D /trunk/qmtpfront-echo.c D /trunk/qmtpfront-echo=x D /trunk/qmtpfront-qmail.c D /trunk/qmtpfront-qmail=x A /trunk/qmtpfront.c (from /trunk/qmtpfront-echo.c:435) A /trunk/qmtpfront=x (from /trunk/qmtpfront-echo=x:435) D /trunk/smtpfront-echo.c D /trunk/smtpfront-echo=x D /trunk/smtpfront-qmail.c D /trunk/smtpfront-qmail=x A /trunk/smtpfront.c (from /trunk/smtpfront-echo.c:435) A /trunk/smtpfront=x (from /trunk/smtpfront-echo=x:435) M /trunk/tests/qmqpfront-echo M /trunk/tests/qmtpfront-echo M /trunk/tests/received M /trunk/tests/rules-rcptlist M /trunk/tests/smtpfront-reject M /trunk/tests/smtpgreeting M /trunk/tests.inc Made all the backends dynamically loadable too. ------------------------------------------------------------------------ r436 | bruce | 2006-07-28 10:46:40 -0600 (Fri, 28 Jul 2006) | 4 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/qmqp-mainloop.c M /trunk/qmtp-mainloop.c M /trunk/smtp-mainloop.c Moved the duplicated call to handle_init out of the protocols and into mailfront.c. This breaks a protocol_init function out of protocol_mainloop. ------------------------------------------------------------------------ r435 | bruce | 2006-07-28 10:38:33 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/qmqpfront-echo.c M /trunk/qmqpfront-echo=x M /trunk/qmqpfront-qmail.c M /trunk/qmqpfront-qmail=x M /trunk/qmtp-respond.c M /trunk/qmtpfront-echo.c M /trunk/qmtpfront-echo=x M /trunk/qmtpfront-qmail.c M /trunk/qmtpfront-qmail=x M /trunk/smtp-respond.c M /trunk/smtpfront-echo.c M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail.c M /trunk/smtpfront-qmail=x Moved main from individual files into mailfront.c ------------------------------------------------------------------------ r434 | bruce | 2006-07-28 10:30:32 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: D /trunk/backend-reject.c A /trunk/plugin-reject.c (from /trunk/backend-reject.c:432) A /trunk/plugin-reject=so (from /trunk/plugin-counters=so:426) D /trunk/qmqpfront-reject.c D /trunk/qmqpfront-reject=x D /trunk/qmtpfront-reject.c D /trunk/qmtpfront-reject=x D /trunk/smtpfront-reject.c D /trunk/smtpfront-reject=x M /trunk/tests/smtpfront-reject Moved the reject backend into a plugin. ------------------------------------------------------------------------ r433 | bruce | 2006-07-28 10:16:59 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: A /trunk/mailfront.c (from /trunk/std-handle.c:424) M /trunk/mailfront=l D /trunk/std-handle.c Renamed std-handle.c to mailfront.c ------------------------------------------------------------------------ r432 | bruce | 2006-07-28 10:14:21 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: M /trunk/backend-reject.c M /trunk/qmqpfront-reject.c M /trunk/qmtpfront-reject.c M /trunk/smtpfront-reject.c Moved the -reject main routine into backend-reject.c ------------------------------------------------------------------------ r431 | bruce | 2006-07-28 09:46:59 -0600 (Fri, 28 Jul 2006) | 3 lines Changed paths: M /trunk/plugin-require-auth.c M /trunk/std-handle.html M /trunk/tests/smtpfront-require-auth Since the require-auth plugin is optional, there is no need for it to check for $REQUIRE_AUTH. ------------------------------------------------------------------------ r430 | bruce | 2006-07-28 09:44:43 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/plugins.c M /trunk/qmqpfront-echo.c M /trunk/qmqpfront-qmail.c M /trunk/qmqpfront-reject.c M /trunk/qmtpfront-echo.c M /trunk/qmtpfront-qmail.c M /trunk/qmtpfront-reject.c M /trunk/smtpfront-echo.c M /trunk/smtpfront-qmail.c M /trunk/smtpfront-reject.c M /trunk/tests/smtpfront-auth-login M /trunk/tests/smtpfront-auth-plain M /trunk/tests/smtpfront-require-auth Removed the default plugins list. ------------------------------------------------------------------------ r429 | bruce | 2006-07-28 09:17:46 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/qmqp-mainloop.c M /trunk/qmqpfront-echo.c M /trunk/qmqpfront-qmail.c M /trunk/qmqpfront-reject.c M /trunk/qmtp-mainloop.c M /trunk/qmtpfront-echo.c M /trunk/qmtpfront-qmail.c M /trunk/qmtpfront-reject.c M /trunk/smtp-mainloop.c M /trunk/smtpfront-echo.c M /trunk/smtpfront-qmail.c M /trunk/smtpfront-reject.c Renamed all the protocol main loops to "protocol_mainloop" ------------------------------------------------------------------------ r428 | bruce | 2006-07-26 17:39:56 -0600 (Wed, 26 Jul 2006) | 3 lines Changed paths: M /trunk/plugins.c M /trunk/std-handle.html M /trunk/tests.inc Renamed $PLUGINS_PATH to $MODULE_PATH, as that path will also include frontends and backends. ------------------------------------------------------------------------ r427 | bruce | 2006-07-26 17:26:50 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: D /trunk/null-validate.c Removed unused null validation plugin. ------------------------------------------------------------------------ r426 | bruce | 2006-07-26 17:23:41 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/plugin-add-received=so M /trunk/plugin-check-fqdn=so M /trunk/plugin-counters=so M /trunk/plugin-cvm-validate=so M /trunk/plugin-mailrules=so M /trunk/plugin-patterns=so M /trunk/plugin-qmail-validate.c M /trunk/plugin-qmail-validate=so M /trunk/plugin-relayclient=so M /trunk/plugin-require-auth=so Removed the last vestiges of the PLUGIN macro. ------------------------------------------------------------------------ r425 | bruce | 2006-07-26 17:08:32 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: M /trunk/TODO A /trunk/backend-echo.c (from /trunk/echo-backend.c:412) A /trunk/backend-qmail.c (from /trunk/qmail-backend.c:412) A /trunk/backend-reject.c (from /trunk/reject-backend.c:412) D /trunk/echo-backend.c D /trunk/qmail-backend.c M /trunk/qmail=l M /trunk/qmqpfront-echo=x M /trunk/qmqpfront-reject=x M /trunk/qmtpfront-echo=x M /trunk/qmtpfront-reject=x D /trunk/reject-backend.c M /trunk/smtpfront-echo=x M /trunk/smtpfront-reject=x Renamed all backend code files to backend-*. ------------------------------------------------------------------------ r424 | bruce | 2006-07-26 17:03:05 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO M /trunk/mailfront.h M /trunk/mailfront=l M /trunk/plugins.c M /trunk/qmqpfront-echo.c M /trunk/qmqpfront-echo=x M /trunk/qmqpfront-qmail.c M /trunk/qmqpfront-reject.c M /trunk/qmtpfront-echo.c M /trunk/qmtpfront-echo=x M /trunk/qmtpfront-qmail.c M /trunk/qmtpfront-reject.c M /trunk/smtpfront-echo.c M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail.c M /trunk/smtpfront-reject.c M /trunk/std-handle.c M /trunk/tests/patterns-after M /trunk/tests/patterns-general M /trunk/tests/patterns-header M /trunk/tests/patterns-message M /trunk/tests/patterns-normal M /trunk/tests/qmqpfront-echo M /trunk/tests/qmtpfront-echo M /trunk/tests/received M /trunk/tests/rules-asterisk M /trunk/tests/rules-both M /trunk/tests/rules-cdb M /trunk/tests/rules-databytes M /trunk/tests/rules-databytes2 M /trunk/tests/rules-defaultmsg M /trunk/tests/rules-empty M /trunk/tests/rules-header-add M /trunk/tests/rules-list M /trunk/tests/rules-maxhops M /trunk/tests/rules-multiline M /trunk/tests/rules-negate M /trunk/tests/rules-noop M /trunk/tests/rules-rcptlist M /trunk/tests/rules-recip M /trunk/tests/rules-selector M /trunk/tests/rules-sender M /trunk/tests/smtpfront-bad-bounce M /trunk/tests/smtpfront-content M /trunk/tests/smtpfront-databytes M /trunk/tests/smtpfront-looping-delivered-to M /trunk/tests/smtpfront-looping-received M /trunk/tests/smtpfront-maxrcpts M /trunk/tests.inc Switched all validation routines from hard-plugged to dynamically plugged. ------------------------------------------------------------------------ r423 | bruce | 2006-07-26 16:38:55 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: M /trunk/plugin-cvm-validate=so Added the missing -lcvm-v2client library needed for the cvm-validate plugin. ------------------------------------------------------------------------ r422 | bruce | 2006-07-26 16:36:34 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: A /trunk/conf-modules Added missing config file. ------------------------------------------------------------------------ r421 | bruce | 2006-07-26 16:36:06 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: M /trunk/qmqp-mainloop.c M /trunk/qmtp-mainloop.c M /trunk/session.c M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c Moved the global struct session into session.c ------------------------------------------------------------------------ r420 | bruce | 2006-07-26 16:24:44 -0600 (Wed, 26 Jul 2006) | 3 lines Changed paths: D /trunk/BIN A /trunk/INSTHIER (from /trunk/BIN:412) A /trunk/plugin-add-received=so A /trunk/plugin-check-fqdn=so A /trunk/plugin-counters=so A /trunk/plugin-cvm-validate=so A /trunk/plugin-mailrules=so A /trunk/plugin-patterns=so A /trunk/plugin-qmail-validate=so A /trunk/plugin-relayclient=so A /trunk/plugin-require-auth=so Compile all the plugins into shared objects, and install them in `conf-modules`. ------------------------------------------------------------------------ r419 | bruce | 2006-07-26 16:23:02 -0600 (Wed, 26 Jul 2006) | 3 lines Changed paths: M /trunk/plugin-qmail-validate.c Make sure conf_qmail is included statically if qmail-validate is being compiled as a plugin. ------------------------------------------------------------------------ r418 | bruce | 2006-07-26 16:22:16 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront=l Add plugins.o object to the mailfront library, missed in last commit. ------------------------------------------------------------------------ r417 | bruce | 2006-07-26 16:21:45 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.h A /trunk/plugins.c M /trunk/qmqpfront-echo=x M /trunk/qmqpfront-qmail=x M /trunk/qmqpfront-reject=x M /trunk/qmtpfront-echo=x M /trunk/qmtpfront-qmail=x M /trunk/qmtpfront-reject=x M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject=x M /trunk/std-handle.c M /trunk/std-handle.html Added support for loading plugins dynamically. ------------------------------------------------------------------------ r416 | bruce | 2006-07-26 15:35:33 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/plugin-add-received.c M /trunk/plugin-check-fqdn.c M /trunk/plugin-counters.c M /trunk/plugin-cvm-validate.c M /trunk/plugin-mailrules.c M /trunk/plugin-patterns.c M /trunk/plugin-qmail-validate.c M /trunk/plugin-relayclient.c M /trunk/plugin-require-auth.c Added a macro for defining the struct plugin in plugins. ------------------------------------------------------------------------ r415 | bruce | 2006-07-26 15:19:08 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/null-validate.c M /trunk/plugin-add-received.c M /trunk/plugin-check-fqdn.c M /trunk/plugin-counters.c M /trunk/plugin-cvm-validate.c M /trunk/plugin-mailrules.c M /trunk/plugin-patterns.c M /trunk/plugin-qmail-validate.c M /trunk/plugin-relayclient.c M /trunk/plugin-require-auth.c M /trunk/std-handle.c Renamed "module" to "plugin" in all relevant files. ------------------------------------------------------------------------ r414 | bruce | 2006-07-26 15:16:11 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: D /trunk/add-received.c D /trunk/check-fqdn.c D /trunk/counters.c D /trunk/cvm-validate.c M /trunk/mailfront=l D /trunk/mailrules.c D /trunk/patterns.c A /trunk/plugin-add-received.c (from /trunk/add-received.c:412) A /trunk/plugin-check-fqdn.c (from /trunk/check-fqdn.c:412) A /trunk/plugin-counters.c (from /trunk/counters.c:412) A /trunk/plugin-cvm-validate.c (from /trunk/cvm-validate.c:412) A /trunk/plugin-mailrules.c (from /trunk/mailrules.c:412) A /trunk/plugin-patterns.c (from /trunk/patterns.c:412) A /trunk/plugin-qmail-validate.c (from /trunk/qmail-validate.c:412) A /trunk/plugin-relayclient.c (from /trunk/relayclient.c:412) A /trunk/plugin-require-auth.c (from /trunk/require-auth.c:412) D /trunk/qmail-validate.c M /trunk/qmail=l D /trunk/relayclient.c D /trunk/require-auth.c Renamed the module source files to add a "plugin-" prefix. ------------------------------------------------------------------------ r413 | bruce | 2006-07-26 11:28:49 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: A /trunk/mailfront=l Added missing file. ------------------------------------------------------------------------ r412 | bruce | 2006-07-22 23:25:02 -0600 (Sat, 22 Jul 2006) | 2 lines Changed paths: M /trunk/TODO M /trunk/require-auth.c M /trunk/std-handle.c Modularization: final module (I hope) -- require-auth. ------------------------------------------------------------------------ r411 | bruce | 2006-07-22 23:18:51 -0600 (Sat, 22 Jul 2006) | 2 lines Changed paths: M /trunk/TODO M /trunk/add-received.c M /trunk/mailrules.c D /trunk/mailrules.h M /trunk/relayclient.c M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/std-handle.c Modularization: made mailrules a module. ------------------------------------------------------------------------ r410 | bruce | 2006-07-22 23:12:19 -0600 (Sat, 22 Jul 2006) | 3 lines Changed paths: M /trunk/counters.c M /trunk/mailfront.h M /trunk/mailrules.c M /trunk/std-handle.c Fixed up counter handling slightly, required to move things out of std-handle.c and still maintain proper semantics. ------------------------------------------------------------------------ r409 | bruce | 2006-07-22 22:43:57 -0600 (Sat, 22 Jul 2006) | 3 lines Changed paths: M /trunk/TODO A /trunk/check-fqdn.c A /trunk/counters.c M /trunk/mailfront.h M /trunk/patterns.c M /trunk/std-handle.c Modularization: made patterns a proper module and added a module for various counters -- too many recipients, hops, or bytes. ------------------------------------------------------------------------ r408 | bruce | 2006-07-22 10:40:50 -0600 (Sat, 22 Jul 2006) | 2 lines Changed paths: M /trunk/TODO M /trunk/add-received.c M /trunk/mailfront.h M /trunk/mailrules.c M /trunk/mailrules.h M /trunk/patterns.c M /trunk/qmail-backend.c M /trunk/qmqp=l M /trunk/qmqpfront-echo=x M /trunk/qmqpfront-qmail=x M /trunk/qmqpfront-reject=x M /trunk/qmtp=l M /trunk/qmtpfront-echo=x M /trunk/qmtpfront-qmail=x M /trunk/qmtpfront-reject=x M /trunk/relayclient.c A /trunk/session.c M /trunk/smtp=l M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject=x M /trunk/std-handle.c Moved rules-specific environment variables into session-generic code. ------------------------------------------------------------------------ r407 | bruce | 2006-07-22 10:12:06 -0600 (Sat, 22 Jul 2006) | 3 lines Changed paths: M /trunk/TODO M /trunk/add-received.c M /trunk/cvm-validate.c M /trunk/echo-backend.c M /trunk/mailfront.h M /trunk/qmail-backend.c M /trunk/qmail-validate.c M /trunk/qmqp-mainloop.c M /trunk/qmtp-mainloop.c M /trunk/reject-backend.c M /trunk/relayclient.c M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/std-handle.c Moved the session parameter back into a global, simplifying a lot of function calls (and some code). ------------------------------------------------------------------------ r406 | bruce | 2006-07-22 09:42:23 -0600 (Sat, 22 Jul 2006) | 2 lines Changed paths: M /trunk/TODO A /trunk/add-received.c M /trunk/mailfront.h M /trunk/qmqp=l M /trunk/qmtp=l M /trunk/smtp=l M /trunk/std-handle.c Modularization: moved Received: header generation into a module. ------------------------------------------------------------------------ r405 | bruce | 2006-07-22 08:57:46 -0600 (Sat, 22 Jul 2006) | 2 lines Changed paths: M /trunk/relayclient.c M /trunk/std-handle.c Removed the extraneous authenticated logic out of std-handle.c ------------------------------------------------------------------------ r404 | bruce | 2006-07-21 18:03:23 -0600 (Fri, 21 Jul 2006) | 2 lines Changed paths: M /trunk/qmqp=l M /trunk/qmtp=l A /trunk/relayclient.c A /trunk/require-auth.c M /trunk/smtp=l M /trunk/std-handle.c Modularization: moved relayclient + authenticated logic into a module. ------------------------------------------------------------------------ r403 | bruce | 2006-07-21 17:44:12 -0600 (Fri, 21 Jul 2006) | 2 lines Changed paths: M /trunk/cvm-validate.c M /trunk/mailfront.h M /trunk/std-handle.c Modularization: moved CVM validation of recipients into a module. ------------------------------------------------------------------------ r402 | bruce | 2006-07-21 17:37:29 -0600 (Fri, 21 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/null-validate.c M /trunk/qmail-validate.c M /trunk/std-handle.c Modularization: made backend validation a module. ------------------------------------------------------------------------ r401 | bruce | 2006-07-21 17:19:28 -0600 (Fri, 21 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/std-handle.c Modularization: start of the dynamic module framework. ------------------------------------------------------------------------ r400 | bruce | 2006-07-21 16:42:34 -0600 (Fri, 21 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/qmqp-mainloop.c M /trunk/qmtp-mainloop.c M /trunk/reject-backend.c M /trunk/smtp-commands.c M /trunk/std-handle.c Modularization: eliminated globals maxdatabytes, maxhops, and maxrcpts. ------------------------------------------------------------------------ r399 | bruce | 2006-07-21 16:11:02 -0600 (Fri, 21 Jul 2006) | 2 lines Changed paths: M /trunk/echo-backend.c M /trunk/mailfront.h M /trunk/qmail-backend.c M /trunk/qmqp-mainloop.c M /trunk/qmtp-mainloop.c M /trunk/reject-backend.c M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/std-handle.c Modularization: moved the session from a global to a parameter. ------------------------------------------------------------------------ r398 | bruce | 2006-07-21 15:41:11 -0600 (Fri, 21 Jul 2006) | 3 lines Changed paths: M /trunk/mailfront.h M /trunk/qmqp-mainloop.c M /trunk/qmtp-mainloop.c M /trunk/reject-backend.c M /trunk/smtp-commands.c M /trunk/std-handle.c More modularization: move the protocol and helo_domain parameters into the session structure. ------------------------------------------------------------------------ r397 | bruce | 2006-07-21 15:28:37 -0600 (Fri, 21 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/qmqp-mainloop.c M /trunk/reject-backend.c M /trunk/smtp-commands.c M /trunk/std-handle.c Starting modularization: move several globals into a session structure. ------------------------------------------------------------------------ r396 | bruce | 2006-07-21 15:28:12 -0600 (Fri, 21 Jul 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.99 ------------------------------------------------------------------------ r395 | bruce | 2006-07-18 16:19:36 -0600 (Tue, 18 Jul 2006) | 1 line Changed paths: A /tags/0.98.1 (from /trunk:394) Tagged version 0.98.1 ------------------------------------------------------------------------ r394 | bruce | 2005-10-29 12:54:15 -0600 (Sat, 29 Oct 2005) | 4 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c Fixed the $REQUIRE_AUTH feature to properly check for $RELAYCLIENT being set by looking up $RELAYCLIENT before (and after) checking the sender against mail rules. ------------------------------------------------------------------------ r393 | bruce | 2005-10-29 12:48:10 -0600 (Sat, 29 Oct 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.98.1 ------------------------------------------------------------------------ r392 | bruce | 2005-10-26 11:34:57 -0600 (Wed, 26 Oct 2005) | 1 line Changed paths: A /tags/0.98 (from /trunk:391) Tagged version 0.98 ------------------------------------------------------------------------ r391 | bruce | 2005-10-26 11:29:55 -0600 (Wed, 26 Oct 2005) | 2 lines Changed paths: M /trunk/NEWS Added note to NEWS about MSA support. ------------------------------------------------------------------------ r390 | bruce | 2005-10-26 11:22:24 -0600 (Wed, 26 Oct 2005) | 2 lines Changed paths: M /trunk/imapfront.html M /trunk/msa.html M /trunk/pop3front.html M /trunk/smtpfront.html Added links for all RFC references. ------------------------------------------------------------------------ r389 | bruce | 2005-10-25 22:43:43 -0600 (Tue, 25 Oct 2005) | 2 lines Changed paths: M /trunk/TODO Updated the TODO document. ------------------------------------------------------------------------ r388 | bruce | 2005-10-25 22:43:34 -0600 (Tue, 25 Oct 2005) | 2 lines Changed paths: A /trunk/tests/qmqpfront-echo A /trunk/tests/qmtpfront-echo Added simple tests for the QMQP/QMTP front-ends. ------------------------------------------------------------------------ r387 | bruce | 2005-10-25 17:26:31 -0600 (Tue, 25 Oct 2005) | 2 lines Changed paths: M /trunk/msa.html M /trunk/smtpfront.html Cleaned up the MSA documentation. ------------------------------------------------------------------------ r386 | bruce | 2005-10-25 17:20:37 -0600 (Tue, 25 Oct 2005) | 3 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.h D /trunk/msa.c M /trunk/qmqp=l M /trunk/qmtp=l M /trunk/smtp=l M /trunk/std-handle.c M /trunk/std-handle.html M /trunk/tests/patterns-after M /trunk/tests/patterns-general M /trunk/tests/patterns-header M /trunk/tests/patterns-message M /trunk/tests/patterns-normal M /trunk/tests/received M /trunk/tests/rules-asterisk M /trunk/tests/rules-both M /trunk/tests/rules-cdb M /trunk/tests/rules-databytes M /trunk/tests/rules-databytes2 M /trunk/tests/rules-defaultmsg M /trunk/tests/rules-empty M /trunk/tests/rules-header-add M /trunk/tests/rules-list M /trunk/tests/rules-maxhops M /trunk/tests/rules-multiline M /trunk/tests/rules-negate M /trunk/tests/rules-noop M /trunk/tests/rules-rcptlist M /trunk/tests/rules-recip M /trunk/tests/rules-selector M /trunk/tests/rules-sender M /trunk/tests/smtpfront-auth-login M /trunk/tests/smtpfront-auth-plain M /trunk/tests/smtpfront-bad-bounce M /trunk/tests/smtpfront-content M /trunk/tests/smtpfront-databytes M /trunk/tests/smtpfront-looping-delivered-to M /trunk/tests/smtpfront-looping-received M /trunk/tests/smtpfront-maxrcpts M /trunk/tests/smtpfront-quotes M /trunk/tests/smtpfront-require-auth Moved most of the MSA functionality into std-handle.c, making FQDNs unconditionally mandatory. ------------------------------------------------------------------------ r385 | bruce | 2005-10-25 00:14:06 -0600 (Tue, 25 Oct 2005) | 3 lines Changed paths: M /trunk/std-handle.html Fixed the std-handle HTML documentation to not mirror the SMTP front end documentation. ------------------------------------------------------------------------ r384 | bruce | 2005-10-24 15:17:43 -0600 (Mon, 24 Oct 2005) | 2 lines Changed paths: M /trunk/reject-backend.c M /trunk/responses.c M /trunk/responses.h M /trunk/std-handle.c Moved the duplicated number_ok and response_ok functions into responses.c ------------------------------------------------------------------------ r383 | bruce | 2005-10-24 15:09:30 -0600 (Mon, 24 Oct 2005) | 2 lines Changed paths: M /trunk/NEWS A /trunk/qmqpfront-reject.c (from /trunk/smtpfront-reject.c:382) A /trunk/qmqpfront-reject=x (from /trunk/smtpfront-reject=x:382) A /trunk/qmtpfront-reject.c (from /trunk/smtpfront-reject.c:382) A /trunk/qmtpfront-reject=x (from /trunk/smtpfront-reject=x:382) M /trunk/reject-backend.c Added QMQP and QMTP "reject" front ends, for completeness. ------------------------------------------------------------------------ r382 | bruce | 2005-10-24 15:01:32 -0600 (Mon, 24 Oct 2005) | 2 lines Changed paths: A /trunk/reject-backend.c (from /trunk/smtpfront-reject.c:378) M /trunk/smtpfront-reject.c M /trunk/smtpfront-reject=x Broke apart the reject backend to make it useable for the other protocols. ------------------------------------------------------------------------ r381 | bruce | 2005-10-24 14:55:03 -0600 (Mon, 24 Oct 2005) | 3 lines Changed paths: M /trunk/smtpfront.html A /trunk/std-handle.html (from /trunk/smtpfront.html:376) Broke the SMTP documentation into its two logical parts, separating out the parts the belong to std-handle.c ------------------------------------------------------------------------ r380 | bruce | 2005-10-24 14:51:22 -0600 (Mon, 24 Oct 2005) | 2 lines Changed paths: M /trunk/qmail-validate.c M /trunk/qmqp=l M /trunk/qmqpfront-qmail=x M /trunk/qmtp=l M /trunk/qmtpfront-qmail=x M /trunk/smtp=l M /trunk/smtpfront-qmail=x M /trunk/std-handle.c Moved the CVM validation hook out of qmail-validate and into std-handle. ------------------------------------------------------------------------ r379 | bruce | 2005-10-24 14:49:57 -0600 (Mon, 24 Oct 2005) | 2 lines Changed paths: M /trunk/tests/smtpfront-require-auth Fixed up message for "authentication required". ------------------------------------------------------------------------ r378 | bruce | 2005-10-24 14:45:02 -0600 (Mon, 24 Oct 2005) | 2 lines Changed paths: M /trunk/smtpfront-reject.c Skip going through std-handle.c for the simple reject backend. ------------------------------------------------------------------------ r377 | bruce | 2005-10-22 00:20:20 -0600 (Sat, 22 Oct 2005) | 2 lines Changed paths: M /trunk/std-handle.c Fix up the SMTP code for the "authentication required" message. ------------------------------------------------------------------------ r376 | bruce | 2005-10-22 00:17:12 -0600 (Sat, 22 Oct 2005) | 4 lines Changed paths: M /trunk/NEWS M /trunk/smtpfront.html M /trunk/std-handle.c A /trunk/tests/smtpfront-require-auth Added support for rejecting all mail unless client is authenticated (either as a relay client or with SMTP authentication) if $REQUIRE_AUTH is set. ------------------------------------------------------------------------ r375 | bruce | 2005-10-21 16:04:51 -0600 (Fri, 21 Oct 2005) | 2 lines Changed paths: M /trunk/smtp-mainloop.c Added a missing extended mail system status code to a response here. ------------------------------------------------------------------------ r374 | bruce | 2005-10-20 23:01:40 -0600 (Thu, 20 Oct 2005) | 2 lines Changed paths: M /trunk/tests/patterns-after M /trunk/tests/patterns-general M /trunk/tests/patterns-header M /trunk/tests/patterns-message M /trunk/tests/patterns-normal M /trunk/tests/rules-databytes M /trunk/tests/rules-databytes2 M /trunk/tests/rules-header-add M /trunk/tests/rules-maxhops M /trunk/tests/smtpfront-auth-login M /trunk/tests/smtpfront-auth-plain M /trunk/tests/smtpfront-bad-bounce M /trunk/tests/smtpfront-content M /trunk/tests/smtpfront-databytes M /trunk/tests/smtpfront-looping-delivered-to M /trunk/tests/smtpfront-looping-received M /trunk/tests/smtpfront-maxnotimpl M /trunk/tests/smtpfront-maxrcpts M /trunk/tests/smtpfront-reject Adjusted messages in the tests to match the current strings. ------------------------------------------------------------------------ r373 | bruce | 2005-10-20 22:55:56 -0600 (Thu, 20 Oct 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/pop3front-maildir.c M /trunk/tests/pop3front-maildir-state Truncate UIDL responses to 70 characters as per RFC 1939. ------------------------------------------------------------------------ r372 | bruce | 2005-10-20 22:11:31 -0600 (Thu, 20 Oct 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/cvm-validate.c M /trunk/mailrules.c M /trunk/msa.c M /trunk/qmail-backend.c M /trunk/qmail-validate.c M /trunk/qmqp-mainloop.c M /trunk/qmtp-mainloop.c M /trunk/responses.c M /trunk/responses.h M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/std-handle.c Added enhanced mail system status codes (RFC 1893/2034). ------------------------------------------------------------------------ r371 | bruce | 2005-10-20 14:15:47 -0600 (Thu, 20 Oct 2005) | 2 lines Changed paths: M /trunk/smtpfront-reject.c Eliminate unused variable warnings in smtpfront-reject.c ------------------------------------------------------------------------ r370 | bruce | 2005-10-19 22:56:28 -0600 (Wed, 19 Oct 2005) | 3 lines Changed paths: M /trunk/msa.c M /trunk/msa.html Added support for adding a default host and domain to addresses that are missing them in MSA mode. ------------------------------------------------------------------------ r369 | bruce | 2005-10-18 17:05:55 -0600 (Tue, 18 Oct 2005) | 2 lines Changed paths: M /trunk/echo-backend.c A /trunk/null-validate.c (from /trunk/echo-backend.c:342) M /trunk/qmqpfront-echo=x M /trunk/qmtpfront-echo=x M /trunk/smtpfront-echo=x Broke the stub validate routines out of echo-backend.c ------------------------------------------------------------------------ r368 | bruce | 2005-10-18 17:03:50 -0600 (Tue, 18 Oct 2005) | 3 lines Changed paths: M /trunk/mailfront.h A /trunk/msa.c A /trunk/msa.html M /trunk/qmqp=l M /trunk/qmtp=l M /trunk/smtp=l M /trunk/smtpfront.html M /trunk/std-handle.c Added the start of hooks and documentation on RFC 2476 "Message Submission Agent" mode. ------------------------------------------------------------------------ r367 | bruce | 2005-10-14 11:29:46 -0600 (Fri, 14 Oct 2005) | 3 lines Changed paths: M /trunk/mailrules.c M /trunk/responses.c Use the RESPONSE macro for all "const response resp_*" definitions to make searching the sources easier. ------------------------------------------------------------------------ r366 | bruce | 2005-10-13 14:04:20 -0600 (Thu, 13 Oct 2005) | 4 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c M /trunk/tests/smtpfront-bad-bounce Removed the "bounce must have a single recipient" rule, as it is currently causing more problems (with address checkers) than it is solving (spammers no longer use this technique). ------------------------------------------------------------------------ r365 | bruce | 2005-10-13 10:45:02 -0600 (Thu, 13 Oct 2005) | 2 lines Changed paths: M /trunk/qmail-backend.c Fixed an "assignment discards qualifiers" warning. ------------------------------------------------------------------------ r364 | bruce | 2005-10-13 10:43:50 -0600 (Thu, 13 Oct 2005) | 2 lines Changed paths: M /trunk/qmail-backend.c Tweaked permanent qmail-queue failure error message. ------------------------------------------------------------------------ r363 | bruce | 2005-10-12 16:38:23 -0600 (Wed, 12 Oct 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c A /trunk/tests/smtpfront-maxrcpts Fixed one-off bug in counting recipients for $MAXRCPTS. ------------------------------------------------------------------------ r362 | bruce | 2005-10-12 16:35:54 -0600 (Wed, 12 Oct 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.98. ------------------------------------------------------------------------ r361 | bruce | 2005-10-05 00:12:51 -0600 (Wed, 05 Oct 2005) | 1 line Changed paths: A /tags/0.97 (from /trunk:360) Tagged version 0.97 ------------------------------------------------------------------------ r360 | bruce | 2005-10-04 23:44:14 -0600 (Tue, 04 Oct 2005) | 2 lines Changed paths: M /trunk/spec Renamed "Copyright:" field in spec to "License:". ------------------------------------------------------------------------ r359 | bruce | 2005-10-04 11:37:31 -0600 (Tue, 04 Oct 2005) | 4 lines Changed paths: M /trunk/NEWS M /trunk/cvm-validate.c Fixed typo in the CVM lookup code that would prevent the proper operation of lookup secrets. Thanks Dale Woolridge ------------------------------------------------------------------------ r358 | bruce | 2005-09-22 16:12:14 -0600 (Thu, 22 Sep 2005) | 2 lines Changed paths: M /trunk/qmail-backend.c Fixed typo in a comparison operator. ------------------------------------------------------------------------ r357 | bruce | 2005-09-22 15:46:06 -0600 (Thu, 22 Sep 2005) | 3 lines Changed paths: M /trunk/qmail-backend.c M /trunk/qmail-backend.html Fixed up the qmail backend to properly follow qmail's semantics for qmail-queue exit codes from 1 to 10. ------------------------------------------------------------------------ r356 | bruce | 2005-09-22 15:14:52 -0600 (Thu, 22 Sep 2005) | 3 lines Changed paths: M /trunk/NEWS M /trunk/qmail-backend.c M /trunk/qmail-backend.html Add support to the qmail backend for custom qmail-queue error messages taken from $QQERRMSG_#. ------------------------------------------------------------------------ r355 | bruce | 2005-08-12 14:27:15 -0600 (Fri, 12 Aug 2005) | 3 lines Changed paths: M /trunk/NEWS M /trunk/imapfront-auth.c M /trunk/pop3front-auth.c Clear session timeouts (via alarm) before executing authenticated commands in imapfront-auth and pop3front-auth. ------------------------------------------------------------------------ r354 | bruce | 2005-08-12 14:26:34 -0600 (Fri, 12 Aug 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.97 ------------------------------------------------------------------------ r353 | bruce | 2005-07-12 00:02:25 -0600 (Tue, 12 Jul 2005) | 1 line Changed paths: A /tags/0.96 (from /trunk:352) Tagged version 0.96 ------------------------------------------------------------------------ r352 | bruce | 2005-07-11 23:52:10 -0600 (Mon, 11 Jul 2005) | 2 lines Changed paths: M /trunk/spec Depend on the new bglibs that has the fixed glob functions. ------------------------------------------------------------------------ r351 | bruce | 2005-07-10 23:13:15 -0600 (Sun, 10 Jul 2005) | 3 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c M /trunk/mailrules.html M /trunk/tests/rules-asterisk Switched Pattern matching from the simpler mechanism (originated in multilog) to standard shell glob. ------------------------------------------------------------------------ r350 | bruce | 2005-07-08 13:17:38 -0600 (Fri, 08 Jul 2005) | 3 lines Changed paths: M /trunk/NEWS M /trunk/smtp-respond.c Fixed extern/static conflicting definition of "line" in smtp-respond.c. Thanks Gerrit Pape ------------------------------------------------------------------------ r349 | bruce | 2005-07-08 13:09:30 -0600 (Fri, 08 Jul 2005) | 2 lines Changed paths: M /trunk/TODO Replaced todo item about negation with one for selectors. ------------------------------------------------------------------------ r348 | bruce | 2005-07-08 12:26:22 -0600 (Fri, 08 Jul 2005) | 3 lines Changed paths: M /trunk/NEWS M /trunk/sasl-stub.c A /trunk/tests/smtpfront-reject Fixed smtpfront-reject crashing on receipt of EHLO. Thanks Janos Farkas ------------------------------------------------------------------------ r347 | bruce | 2005-07-08 00:25:39 -0600 (Fri, 08 Jul 2005) | 3 lines Changed paths: M /trunk/NEWS M /trunk/constants.h M /trunk/smtp-commands.c A /trunk/tests/smtpfront-quotes Fixed the SMTP front-end's inability to handle quoted or escaped characters, or to strip source routing addresses. ------------------------------------------------------------------------ r346 | bruce | 2005-07-08 00:19:44 -0600 (Fri, 08 Jul 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.96 ------------------------------------------------------------------------ r345 | bruce | 2005-06-10 15:12:59 -0600 (Fri, 10 Jun 2005) | 1 line Changed paths: A /tags/0.95 (from /trunk:344) Tagged version 0.95 ------------------------------------------------------------------------ r344 | bruce | 2005-06-10 15:08:45 -0600 (Fri, 10 Jun 2005) | 2 lines Changed paths: M /trunk/spec Fixed install stage in spec. ------------------------------------------------------------------------ r343 | bruce | 2005-06-10 13:39:20 -0600 (Fri, 10 Jun 2005) | 3 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c A /trunk/tests/rules-databytes2 Fixed bug in handling of environment variables when applying multiple rules to the same message. ------------------------------------------------------------------------ r342 | bruce | 2005-06-10 12:23:48 -0600 (Fri, 10 Jun 2005) | 2 lines Changed paths: A /trunk/BIN M /trunk/README.in D /trunk/insthier.c M /trunk/spec Switch installation procedure to use new bg-installer from bglibs-1.022 ------------------------------------------------------------------------ r341 | bruce | 2005-06-09 23:31:00 -0600 (Thu, 09 Jun 2005) | 2 lines Changed paths: M /trunk/tests/patterns-after M /trunk/tests/patterns-general M /trunk/tests/patterns-header M /trunk/tests/patterns-message M /trunk/tests/patterns-normal M /trunk/tests/rules-asterisk M /trunk/tests/rules-both M /trunk/tests/rules-cdb M /trunk/tests/rules-databytes M /trunk/tests/rules-defaultmsg M /trunk/tests/rules-empty M /trunk/tests/rules-header-add M /trunk/tests/rules-list M /trunk/tests/rules-maxhops M /trunk/tests/rules-multiline M /trunk/tests/rules-negate M /trunk/tests/rules-noop M /trunk/tests/rules-recip M /trunk/tests/rules-selector M /trunk/tests/rules-sender M /trunk/tests/smtpfront-databytes M /trunk/tests/smtpfront-looping-delivered-to M /trunk/tests/smtpfront-looping-received M /trunk/tests/smtpfront-maxnotimpl M /trunk/tests.inc Made the test scripts more portable (tested with ash). ------------------------------------------------------------------------ r340 | bruce | 2005-06-09 16:47:14 -0600 (Thu, 09 Jun 2005) | 3 lines Changed paths: M /trunk/tests.inc Fixed the selftests to use the invoking user's UID/GID. Thanks Janos Farkas ------------------------------------------------------------------------ r339 | bruce | 2005-06-09 16:46:01 -0600 (Thu, 09 Jun 2005) | 4 lines Changed paths: M /trunk/NEWS M /trunk/patterns.c M /trunk/tests/patterns-header Fixed bug in header pattern matching that made it only look at the first header line. Thanks Janos Farkas ------------------------------------------------------------------------ r338 | bruce | 2005-06-09 16:44:36 -0600 (Thu, 09 Jun 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.95 ------------------------------------------------------------------------ r337 | bruce | 2005-06-02 00:35:50 -0600 (Thu, 02 Jun 2005) | 1 line Changed paths: A /tags/0.94 (from /trunk:336) Tagged version 0.94 ------------------------------------------------------------------------ r336 | bruce | 2005-06-01 23:35:05 -0600 (Wed, 01 Jun 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/cvm-validate.c M /trunk/imapfront-auth.c M /trunk/imapfront-auth=x M /trunk/pop3front-auth.c M /trunk/pop3front-auth=x M /trunk/qmqpfront-echo=x M /trunk/qmqpfront-qmail=x M /trunk/qmtpfront-echo=x M /trunk/qmtpfront-qmail=x D /trunk/sasl-auth.c D /trunk/sasl-auth.h M /trunk/sasl-stub.c M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/smtp.h M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x Switched to CVM 2 support, with new SASL library etc. ------------------------------------------------------------------------ r335 | bruce | 2005-06-01 23:20:37 -0600 (Wed, 01 Jun 2005) | 2 lines Changed paths: M /trunk/tests.inc Use cvm-pwfile instead of a shell script for testing authentication. ------------------------------------------------------------------------ r334 | bruce | 2005-06-01 23:19:59 -0600 (Wed, 01 Jun 2005) | 2 lines Changed paths: M /trunk/makedist.py Put the ChangeLog on the web site. ------------------------------------------------------------------------ r333 | bruce | 2005-06-01 19:30:29 -0600 (Wed, 01 Jun 2005) | 2 lines Changed paths: M /trunk/README.in M /trunk/spec Document the current version requirements. ------------------------------------------------------------------------ r332 | bruce | 2005-05-30 23:45:10 -0600 (Mon, 30 May 2005) | 2 lines Changed paths: M /trunk/tests/rules-rcptlist Fixed up a test that was broken by recent changes to spac-tests ------------------------------------------------------------------------ r331 | bruce | 2005-05-30 23:13:09 -0600 (Mon, 30 May 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/patterns.c M /trunk/patterns.html A /trunk/tests/patterns-header Added support for restricting patterns to match only in headers. ------------------------------------------------------------------------ r330 | bruce | 2005-05-30 23:02:27 -0600 (Mon, 30 May 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.94 ------------------------------------------------------------------------ r329 | bruce | 2005-04-21 11:21:00 -0600 (Thu, 21 Apr 2005) | 1 line Changed paths: A /tags/0.93 (from /trunk:328) Tagged version 0.93 ------------------------------------------------------------------------ r328 | bruce | 2005-04-21 11:02:44 -0600 (Thu, 21 Apr 2005) | 2 lines Changed paths: M /trunk/README.in Use the new @YEAR@ macro in the copyright statement. ------------------------------------------------------------------------ r327 | bruce | 2005-04-21 00:31:47 -0600 (Thu, 21 Apr 2005) | 3 lines Changed paths: M /trunk/NEWS M /trunk/imapfront-auth.c M /trunk/imapfront.html M /trunk/pop3front-auth.c M /trunk/pop3front-maildir.c M /trunk/pop3front.html M /trunk/std-handle.c M /trunk/timeout.c Added seperate $AUTH_TIMEOUT and $AUTH_SESSION_TIMEOUT overrides for the authentication front-ends (imapfront-auth and pop3front-auth). ------------------------------------------------------------------------ r326 | bruce | 2004-12-04 11:59:06 -0600 (Sat, 04 Dec 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c A /trunk/tests/rules-rcptlist Fixed bug in handling multiple sender or recipient specific rules. ------------------------------------------------------------------------ r325 | bruce | 2004-12-04 11:58:13 -0600 (Sat, 04 Dec 2004) | 4 lines Changed paths: M /trunk/NEWS M /trunk/cvm-validate.c M /trunk/smtpfront.html Modified the CVM lookup secret handling to use $CVM_LOOKUP_SECRET just like the latest CVM code, falling back to $LOOKUP_SECRET if that isn't set. ------------------------------------------------------------------------ r324 | bruce | 2004-12-03 12:26:40 -0600 (Fri, 03 Dec 2004) | 5 lines Changed paths: M /trunk/NEWS M /trunk/patterns.c A /trunk/tests/patterns-general Fixed bug in pattern matching where the pattern was longer than the line that would other match. This relied on the erroneous assumption that patterns would always be shorter than the lines they were intended to match. ------------------------------------------------------------------------ r323 | bruce | 2004-12-03 10:56:18 -0600 (Fri, 03 Dec 2004) | 2 lines Changed paths: A /trunk/tests/rules-databytes (from /trunk/tests/smtpfront-databytes:320) Added test to ensure databytes is being obeyed. ------------------------------------------------------------------------ r322 | bruce | 2004-12-02 10:03:00 -0600 (Thu, 02 Dec 2004) | 3 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c Fixed omission of not resetting maxdatabytes, which could be set by a rule, after checking for sender rules. ------------------------------------------------------------------------ r321 | bruce | 2004-12-02 10:01:36 -0600 (Thu, 02 Dec 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c Fixed bug in parsing the databytes column in mail rules. ------------------------------------------------------------------------ r320 | bruce | 2004-10-29 16:03:27 -0600 (Fri, 29 Oct 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.93 ------------------------------------------------------------------------ r319 | bruce | 2004-10-29 16:01:42 -0600 (Fri, 29 Oct 2004) | 1 line Changed paths: A /tags/0.92 (from /trunk:318) Tagged version 0.92 ------------------------------------------------------------------------ r318 | bruce | 2004-10-29 15:56:13 -0600 (Fri, 29 Oct 2004) | 2 lines Changed paths: M /trunk/tests.inc Use the newer "-n" format for head/tail. ------------------------------------------------------------------------ r317 | bruce | 2004-03-25 16:49:51 -0600 (Thu, 25 Mar 2004) | 3 lines Changed paths: M /trunk/NEWS M /trunk/imapfront-auth.c Fixed bug: Only set $MAILDIR in imapfront-auth if the CVM set it. Thanks Charlie Brady. ------------------------------------------------------------------------ r316 | bruce | 2004-03-11 12:20:12 -0600 (Thu, 11 Mar 2004) | 3 lines Changed paths: M /trunk/NEWS M /trunk/patterns.c M /trunk/tests/patterns-normal Fixed bug in pattern handling that would cause a bogus "out of memory" error if the patterns file had a blank line. ------------------------------------------------------------------------ r315 | bruce | 2004-03-06 22:29:04 -0600 (Sat, 06 Mar 2004) | 3 lines Changed paths: M /trunk/NEWS M /trunk/qmqp-mainloop.c Fixed bug in QMQP front-end that prevented it from accepting relayed messages (relayclient wasn't getting set properly). ------------------------------------------------------------------------ r314 | bruce | 2004-03-06 22:25:47 -0600 (Sat, 06 Mar 2004) | 2 lines Changed paths: M /trunk/insthier.c Added qmqpfront-echo and qmtpfront-echo test front-ends to insthier. ------------------------------------------------------------------------ r313 | bruce | 2004-03-06 22:25:00 -0600 (Sat, 06 Mar 2004) | 2 lines Changed paths: M /trunk/smtpfront-echo.c Fixed program name. ------------------------------------------------------------------------ r312 | bruce | 2004-03-06 22:24:47 -0600 (Sat, 06 Mar 2004) | 2 lines Changed paths: M /trunk/NEWS A /trunk/qmqpfront-echo.c (from /trunk/smtpfront-echo.c:293) A /trunk/qmqpfront-echo=x (from /trunk/smtpfront-echo=x:302) A /trunk/qmtpfront-echo.c (from /trunk/smtpfront-echo.c:293) A /trunk/qmtpfront-echo=x (from /trunk/smtpfront-echo=x:302) Added qmqpfront-echo and qmtpfront-echo test front-ends. ------------------------------------------------------------------------ r311 | bruce | 2004-03-06 22:12:36 -0600 (Sat, 06 Mar 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.92 ------------------------------------------------------------------------ r310 | bruce | 2004-03-05 17:14:35 -0600 (Fri, 05 Mar 2004) | 2 lines Changed paths: M /trunk/smtp-mainloop.c Show a message if the connection drops or times out during a command. ------------------------------------------------------------------------ r309 | bruce | 2004-03-05 16:47:38 -0600 (Fri, 05 Mar 2004) | 2 lines Changed paths: M /trunk/spec Depend on bglibs version 1.016 ------------------------------------------------------------------------ r308 | bruce | 2004-03-05 12:54:31 -0600 (Fri, 05 Mar 2004) | 1 line Changed paths: A /tags/0.91 (from /trunk:307) Tagged version 0.91 ------------------------------------------------------------------------ r307 | bruce | 2004-03-04 17:19:03 -0600 (Thu, 04 Mar 2004) | 2 lines Changed paths: M /trunk/TODO Added notes about better MIME patterns. ------------------------------------------------------------------------ r306 | bruce | 2004-03-04 17:08:43 -0600 (Thu, 04 Mar 2004) | 2 lines Changed paths: M /trunk/patterns.html Added new signature identified by James Triplett on the qmail mailing list. ------------------------------------------------------------------------ r305 | bruce | 2004-03-04 16:59:18 -0600 (Thu, 04 Mar 2004) | 2 lines Changed paths: M /trunk/NEWS Fixed typo in news about Received: header changes. ------------------------------------------------------------------------ r304 | bruce | 2004-03-04 16:58:20 -0600 (Thu, 04 Mar 2004) | 4 lines Changed paths: M /trunk/mailfront.h M /trunk/smtp-commands.c M /trunk/std-handle.c M /trunk/tests/received Try #3 at proper Received: header generation. This time, ${PROTO}LOCALIP and ${PROTO}REMOTEIP don't need to be set (which was the behavior before the last change). ------------------------------------------------------------------------ r303 | bruce | 2004-03-03 23:16:37 -0600 (Wed, 03 Mar 2004) | 3 lines Changed paths: M /trunk/echo-backend.c A /trunk/tests/received Dump the Received: header in the echo backend, so I can use it to test for proper header generation. ------------------------------------------------------------------------ r302 | bruce | 2004-03-03 23:16:00 -0600 (Wed, 03 Mar 2004) | 2 lines Changed paths: M /trunk/imapfront-auth=x M /trunk/pop3front-auth=x M /trunk/pop3front-maildir=x M /trunk/qmqpfront-qmail=x M /trunk/qmtpfront-qmail=x M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject=x M /trunk/spec Switched to bglibs 1.015 using -lbg. ------------------------------------------------------------------------ r301 | bruce | 2004-03-03 23:14:50 -0600 (Wed, 03 Mar 2004) | 3 lines Changed paths: M /trunk/std-handle.c M /trunk/tests/patterns-after M /trunk/tests/rules-header-add M /trunk/tests/rules-maxhops M /trunk/tests/smtpfront-bad-bounce M /trunk/tests/smtpfront-content M /trunk/tests/smtpfront-looping-delivered-to M /trunk/tests/smtpfront-looping-received Fixed up handling of cases where ${PROTO}LOCALHOST or ${PROTO}REMOTEHOST is unset; require ${PROTO}LOCALIP and ${PROTO}REMOTEIP to be set. ------------------------------------------------------------------------ r300 | bruce | 2004-03-02 17:52:41 -0600 (Tue, 02 Mar 2004) | 3 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c Fixed the generated Received: headers to always put the local host name in the comment if tcpserver looked it up. ------------------------------------------------------------------------ r299 | bruce | 2004-02-10 14:51:57 -0600 (Tue, 10 Feb 2004) | 3 lines Changed paths: M /trunk/NEWS M /trunk/imapfront-auth.c Explicitly set $MAILDIR in imapfront-auth for Courier-IMAP's imapd. Thanks Bernhard Graf ------------------------------------------------------------------------ r298 | bruce | 2004-02-10 13:14:39 -0600 (Tue, 10 Feb 2004) | 3 lines Changed paths: M /trunk/NEWS M /trunk/cvm-validate.c Fixed a bug in the CVM lookup code that would cause failures if $LOOKUP_SECRET was not set. Thanks Bernhard Graf ------------------------------------------------------------------------ r297 | bruce | 2004-02-10 13:12:43 -0600 (Tue, 10 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.91 ------------------------------------------------------------------------ r296 | bruce | 2004-02-09 16:13:58 -0600 (Mon, 09 Feb 2004) | 1 line Changed paths: A /tags/0.90 (from /trunk:295) Tagged version 0.90 ------------------------------------------------------------------------ r295 | bruce | 2004-02-09 16:08:24 -0600 (Mon, 09 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c M /trunk/mailrules.html D /trunk/mailrules2.html A /trunk/tests/rules-negate Added support for negation of rule patterns. ------------------------------------------------------------------------ r294 | bruce | 2004-02-09 15:38:54 -0600 (Mon, 09 Feb 2004) | 2 lines Changed paths: M /trunk/tests/pop3front-auth M /trunk/tests/smtpgreeting M /trunk/tests.inc Use explicit paths when running programs. ------------------------------------------------------------------------ r293 | bruce | 2004-02-09 14:49:00 -0600 (Mon, 09 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c M /trunk/mailrules.html M /trunk/mailrules2.html A /trunk/tests/rules-selector Added support for explicit sender/recipient selection. ------------------------------------------------------------------------ r292 | bruce | 2004-02-09 13:49:06 -0600 (Mon, 09 Feb 2004) | 2 lines Changed paths: A /trunk/mailrules2.html Checked in interim mailrules v2 documentation. ------------------------------------------------------------------------ r291 | bruce | 2004-02-09 12:30:51 -0600 (Mon, 09 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/patterns.c M /trunk/tests/patterns-normal Fixed a bug in handling patterns that are not after a blank line. ------------------------------------------------------------------------ r290 | bruce | 2004-02-09 12:30:04 -0600 (Mon, 09 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.90 ------------------------------------------------------------------------ r289 | bruce | 2004-02-07 15:01:55 -0600 (Sat, 07 Feb 2004) | 1 line Changed paths: A /tags/0.89 (from /trunk:288) Tagged version 0.89 ------------------------------------------------------------------------ r288 | bruce | 2004-02-07 14:54:22 -0600 (Sat, 07 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/qmail-backend.c M /trunk/qmail-backend.html M /trunk/qmail-validate.c Allow overriding the qmail home directory with $QMAILHOME. ------------------------------------------------------------------------ r287 | bruce | 2004-02-07 14:48:55 -0600 (Sat, 07 Feb 2004) | 2 lines Changed paths: M /trunk/README.in Bumped up the copyright year. ------------------------------------------------------------------------ r286 | bruce | 2004-02-07 14:47:38 -0600 (Sat, 07 Feb 2004) | 2 lines Changed paths: M /trunk/qmail-backend.c Block SIGPIPE from killing the front-end if qmail-queue dies. ------------------------------------------------------------------------ r285 | bruce | 2004-02-06 14:05:08 -0600 (Fri, 06 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/smtpfront.html A /trunk/tests/smtpfront-maxnotimpl Drop connections after $MAXNOTIMPL unimplemented commands are given. ------------------------------------------------------------------------ r284 | bruce | 2004-02-06 12:40:28 -0600 (Fri, 06 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.89, fixing up the NEWS file. ------------------------------------------------------------------------ r283 | bruce | 2004-02-06 12:40:01 -0600 (Fri, 06 Feb 2004) | 1 line Changed paths: M /trunk/TODO ------------------------------------------------------------------------ r282 | bruce | 2004-02-06 12:27:58 -0600 (Fri, 06 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c M /trunk/mailrules.html A /trunk/tests/rules-noop Added a new "no-op" mail rule type. ------------------------------------------------------------------------ r281 | bruce | 2004-02-06 12:20:31 -0600 (Fri, 06 Feb 2004) | 2 lines Changed paths: M /trunk/mailrules.c Make namelen a pre-initialized constant. ------------------------------------------------------------------------ r280 | bruce | 2004-02-06 12:18:19 -0600 (Fri, 06 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.h A /trunk/patterns.c A /trunk/patterns.html M /trunk/qmqp=l M /trunk/qmtp=l M /trunk/smtp=l M /trunk/smtpfront.html M /trunk/std-handle.c A /trunk/tests/patterns-after A /trunk/tests/patterns-message A /trunk/tests/patterns-normal Added support for content pattern rejection. ------------------------------------------------------------------------ r279 | bruce | 2004-02-05 17:33:58 -0600 (Thu, 05 Feb 2004) | 2 lines Changed paths: M /trunk/std-handle.c Pre-initialize the value of maxdatabytes so SMTP can report it. ------------------------------------------------------------------------ r278 | bruce | 2004-02-05 17:28:55 -0600 (Thu, 05 Feb 2004) | 2 lines Changed paths: M /trunk/mailrules.c Fixed one (last?) bug in rules_getenvu. ------------------------------------------------------------------------ r277 | bruce | 2004-02-05 17:14:49 -0600 (Thu, 05 Feb 2004) | 3 lines Changed paths: M /trunk/std-handle.c Skip character-by-character processing of data bytes after the last header byte is processed. ------------------------------------------------------------------------ r276 | bruce | 2004-02-05 17:04:21 -0600 (Thu, 05 Feb 2004) | 3 lines Changed paths: M /trunk/std-handle.c Don't bother incrementing the line position if it's already past any possible useful values. ------------------------------------------------------------------------ r275 | bruce | 2004-02-05 15:33:51 -0600 (Thu, 05 Feb 2004) | 4 lines Changed paths: M /trunk/mailrules.c Fixed two bugs in the new rules_getenvu function: 1. missing external environment variables caused a seg fault 2. external environment variable values were ignored ------------------------------------------------------------------------ r274 | bruce | 2004-02-05 13:11:36 -0600 (Thu, 05 Feb 2004) | 3 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c Defer looking up $RELAYCLIENT and $MAXRCPTS so they can be set in mail rules; use the new rules_getenvu to look up $MAXHOPS. ------------------------------------------------------------------------ r273 | bruce | 2004-02-05 11:54:09 -0600 (Thu, 05 Feb 2004) | 3 lines Changed paths: M /trunk/mailrules.c M /trunk/mailrules.h M /trunk/std-handle.c Handle the databytes rules column by setting an internal environment variable. ------------------------------------------------------------------------ r272 | bruce | 2004-01-27 12:58:39 -0600 (Tue, 27 Jan 2004) | 2 lines Changed paths: M /trunk/smtpfront.html Fixed minor typo in description of databytes handling. ------------------------------------------------------------------------ r271 | bruce | 2004-01-05 23:08:42 -0600 (Mon, 05 Jan 2004) | 2 lines Changed paths: M /trunk/README.in Updated documentation to make note of seperation between cvm and bglibs. ------------------------------------------------------------------------ r270 | bruce | 2003-12-01 15:43:59 -0600 (Mon, 01 Dec 2003) | 1 line Changed paths: A /tags/0.88 (from /trunk:269) Tagged version 0.88 ------------------------------------------------------------------------ r269 | bruce | 2003-12-01 14:28:40 -0600 (Mon, 01 Dec 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO M /trunk/sasl-auth.c Export CVM data after authentication. ------------------------------------------------------------------------ r268 | bruce | 2003-12-01 13:38:52 -0600 (Mon, 01 Dec 2003) | 2 lines Changed paths: M /trunk/spec Depend on the latest version of bglibs. ------------------------------------------------------------------------ r267 | bruce | 2003-11-27 14:52:32 -0600 (Thu, 27 Nov 2003) | 2 lines Changed paths: M /trunk/TODO Fixed RFC numbers for enhanced status codes. ------------------------------------------------------------------------ r266 | bruce | 2003-11-27 14:52:15 -0600 (Thu, 27 Nov 2003) | 2 lines Changed paths: A /trunk/tests/imapfront-auth-login A /trunk/tests/imapfront-auth-plain Added tests for imapfront-auth AUTHENTICATE command. ------------------------------------------------------------------------ r265 | bruce | 2003-11-27 14:31:43 -0600 (Thu, 27 Nov 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/imapfront-auth.c A /trunk/tests/imapfront-auth M /trunk/tests.inc Added support for IMAP string literals, and tests for imapfront-auth. ------------------------------------------------------------------------ r264 | bruce | 2003-11-26 17:00:52 -0600 (Wed, 26 Nov 2003) | 2 lines Changed paths: M /trunk/mailrules.html Fixed documentation on syntax of setting environment variables in rules. ------------------------------------------------------------------------ r263 | bruce | 2003-11-20 15:47:46 -0600 (Thu, 20 Nov 2003) | 2 lines Changed paths: M /trunk/spec Fixed typo: building depends on cvm-devel, not cvm. ------------------------------------------------------------------------ r262 | bruce | 2003-11-20 15:33:41 -0600 (Thu, 20 Nov 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c A /trunk/tests/rules-header-add A /trunk/tests/rules-maxhops Defer looking up $MAXHOPS and $HEADER_ADD and use rules_getenv instead. ------------------------------------------------------------------------ r261 | bruce | 2003-11-17 22:21:01 -0600 (Mon, 17 Nov 2003) | 2 lines Changed paths: M /trunk/spec Added dependancy notes regarding bglibs and cvm libraries. ------------------------------------------------------------------------ r260 | bruce | 2003-11-17 22:13:03 -0600 (Mon, 17 Nov 2003) | 2 lines Changed paths: M /trunk/std-handle.c Make rcpt_count unsigned, to match the values its compared against. ------------------------------------------------------------------------ r259 | bruce | 2003-11-17 22:12:07 -0600 (Mon, 17 Nov 2003) | 2 lines Changed paths: M /trunk/sasl-auth.c M /trunk/sasl-stub.c Fixup the include path for recent cvm libraries. ------------------------------------------------------------------------ r258 | bruce | 2003-11-17 21:07:40 -0600 (Mon, 17 Nov 2003) | 2 lines Changed paths: M /trunk/README.in M /trunk/makedist.py Converted lists.em.ca to lists.untroubled.org ------------------------------------------------------------------------ r257 | bruce | 2003-11-08 15:13:37 -0600 (Sat, 08 Nov 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtpfront.html M /trunk/std-handle.c Added MAXRCPTS patch from Marcelo Augusto . ------------------------------------------------------------------------ r256 | bruce | 2003-09-15 12:12:36 -0600 (Mon, 15 Sep 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c M /trunk/tests/rules-cdb M /trunk/tests/rules-list Fixed handling of "@domain" entries in mailrules lists and CDB files. ------------------------------------------------------------------------ r255 | bruce | 2003-09-15 11:42:15 -0600 (Mon, 15 Sep 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.88 ------------------------------------------------------------------------ r254 | bruce | 2003-08-28 15:52:15 -0600 (Thu, 28 Aug 2003) | 2 lines Changed paths: M /trunk/tests.inc Removed testing echo hook. ------------------------------------------------------------------------ r253 | bruce | 2003-08-28 15:50:49 -0600 (Thu, 28 Aug 2003) | 1 line Changed paths: A /tags/0.87 (from /trunk:252) Tagged version 0.87 ------------------------------------------------------------------------ r252 | bruce | 2003-08-28 14:04:30 -0600 (Thu, 28 Aug 2003) | 2 lines Changed paths: D /trunk/mailrules2.html A /trunk/mailrulesx.html (from /trunk/mailrules2.html:251) Renamed mailrules v2 to vX, as there may be an intermediate v2 step. ------------------------------------------------------------------------ r251 | bruce | 2003-08-27 18:09:22 -0600 (Wed, 27 Aug 2003) | 2 lines Changed paths: A /trunk/mailrules2.html Rewrote the mailrules v2 documentation to use a compiled file format. ------------------------------------------------------------------------ r250 | bruce | 2003-08-27 17:17:10 -0600 (Wed, 27 Aug 2003) | 2 lines Changed paths: M /trunk/tests/pop3front-auth-login M /trunk/tests/pop3front-auth-plain M /trunk/tests/pop3front-auth-userpass M /trunk/tests/smtpfront-auth-login M /trunk/tests/smtpfront-auth-plain M /trunk/tests.inc Use a locally generated CVM for testing. ------------------------------------------------------------------------ r249 | bruce | 2003-08-27 16:26:03 -0600 (Wed, 27 Aug 2003) | 2 lines Changed paths: M /trunk/tests/smtpfront-bad-bounce M /trunk/tests/smtpfront-content M /trunk/tests/smtpfront-looping-delivered-to M /trunk/tests/smtpfront-looping-received M /trunk/tests.inc Really fixed the sizes, forgot to export the new variables. ------------------------------------------------------------------------ r248 | bruce | 2003-08-27 14:59:44 -0600 (Wed, 27 Aug 2003) | 2 lines Changed paths: M /trunk/tests/smtpfront-bad-bounce M /trunk/tests/smtpfront-content M /trunk/tests/smtpfront-looping-delivered-to M /trunk/tests/smtpfront-looping-received M /trunk/tests.inc Adjusted tests for new link protocol handling. ------------------------------------------------------------------------ r247 | bruce | 2003-08-26 17:51:50 -0600 (Tue, 26 Aug 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c Added the link protocol (ie TCP or TCP6) to the Received: header. ------------------------------------------------------------------------ r246 | bruce | 2003-08-26 16:50:03 -0600 (Tue, 26 Aug 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c Fixed the Received: header generation to match the syntax described in RFC 2821. ------------------------------------------------------------------------ r245 | bruce | 2003-07-17 13:50:15 -0600 (Thu, 17 Jul 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c A /trunk/tests/smtpfront-looping-delivered-to A /trunk/tests/smtpfront-looping-received Fixed a bug that prevented looping email detection from working. ------------------------------------------------------------------------ r244 | bruce | 2003-07-17 13:05:19 -0600 (Thu, 17 Jul 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.87 ------------------------------------------------------------------------ r243 | bruce | 2003-05-28 14:56:18 -0600 (Wed, 28 May 2003) | 1 line Changed paths: A /tags/0.86 (from /trunk:242) Tagged version 0.86 ------------------------------------------------------------------------ r242 | bruce | 2003-05-28 14:51:04 -0600 (Wed, 28 May 2003) | 2 lines Changed paths: M /trunk/TODO Added notes about address handling reorganization. ------------------------------------------------------------------------ r241 | bruce | 2003-05-28 14:48:10 -0600 (Wed, 28 May 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtp-commands.c M /trunk/smtpfront.html A /trunk/tests/smtpfront-databytes Added support for RFC 1870 ESMTP SIZE extension. ------------------------------------------------------------------------ r240 | bruce | 2003-05-28 14:05:25 -0600 (Wed, 28 May 2003) | 2 lines Changed paths: M /trunk/NEWS A /trunk/cvm-validate.c M /trunk/mailfront.h M /trunk/qmail-validate.c M /trunk/qmqpfront-qmail=x M /trunk/qmtpfront-qmail=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront.html Added CVM validation of recipient addresses. ------------------------------------------------------------------------ r239 | bruce | 2003-05-27 13:20:19 -0600 (Tue, 27 May 2003) | 2 lines Changed paths: M /trunk/README.in Added note about Subversion repository. ------------------------------------------------------------------------ r238 | bruce | 2003-05-27 13:19:15 -0600 (Tue, 27 May 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtp-commands.c Make SMTP front end log invalid commands. ------------------------------------------------------------------------ r237 | bruce | 2003-05-27 12:52:36 -0600 (Tue, 27 May 2003) | 2 lines Changed paths: M /trunk/qmtp-respond.c M /trunk/qmtp.h Moved the internal respond_* functions to static. ------------------------------------------------------------------------ r236 | bruce | 2003-05-22 22:51:18 -0600 (Thu, 22 May 2003) | 3 lines Changed paths: M /trunk/qmail-backend.c M /trunk/smtp-respond.c Restore former behavior of only logging errors (and qmail message acceptance data). ------------------------------------------------------------------------ r235 | bruce | 2003-05-22 22:39:12 -0600 (Thu, 22 May 2003) | 3 lines Changed paths: M /trunk/qmail-backend.c No longer need to log message delivery status, as the front-end code logs all responses. ------------------------------------------------------------------------ r234 | bruce | 2003-05-22 22:34:51 -0600 (Thu, 22 May 2003) | 2 lines Changed paths: M /trunk/smtp-respond.c M /trunk/smtp.h Restored the previously deleted logging messages. ------------------------------------------------------------------------ r233 | bruce | 2003-04-30 18:09:16 -0600 (Wed, 30 Apr 2003) | 3 lines Changed paths: M /trunk/README.in Added (tweaked) documentation additions from "Bryan Curnutt" ------------------------------------------------------------------------ r232 | bruce | 2003-03-24 14:35:51 -0600 (Mon, 24 Mar 2003) | 2 lines Changed paths: M /trunk/NEWS Added missing NEWS line item about $HEADER_ADD. ------------------------------------------------------------------------ r231 | bruce | 2003-03-24 14:35:02 -0600 (Mon, 24 Mar 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bump up version number. ------------------------------------------------------------------------ r230 | bruce | 2003-03-24 14:34:21 -0600 (Mon, 24 Mar 2003) | 2 lines Changed paths: M /trunk/smtpfront.html M /trunk/std-handle.c Allow for addition of user specified headers with $HEADER_ADD ------------------------------------------------------------------------ r229 | bruce | 2003-03-24 14:23:07 -0600 (Mon, 24 Mar 2003) | 2 lines Changed paths: M /trunk/smtp-respond.c Move the \n handling into the primary respond function. ------------------------------------------------------------------------ r228 | bruce | 2003-03-24 14:17:29 -0600 (Mon, 24 Mar 2003) | 3 lines Changed paths: M /trunk/echo-backend.c M /trunk/mailrules.c M /trunk/qmail-backend.c M /trunk/qmail-validate.c M /trunk/qmqp-mainloop.c M /trunk/qmtp-mainloop.c M /trunk/qmtp-respond.c M /trunk/responses.c M /trunk/responses.h M /trunk/smtp-commands.c M /trunk/smtp-respond.c M /trunk/smtpfront-reject.c Instead of using (inconvenient) pointers to link multi-line messages, just treat '\n' as a separator within the message itself. ------------------------------------------------------------------------ r227 | bruce | 2003-03-06 11:58:02 -0600 (Thu, 06 Mar 2003) | 2 lines Changed paths: M /trunk/README.in Added note about QMQP and QMTP front-ends. ------------------------------------------------------------------------ r226 | bruce | 2003-03-05 17:28:29 -0600 (Wed, 05 Mar 2003) | 1 line Changed paths: A /tags/0.85 (from /trunk:225) Tagged version 0.85 ------------------------------------------------------------------------ r225 | bruce | 2003-03-05 17:05:05 -0600 (Wed, 05 Mar 2003) | 2 lines Changed paths: M /trunk/TODO Added some things to do. ------------------------------------------------------------------------ r224 | bruce | 2003-03-05 14:57:18 -0600 (Wed, 05 Mar 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtpfront.html Documented the fixup header. ------------------------------------------------------------------------ r223 | bruce | 2003-03-05 14:38:08 -0600 (Wed, 05 Mar 2003) | 2 lines Changed paths: M /trunk/qmtp-respond.c If multiple responses are give, separate them with LF chars. ------------------------------------------------------------------------ r222 | bruce | 2003-03-05 14:36:53 -0600 (Wed, 05 Mar 2003) | 4 lines Changed paths: M /trunk/qmqp=l M /trunk/qmtp=l M /trunk/smtp=l M /trunk/std-handle.c Added code to add a second "Received:" header before the normal one that can be used to fix up mismatches between incoming and outgoing hostnames or IPs. ------------------------------------------------------------------------ r221 | bruce | 2003-03-05 14:34:11 -0600 (Wed, 05 Mar 2003) | 2 lines Changed paths: M /trunk/responses.c M /trunk/responses.h Remove the unused response, and add a OOM one. ------------------------------------------------------------------------ r220 | bruce | 2003-03-05 14:32:55 -0600 (Wed, 05 Mar 2003) | 2 lines Changed paths: M /trunk/README.in Fix up the copyright years. ------------------------------------------------------------------------ r219 | bruce | 2003-03-04 11:33:59 -0600 (Tue, 04 Mar 2003) | 2 lines Changed paths: A /trunk/tests/smtpfront-content Test to make sure escaping on SMTP is handled correctly. ------------------------------------------------------------------------ r218 | bruce | 2003-03-04 11:33:38 -0600 (Tue, 04 Mar 2003) | 2 lines Changed paths: M /trunk/echo-backend.c Properly reset the number of bytes received. ------------------------------------------------------------------------ r217 | bruce | 2003-03-04 11:01:42 -0600 (Tue, 04 Mar 2003) | 2 lines Changed paths: M /trunk/smtp-commands.c Fixed broken leading period handling. ------------------------------------------------------------------------ r216 | bruce | 2003-03-04 01:01:59 -0600 (Tue, 04 Mar 2003) | 2 lines Changed paths: M /trunk/std-handle.c The second line uses two spaces, for continuity with qmail. ------------------------------------------------------------------------ r215 | bruce | 2003-03-04 00:55:23 -0600 (Tue, 04 Mar 2003) | 2 lines Changed paths: M /trunk/insthier.c Install the new QMQP and QMTP programs. ------------------------------------------------------------------------ r214 | bruce | 2003-03-03 17:49:14 -0600 (Mon, 03 Mar 2003) | 2 lines Changed paths: M /trunk/std-handle.c Use str_cat#s functions to shrink code size. ------------------------------------------------------------------------ r213 | bruce | 2003-03-03 17:42:29 -0600 (Mon, 03 Mar 2003) | 4 lines Changed paths: M /trunk/std-handle.c Set up {local,remote}_{host,ip} at init time, instead of when building the Received: header; modularize building the date string into a seperate function. ------------------------------------------------------------------------ r212 | bruce | 2003-03-03 17:34:42 -0600 (Mon, 03 Mar 2003) | 2 lines Changed paths: M /trunk/smtp-commands.c Removed extraneous reset that was blowing away SMTP response messages. ------------------------------------------------------------------------ r211 | bruce | 2003-03-03 16:51:13 -0600 (Mon, 03 Mar 2003) | 2 lines Changed paths: M /trunk/qmtpfront-qmail.c Fixed typo: program name is qmtpfront-qmail, not smtpfront-qmail ------------------------------------------------------------------------ r210 | bruce | 2003-03-03 16:50:16 -0600 (Mon, 03 Mar 2003) | 2 lines Changed paths: M /trunk/NEWS A /trunk/qmqp-mainloop.c A /trunk/qmqp=l A /trunk/qmqpfront-qmail.c A /trunk/qmqpfront-qmail=x Added QMQP front-end with qmail back-end. ------------------------------------------------------------------------ r209 | bruce | 2003-03-03 16:47:08 -0600 (Mon, 03 Mar 2003) | 2 lines Changed paths: M /trunk/qmtp-mainloop.c Log the sender and recipient addresses. ------------------------------------------------------------------------ r208 | bruce | 2003-03-03 16:45:38 -0600 (Mon, 03 Mar 2003) | 2 lines Changed paths: M /trunk/mailfront.h A /trunk/netstring.c M /trunk/qmtp-mainloop.c M /trunk/qmtp=l Moved the netstring reading code into a separate object. ------------------------------------------------------------------------ r207 | bruce | 2003-03-03 16:10:48 -0600 (Mon, 03 Mar 2003) | 2 lines Changed paths: M /trunk/imapfront-auth=x M /trunk/pop3front-auth=x M /trunk/pop3front-maildir=x M /trunk/qmtpfront-qmail=x M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject=x M /trunk/spec Switched to new (revised) bglibs library scheme. ------------------------------------------------------------------------ r206 | bruce | 2003-02-18 18:03:40 -0600 (Tue, 18 Feb 2003) | 1 line Changed paths: M /trunk/NEWS ------------------------------------------------------------------------ r205 | bruce | 2002-12-18 16:06:41 -0600 (Wed, 18 Dec 2002) | 2 lines Changed paths: M /trunk/std-handle.c Reject the message outright if more than one recipient was given. ------------------------------------------------------------------------ r204 | bruce | 2002-12-18 14:17:32 -0600 (Wed, 18 Dec 2002) | 2 lines Changed paths: M /trunk/NEWS Added comment about new bglibs usage. ------------------------------------------------------------------------ r203 | bruce | 2002-12-17 17:09:38 -0600 (Tue, 17 Dec 2002) | 2 lines Changed paths: M /trunk/imapfront-auth=x M /trunk/pop3front-auth=x M /trunk/pop3front-maildir=x M /trunk/qmtpfront-qmail=x M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject=x Switched to new bglibs library paths. ------------------------------------------------------------------------ r202 | bruce | 2002-12-17 17:08:51 -0600 (Tue, 17 Dec 2002) | 2 lines Changed paths: M /trunk/README.in Added installation notes. ------------------------------------------------------------------------ r201 | bruce | 2002-12-16 17:49:47 -0600 (Mon, 16 Dec 2002) | 2 lines Changed paths: M /trunk/imapfront-auth.c M /trunk/mailrules.c M /trunk/pop3front-maildir.c M /trunk/qmail-backend.c M /trunk/qmtp-mainloop.c M /trunk/qmtp-respond.c M /trunk/sasl-auth.c M /trunk/sasl-auth.h M /trunk/smtp-respond.c M /trunk/std-handle.c Renamed variables to eliminate global/local shadow declarations. ------------------------------------------------------------------------ r200 | bruce | 2002-12-16 17:27:34 -0600 (Mon, 16 Dec 2002) | 2 lines Changed paths: D /trunk/README A /trunk/README.in (from /trunk/README:196) Moved to a templated README system, generated by spac-dist. ------------------------------------------------------------------------ r199 | bruce | 2002-12-16 17:26:50 -0600 (Mon, 16 Dec 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version from 0.82 to 0.85 (0.82 was not released). ------------------------------------------------------------------------ r198 | bruce | 2002-12-16 17:07:29 -0600 (Mon, 16 Dec 2002) | 2 lines Changed paths: D /trunk/README.CVS Removed extraneous CVS instructions. ------------------------------------------------------------------------ r197 | bruce | 2002-11-29 15:19:08 -0600 (Fri, 29 Nov 2002) | 2 lines Changed paths: M /trunk/std-handle.c Clarified the logic of handle_sender and handle_recipient. ------------------------------------------------------------------------ r196 | bruce | 2002-11-19 17:21:55 -0600 (Tue, 19 Nov 2002) | 1 line Changed paths: A /branches Created branches directory ------------------------------------------------------------------------ r195 | bruce | 2002-11-19 17:21:55 -0600 (Tue, 19 Nov 2002) | 1 line Changed paths: A /tags Created tags directory ------------------------------------------------------------------------ r194 | bruce | 2002-11-08 23:36:03 -0600 (Fri, 08 Nov 2002) | 4 lines Changed paths: M /trunk/echo-backend.c M /trunk/mailfront.h M /trunk/qmail-backend.c M /trunk/qmail-validate.c D /trunk/qmail.h M /trunk/qmtpfront-qmail.c M /trunk/smtpfront-qmail.c M /trunk/smtpfront-reject.c M /trunk/std-handle.c Renamed the qmail_ functions to standard backend_ naming. Removed the qmail.h header file. Added a call to backend_validate_init to std-handle.c. ------------------------------------------------------------------------ r193 | bruce | 2002-11-08 23:20:28 -0600 (Fri, 08 Nov 2002) | 2 lines Changed paths: M /trunk/qmtpfront-qmail.c M /trunk/smtpfront-qmail.c Removed duplicate relayclient and authenticated handling. ------------------------------------------------------------------------ r192 | bruce | 2002-11-08 23:03:40 -0600 (Fri, 08 Nov 2002) | 2 lines Changed paths: M /trunk/std-handle.c Fixed typo with maxdatabytes. ------------------------------------------------------------------------ r191 | bruce | 2002-11-08 23:03:22 -0600 (Fri, 08 Nov 2002) | 2 lines Changed paths: A /trunk/qmtpfront-qmail.c A /trunk/qmtpfront-qmail=x Added QMTP-qmail main routine. ------------------------------------------------------------------------ r190 | bruce | 2002-11-08 22:53:54 -0600 (Fri, 08 Nov 2002) | 5 lines Changed paths: M /trunk/echo-backend.c M /trunk/mailfront.h M /trunk/qmtp-mainloop.c M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/smtpfront-qmail.c M /trunk/smtpfront-reject.c M /trunk/std-handle.c Renamed handle and validate functions: handle_* => backend_handle_* validate_* => backend_validate_* std_handle_* => handle_* ------------------------------------------------------------------------ r189 | bruce | 2002-11-08 22:36:01 -0600 (Fri, 08 Nov 2002) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/smtp.h M /trunk/smtp=l Removed the duplicated code in std-handle.c ------------------------------------------------------------------------ r188 | bruce | 2002-11-08 22:35:35 -0600 (Fri, 08 Nov 2002) | 3 lines Changed paths: A /trunk/std-handle.c Pulled a lot of common code from the SMTP library into this shared module. ------------------------------------------------------------------------ r187 | bruce | 2002-11-08 22:34:33 -0600 (Fri, 08 Nov 2002) | 2 lines Changed paths: M /trunk/NEWS A /trunk/qmtp-mainloop.c A /trunk/qmtp-respond.c A /trunk/qmtp.h A /trunk/qmtp=l Added a QMTP back-end. ------------------------------------------------------------------------ r186 | bruce | 2002-11-07 19:42:05 -0600 (Thu, 07 Nov 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtp-commands.c Fixed internal variable transposition bug. ------------------------------------------------------------------------ r185 | bruce | 2002-11-07 19:41:51 -0600 (Thu, 07 Nov 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped up version. ------------------------------------------------------------------------ r184 | bruce | 2002-09-27 23:41:02 -0600 (Fri, 27 Sep 2002) | 2 lines Changed paths: M /trunk/README M /trunk/VERSION Bumped version to 0.81. ------------------------------------------------------------------------ r183 | bruce | 2002-09-25 17:10:10 -0600 (Wed, 25 Sep 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtp-commands.c Abort the DATA command immediately if the databytes limit is reached. ------------------------------------------------------------------------ r182 | bruce | 2002-09-25 17:08:57 -0600 (Wed, 25 Sep 2002) | 2 lines Changed paths: M /trunk/tests/rules-asterisk Test for "*" pattern matching "". ------------------------------------------------------------------------ r181 | bruce | 2002-09-25 17:00:10 -0600 (Wed, 25 Sep 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c Make the "*" pattern properly match all strings. ------------------------------------------------------------------------ r180 | bruce | 2002-09-25 16:53:02 -0600 (Wed, 25 Sep 2002) | 2 lines Changed paths: M /trunk/smtp-commands.c Remove extraneous reset of mail/rcpt state. ------------------------------------------------------------------------ r179 | bruce | 2002-09-25 16:51:48 -0600 (Wed, 25 Sep 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtp-commands.c Accept bounces after the first one by properly resetting state. ------------------------------------------------------------------------ r178 | bruce | 2002-09-25 16:49:50 -0600 (Wed, 25 Sep 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c Apply maxdatabytes even if $DATABYTES is not set. ------------------------------------------------------------------------ r177 | bruce | 2002-09-24 20:53:06 -0600 (Tue, 24 Sep 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/qmail-backend.c Fixed handling of environment variables in mail rules. ------------------------------------------------------------------------ r176 | bruce | 2002-09-17 19:29:32 -0600 (Tue, 17 Sep 2002) | 4 lines Changed paths: M /trunk/mailrules.c M /trunk/mailrules.h Fix prototype for rules_getenv to return const data. Fix rules_getenv to call getenv if no suitable variable was found. Fix rules_getenv to return the *last* matching result. ------------------------------------------------------------------------ r175 | bruce | 2002-09-13 19:46:30 -0600 (Fri, 13 Sep 2002) | 2 lines Changed paths: M /trunk/tests/rules-defaultmsg Fixed deferred message. ------------------------------------------------------------------------ r174 | bruce | 2002-09-13 19:46:15 -0600 (Fri, 13 Sep 2002) | 2 lines Changed paths: M /trunk/README Bumped up version. ------------------------------------------------------------------------ r173 | bruce | 2002-09-13 04:38:07 -0600 (Fri, 13 Sep 2002) | 2 lines Changed paths: M /trunk/mailrules.html Added some more examples. ------------------------------------------------------------------------ r172 | bruce | 2002-09-13 04:37:33 -0600 (Fri, 13 Sep 2002) | 2 lines Changed paths: M /trunk/mailrules.c Added a default handler. ------------------------------------------------------------------------ r171 | bruce | 2002-09-11 17:31:39 -0600 (Wed, 11 Sep 2002) | 2 lines Changed paths: M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r170 | bruce | 2002-09-11 16:29:27 -0600 (Wed, 11 Sep 2002) | 2 lines Changed paths: M /trunk/mailrules.c M /trunk/mailrules.html M /trunk/tests/rules-cdb M /trunk/tests/rules-defaultmsg M /trunk/tests/rules-list M /trunk/tests/rules-recip M /trunk/tests/rules-sender Fixed z/d semantics to match qmail-remote, QMQP, and QMTP. ------------------------------------------------------------------------ r169 | bruce | 2002-09-11 16:20:08 -0600 (Wed, 11 Sep 2002) | 2 lines Changed paths: M /trunk/mailrules.html Clarified the note on escapes. ------------------------------------------------------------------------ r168 | bruce | 2002-09-11 16:17:12 -0600 (Wed, 11 Sep 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/qmail-validate.c Added support for wildcards in rcpthosts and morercpthosts.cdb. ------------------------------------------------------------------------ r167 | bruce | 2002-08-27 21:13:21 -0600 (Tue, 27 Aug 2002) | 2 lines Changed paths: M /trunk/mailrules.c M /trunk/mailrules.html M /trunk/tests/rules-recip M /trunk/tests/rules-sender Added support for "pass-through" rules. ------------------------------------------------------------------------ r166 | bruce | 2002-08-26 20:28:27 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/mailrules.html Added note that the qmail rules are only an example. ------------------------------------------------------------------------ r165 | bruce | 2002-08-26 20:20:24 -0600 (Mon, 26 Aug 2002) | 3 lines Changed paths: M /trunk/NEWS M /trunk/qmail-validate.c Properly lowercase the sender address before looking it up in badmailfrom. ------------------------------------------------------------------------ r164 | bruce | 2002-08-26 03:35:44 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/README M /trunk/mailrules.html Clarified interpretation of empty or missing columns. ------------------------------------------------------------------------ r163 | bruce | 2002-08-26 03:35:19 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: A /trunk/tests/rules-defaultmsg Test default messages. ------------------------------------------------------------------------ r162 | bruce | 2002-08-26 03:35:08 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/mailrules.c Properly set up different default messages for each type of rule. ------------------------------------------------------------------------ r161 | bruce | 2002-08-26 03:28:45 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/mailrules.c Fixed handling of empty resposes. ------------------------------------------------------------------------ r160 | bruce | 2002-08-26 03:08:27 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/mailrules.html Added note about empty pattern matching. ------------------------------------------------------------------------ r159 | bruce | 2002-08-26 03:07:12 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: A /trunk/tests/rules-empty Added test for empty pattern. ------------------------------------------------------------------------ r158 | bruce | 2002-08-26 03:06:57 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r157 | bruce | 2002-08-26 03:05:35 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/NEWS Added note about mail rules processing and sponsorship. ------------------------------------------------------------------------ r156 | bruce | 2002-08-26 03:04:35 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/VERSION Bumped version. ------------------------------------------------------------------------ r155 | bruce | 2002-08-26 03:04:02 -0600 (Mon, 26 Aug 2002) | 3 lines Changed paths: M /trunk/smtp-commands.c Fixed bounce to multiple recipient logic to properly reject the data command after the condition is discovered. ------------------------------------------------------------------------ r154 | bruce | 2002-08-26 03:03:25 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/smtpfront.html Added note about bounce to multiple recipient handling. ------------------------------------------------------------------------ r153 | bruce | 2002-08-26 02:57:39 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/smtp=l M /trunk/smtpfront-echo=x M /trunk/smtpfront-reject=x Added necessary linkage for mailrules implementation. ------------------------------------------------------------------------ r152 | bruce | 2002-08-26 02:57:17 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: A /trunk/tests/rules-asterisk A /trunk/tests/rules-both A /trunk/tests/rules-cdb A /trunk/tests/rules-list A /trunk/tests/rules-multiline A /trunk/tests/rules-recip A /trunk/tests/rules-sender Added mail rules tests. ------------------------------------------------------------------------ r151 | bruce | 2002-08-26 02:57:12 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: A /trunk/mailrules.c A /trunk/mailrules.html Added mail rules implementation and documentation. ------------------------------------------------------------------------ r150 | bruce | 2002-08-26 02:56:38 -0600 (Mon, 26 Aug 2002) | 3 lines Changed paths: M /trunk/qmail-validate.html M /trunk/smtpfront.html Added notes about new mail rules interface, and the addition of $RELAYCLIENT and authentication handling to all back-ends. ------------------------------------------------------------------------ r149 | bruce | 2002-08-26 02:55:46 -0600 (Mon, 26 Aug 2002) | 4 lines Changed paths: M /trunk/smtp-commands.c Call the mailrules API at the appropriate places. Add $RELAYCLIENT handling here from qmail-validate. Add authenticated handleing here. ------------------------------------------------------------------------ r148 | bruce | 2002-08-25 21:26:30 -0600 (Sun, 25 Aug 2002) | 2 lines Changed paths: M /trunk/qmail-backend.c Use mailrules API to get/export environment variables. ------------------------------------------------------------------------ r147 | bruce | 2002-08-25 21:24:29 -0600 (Sun, 25 Aug 2002) | 3 lines Changed paths: M /trunk/mailrules.h M /trunk/smtp-mainloop.c M /trunk/smtp.h Moved maxdatabytes saving and restoring into mailrules. Added environment API to mailrules. ------------------------------------------------------------------------ r146 | bruce | 2002-08-20 18:12:20 -0600 (Tue, 20 Aug 2002) | 2 lines Changed paths: M /trunk/smtp-mainloop.c Set up relayclient and saved_maxdatabytes, and init mail rules. ------------------------------------------------------------------------ r145 | bruce | 2002-08-20 18:11:46 -0600 (Tue, 20 Aug 2002) | 2 lines Changed paths: A /trunk/mailrules.h Added initial API for mail rules processing. ------------------------------------------------------------------------ r144 | bruce | 2002-08-20 18:10:23 -0600 (Tue, 20 Aug 2002) | 2 lines Changed paths: M /trunk/echo-backend.c M /trunk/mailfront.h M /trunk/smtpfront-qmail.c Add seperate validate_(sender|recipient) routines. ------------------------------------------------------------------------ r143 | bruce | 2002-08-20 18:09:56 -0600 (Tue, 20 Aug 2002) | 3 lines Changed paths: M /trunk/smtpfront-reject.c Add seperate validate_(sender|recipient) routines. Explicitly set relayclient and authenticated to false. ------------------------------------------------------------------------ r142 | bruce | 2002-08-20 18:07:10 -0600 (Tue, 20 Aug 2002) | 2 lines Changed paths: M /trunk/smtp.h Export relayclient and saved_maxdatabytes state. ------------------------------------------------------------------------ r141 | bruce | 2002-08-19 18:24:00 -0600 (Mon, 19 Aug 2002) | 2 lines Changed paths: M /trunk/smtp-commands.c Completed other half of single-recipient-bounce logic. ------------------------------------------------------------------------ r140 | bruce | 2002-08-19 18:22:31 -0600 (Mon, 19 Aug 2002) | 2 lines Changed paths: M /trunk/smtp-commands.c Tweaked single-recipient-bounce logic to apply before any parsing. ------------------------------------------------------------------------ r139 | bruce | 2002-08-13 04:35:57 -0600 (Tue, 13 Aug 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtp-mainloop.c Fixed handling of SMTPGREETING and TCPLOCALHOST. ------------------------------------------------------------------------ r138 | bruce | 2002-08-09 20:07:21 -0600 (Fri, 09 Aug 2002) | 2 lines Changed paths: M /trunk/README M /trunk/VERSION Bumped up version. ------------------------------------------------------------------------ r137 | bruce | 2002-08-08 17:18:45 -0600 (Thu, 08 Aug 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/qmail-validate.c Add wildcard code for badrcptto to smtpfront-qmail. ------------------------------------------------------------------------ r136 | bruce | 2002-07-15 23:58:02 -0600 (Mon, 15 Jul 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/insthier.c Added missing imapfront-auth. ------------------------------------------------------------------------ r135 | bruce | 2002-06-20 18:24:41 -0600 (Thu, 20 Jun 2002) | 2 lines Changed paths: M /trunk/spec Added build requirement for bglibs. ------------------------------------------------------------------------ r134 | bruce | 2002-06-20 16:22:41 -0600 (Thu, 20 Jun 2002) | 2 lines Changed paths: M /trunk/README M /trunk/VERSION Bumped up version number. ------------------------------------------------------------------------ r133 | bruce | 2002-06-20 16:20:27 -0600 (Thu, 20 Jun 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/sasl-auth.c Provide better credential information, as well as logging failures. ------------------------------------------------------------------------ r132 | bruce | 2002-06-18 23:38:50 -0600 (Tue, 18 Jun 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/imapfront-auth=x M /trunk/sasl-auth.c Log SASL authenticated username. ------------------------------------------------------------------------ r131 | bruce | 2002-06-18 21:21:16 -0600 (Tue, 18 Jun 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/imapfront-auth.c Fixed missing "OK" bug in imapfront-auth. ------------------------------------------------------------------------ r130 | bruce | 2002-06-06 18:28:58 -0600 (Thu, 06 Jun 2002) | 2 lines Changed paths: M /trunk/spec Added missing include/library flags. ------------------------------------------------------------------------ r129 | bruce | 2002-06-06 18:25:47 -0600 (Thu, 06 Jun 2002) | 2 lines Changed paths: M /trunk/README M /trunk/VERSION Bumped up version. ------------------------------------------------------------------------ r128 | bruce | 2002-06-06 18:22:32 -0600 (Thu, 06 Jun 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO M /trunk/imapfront-auth=x M /trunk/imapfront.html M /trunk/pop3front-auth=x M /trunk/pop3front-maildir=x M /trunk/pop3front.html M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject=x M /trunk/smtpfront.html M /trunk/timeout.c Added support for a session timeout. ------------------------------------------------------------------------ r127 | bruce | 2002-06-06 18:12:04 -0600 (Thu, 06 Jun 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO M /trunk/smtp-commands.c A /trunk/tests/smtpfront-bad-bounce M /trunk/tests.inc Reject bounces with multiple recipients. ------------------------------------------------------------------------ r126 | bruce | 2002-06-06 17:58:45 -0600 (Thu, 06 Jun 2002) | 2 lines Changed paths: M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r125 | bruce | 2002-06-06 17:47:17 -0600 (Thu, 06 Jun 2002) | 2 lines Changed paths: M /trunk/TODO M /trunk/imapfront-auth.c M /trunk/imapfront-auth=x M /trunk/pop3-mainloop.c M /trunk/pop3=l M /trunk/smtp-mainloop.c M /trunk/smtp=l A /trunk/timeout.c Merged the common timeout code into one place. ------------------------------------------------------------------------ r124 | bruce | 2002-06-06 17:34:54 -0600 (Thu, 06 Jun 2002) | 2 lines Changed paths: M /trunk/TODO Revised pattern matching plan. ------------------------------------------------------------------------ r123 | bruce | 2002-06-04 20:59:49 -0600 (Tue, 04 Jun 2002) | 2 lines Changed paths: M /trunk/imapfront-auth.c M /trunk/imapfront-auth=x M /trunk/insthier.c M /trunk/iobytes.c M /trunk/mailfront.h M /trunk/pop3-mainloop.c M /trunk/pop3-response.c M /trunk/pop3front-auth.c M /trunk/pop3front-auth=x M /trunk/pop3front-maildir.c M /trunk/pop3front-maildir=x M /trunk/qmail-backend.c M /trunk/qmail-validate.c M /trunk/sasl-auth.c M /trunk/sasl-stub.c M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/smtp-respond.c M /trunk/smtp.h M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail.c M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject.c M /trunk/smtpfront-reject=x Switched to using external bglibs. ------------------------------------------------------------------------ r122 | bruce | 2002-06-04 20:41:30 -0600 (Tue, 04 Jun 2002) | 2 lines Changed paths: M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r121 | bruce | 2002-05-07 23:04:48 -0600 (Tue, 07 May 2002) | 2 lines Changed paths: M /trunk/README A /trunk/imapfront.html M /trunk/mailfront.html Added some IMAP documentation. ------------------------------------------------------------------------ r120 | bruce | 2002-05-07 22:23:04 -0600 (Tue, 07 May 2002) | 2 lines Changed paths: M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r119 | bruce | 2002-05-07 21:15:51 -0600 (Tue, 07 May 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r118 | bruce | 2002-05-07 20:28:57 -0600 (Tue, 07 May 2002) | 2 lines Changed paths: M /trunk/imapfront-auth.c Added support for the AUTHENTICATE command. ------------------------------------------------------------------------ r117 | bruce | 2002-05-07 20:28:43 -0600 (Tue, 07 May 2002) | 2 lines Changed paths: M /trunk/pop3front-auth.c M /trunk/sasl-auth.c M /trunk/sasl-auth.h M /trunk/sasl-stub.c M /trunk/smtp-commands.c Updated the SASL interface to allow one or two arguments. ------------------------------------------------------------------------ r116 | bruce | 2002-05-07 19:17:47 -0600 (Tue, 07 May 2002) | 2 lines Changed paths: A /trunk/imapfront-auth.c A /trunk/imapfront-auth=x Added first try at an IMAP authentication front end. ------------------------------------------------------------------------ r115 | bruce | 2002-05-06 20:55:23 -0600 (Mon, 06 May 2002) | 2 lines Changed paths: A /trunk/tests/smtpgreeting Added test for $SMTPGREETING. ------------------------------------------------------------------------ r114 | bruce | 2002-05-06 20:55:16 -0600 (Mon, 06 May 2002) | 2 lines Changed paths: M /trunk/tests.inc Fixed pop3front-auth function. ------------------------------------------------------------------------ r113 | bruce | 2002-05-06 20:54:57 -0600 (Mon, 06 May 2002) | 2 lines Changed paths: M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r112 | bruce | 2002-05-06 20:50:23 -0600 (Mon, 06 May 2002) | 2 lines Changed paths: M /trunk/mailfront.html M /trunk/smtpfront.html Updated documentation. ------------------------------------------------------------------------ r111 | bruce | 2002-05-06 20:49:42 -0600 (Mon, 06 May 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtp-mainloop.c M /trunk/smtp.h M /trunk/smtpfront-echo.c M /trunk/smtpfront-qmail.c M /trunk/smtpfront-reject.c Added support for $SMTPGREETING. ------------------------------------------------------------------------ r110 | bruce | 2002-04-17 20:31:28 -0600 (Wed, 17 Apr 2002) | 3 lines Changed paths: M /trunk/pop3-mainloop.c M /trunk/pop3.h M /trunk/pop3front-auth.c M /trunk/pop3front-maildir.c Allow for "sanitized" versions of some commands to be logged, for example to strip passwords. ------------------------------------------------------------------------ r109 | bruce | 2002-04-17 20:03:43 -0600 (Wed, 17 Apr 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/pop3-mainloop.c M /trunk/pop3-response.c M /trunk/pop3.h Modified pop3front to log all commands, not just errors. ------------------------------------------------------------------------ r108 | bruce | 2002-02-12 22:56:11 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/NEWS Typo. ------------------------------------------------------------------------ r107 | bruce | 2002-02-12 22:41:15 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/README M /trunk/VERSION un-bumped version number. ------------------------------------------------------------------------ r106 | bruce | 2002-02-12 22:23:01 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/README.CVS M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r105 | bruce | 2002-02-12 22:19:22 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/pop3front-auth=x M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x Replace use of "socket" library with the "net" library. ------------------------------------------------------------------------ r104 | bruce | 2002-02-12 21:03:07 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/README M /trunk/VERSION *** empty log message *** ------------------------------------------------------------------------ r103 | bruce | 2002-02-12 21:01:33 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/pop3front-auth.c Log the username. ------------------------------------------------------------------------ r102 | bruce | 2002-02-12 20:11:16 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/qmail-validate.c Fixed one-off bug in badmailfrom handling. ------------------------------------------------------------------------ r101 | bruce | 2002-02-12 20:05:57 -0600 (Tue, 12 Feb 2002) | 3 lines Changed paths: D /trunk/log.c D /trunk/log.h M /trunk/mailfront.h M /trunk/qmail-backend.c M /trunk/smtp-commands.c M /trunk/smtp-respond.c M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject=x Converted smtpfront to use the msg library, and dropped the custom log functions. ------------------------------------------------------------------------ r100 | bruce | 2002-02-12 20:05:26 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/NEWS *** empty log message *** ------------------------------------------------------------------------ r99 | bruce | 2002-02-12 19:58:46 -0600 (Tue, 12 Feb 2002) | 3 lines Changed paths: A /trunk/iobytes.c M /trunk/pop3=l M /trunk/pop3front-maildir.c M /trunk/smtp-mainloop.c M /trunk/smtp=l Moved the I/O byte reporting into a common module, and added the hook to the SMTP front end. ------------------------------------------------------------------------ r98 | bruce | 2002-02-12 19:48:30 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/tests.inc *** empty log message *** ------------------------------------------------------------------------ r97 | bruce | 2002-02-12 19:48:18 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/pop3front-maildir.c Converted to using msg for errors. ------------------------------------------------------------------------ r96 | bruce | 2002-02-12 17:55:42 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r95 | bruce | 2002-02-12 17:55:24 -0600 (Tue, 12 Feb 2002) | 3 lines Changed paths: M /trunk/NEWS M /trunk/pop3front-maildir.c Added an exit hook to pop3front-maildir to print the number of bytes input and output. ------------------------------------------------------------------------ r94 | bruce | 2002-02-06 18:25:49 -0600 (Wed, 06 Feb 2002) | 2 lines Changed paths: M /trunk/tests/pop3front-auth-userpass A /trunk/tests/pop3front-maildir-flags A /trunk/tests/pop3front-maildir-last A /trunk/tests/pop3front-maildir-sort A /trunk/tests/pop3front-maildir-state M /trunk/tests.inc Updated and added tests. ------------------------------------------------------------------------ r93 | bruce | 2002-02-01 17:30:06 -0600 (Fri, 01 Feb 2002) | 2 lines Changed paths: M /trunk/pop3front-maildir.c Use strchr instead of scanning for flags by hand. ------------------------------------------------------------------------ r92 | bruce | 2002-02-01 17:27:38 -0600 (Fri, 01 Feb 2002) | 2 lines Changed paths: M /trunk/NEWS *** empty log message *** ------------------------------------------------------------------------ r91 | bruce | 2002-02-01 17:26:55 -0600 (Fri, 01 Feb 2002) | 2 lines Changed paths: M /trunk/pop3front-maildir.c Implemented the obsolete LAST command. ------------------------------------------------------------------------ r90 | bruce | 2002-02-01 17:07:18 -0600 (Fri, 01 Feb 2002) | 2 lines Changed paths: M /trunk/pop3front-maildir.c Sort the messages in the maildir (by numerical value). ------------------------------------------------------------------------ r89 | bruce | 2002-02-01 04:08:13 -0600 (Fri, 01 Feb 2002) | 2 lines Changed paths: M /trunk/pop3front-maildir.c Scan the messages for a "read" flag. ------------------------------------------------------------------------ r88 | bruce | 2002-02-01 04:01:13 -0600 (Fri, 01 Feb 2002) | 3 lines Changed paths: M /trunk/pop3front-maildir.c Modified the flags handling to properly *add* instead of replacing the flags. ------------------------------------------------------------------------ r87 | bruce | 2002-01-31 18:25:15 -0600 (Thu, 31 Jan 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/pop3front-maildir.c Properly tag read messages on QUIT. ------------------------------------------------------------------------ r86 | bruce | 2002-01-31 18:24:28 -0600 (Thu, 31 Jan 2002) | 2 lines Changed paths: M /trunk/README M /trunk/VERSION Bumped version number. ------------------------------------------------------------------------ r85 | bruce | 2002-01-11 18:54:40 -0600 (Fri, 11 Jan 2002) | 2 lines Changed paths: M /trunk/tests/pop3front-auth M /trunk/tests/pop3front-auth-userpass Fixed extra period. ------------------------------------------------------------------------ r84 | bruce | 2002-01-11 18:54:29 -0600 (Fri, 11 Jan 2002) | 2 lines Changed paths: M /trunk/README Touched date. ------------------------------------------------------------------------ r83 | bruce | 2002-01-11 04:29:35 -0600 (Fri, 11 Jan 2002) | 3 lines Changed paths: M /trunk/pop3-mainloop.c M /trunk/pop3front.html M /trunk/smtp-mainloop.c Added $TIMEOUT handling to the POP3 modules. Minor adjustment to SMTP $TIMEOUT handling. ------------------------------------------------------------------------ r82 | bruce | 2002-01-11 04:28:02 -0600 (Fri, 11 Jan 2002) | 2 lines Changed paths: M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r81 | bruce | 2002-01-09 21:59:26 -0600 (Wed, 09 Jan 2002) | 3 lines Changed paths: M /trunk/NEWS M /trunk/pop3front-maildir.c DELE needed to add deleted messages to the appropriate counters so STAT could account for the difference. ------------------------------------------------------------------------ r80 | bruce | 2001-12-28 00:31:52 -0600 (Fri, 28 Dec 2001) | 2 lines Changed paths: M /trunk/pop3front.html Documented the MAX_CUR/NEW_MESSAGES options. ------------------------------------------------------------------------ r79 | bruce | 2001-12-28 00:25:07 -0600 (Fri, 28 Dec 2001) | 3 lines Changed paths: M /trunk/pop3front-maildir.c Minor optimization: only update the count pointer after the loop is complete. ------------------------------------------------------------------------ r78 | bruce | 2001-12-28 00:23:54 -0600 (Fri, 28 Dec 2001) | 3 lines Changed paths: M /trunk/pop3front-maildir.c Add optional individual count limits on both the cur and new subdirectories. ------------------------------------------------------------------------ r77 | bruce | 2001-12-27 22:32:41 -0600 (Thu, 27 Dec 2001) | 2 lines Changed paths: M /trunk/pop3front-auth=x M /trunk/pop3front-maildir=x Added missing msg/msg.a library. ------------------------------------------------------------------------ r76 | bruce | 2001-12-27 22:32:23 -0600 (Thu, 27 Dec 2001) | 2 lines Changed paths: M /trunk/pop3-response.c Output all error responses to the logs. ------------------------------------------------------------------------ r75 | bruce | 2001-12-24 05:38:59 -0600 (Mon, 24 Dec 2001) | 5 lines Changed paths: M /trunk/pop3front-maildir.c Fixed two message corruption bugs in dump_msg: - periods at the start of a line weren't escaped and - if the line after the last requested line of the body spanned buffers, the first part of it would be written. ------------------------------------------------------------------------ r74 | bruce | 2001-12-23 05:53:24 -0600 (Sun, 23 Dec 2001) | 2 lines Changed paths: M /trunk/pop3-mainloop.c Added timeout option. ------------------------------------------------------------------------ r73 | bruce | 2001-12-23 05:52:52 -0600 (Sun, 23 Dec 2001) | 2 lines Changed paths: M /trunk/pop3front-auth.c Fixed some response strings, added program string. ------------------------------------------------------------------------ r72 | bruce | 2001-12-23 05:52:26 -0600 (Sun, 23 Dec 2001) | 2 lines Changed paths: M /trunk/pop3front-maildir.c Fixed some debug strings, add program string. ------------------------------------------------------------------------ r71 | bruce | 2001-12-17 04:35:01 -0600 (Mon, 17 Dec 2001) | 2 lines Changed paths: A /trunk/COPYING M /trunk/README M /trunk/TODO M /trunk/VERSION *** empty log message *** ------------------------------------------------------------------------ r70 | bruce | 2001-12-17 04:30:55 -0600 (Mon, 17 Dec 2001) | 2 lines Changed paths: A /trunk/spec Added missing spec file. ------------------------------------------------------------------------ r69 | bruce | 2001-11-22 23:13:54 -0600 (Thu, 22 Nov 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/pop3front-maildir.c M /trunk/pop3front.html Added a maximum accessable message count option. ------------------------------------------------------------------------ r68 | bruce | 2001-10-18 23:20:17 -0600 (Thu, 18 Oct 2001) | 2 lines Changed paths: M /trunk/pop3front-maildir=x This module doesn't need CVM, so don't link against it. ------------------------------------------------------------------------ r67 | bruce | 2001-10-18 23:19:57 -0600 (Thu, 18 Oct 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/pop3front-auth=x M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x Added missing socket.lib linker option. ------------------------------------------------------------------------ r66 | bruce | 2001-10-18 23:13:41 -0600 (Thu, 18 Oct 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/README M /trunk/VERSION Bumped up the version number. ------------------------------------------------------------------------ r65 | bruce | 2001-10-17 22:30:12 -0600 (Wed, 17 Oct 2001) | 2 lines Changed paths: M /trunk/insthier.c Added pop3front-* programs. ------------------------------------------------------------------------ r64 | bruce | 2001-09-21 21:35:17 -0600 (Fri, 21 Sep 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r63 | bruce | 2001-09-21 18:33:35 -0600 (Fri, 21 Sep 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/README *** empty log message *** ------------------------------------------------------------------------ r62 | bruce | 2001-09-21 18:32:13 -0600 (Fri, 21 Sep 2001) | 3 lines Changed paths: M /trunk/smtp-commands.c Log the MAIL and RCPT parameters always, not just when they are accepted by handle_sender and handle_recipient. ------------------------------------------------------------------------ r61 | bruce | 2001-09-14 22:32:27 -0600 (Fri, 14 Sep 2001) | 2 lines Changed paths: A /trunk/tests/pop3front-auth M /trunk/tests/smtpfront-auth-plain More testing... ------------------------------------------------------------------------ r60 | bruce | 2001-09-14 21:31:50 -0600 (Fri, 14 Sep 2001) | 2 lines Changed paths: A /trunk/tests A /trunk/tests/pop3front-auth-login A /trunk/tests/pop3front-auth-plain A /trunk/tests/pop3front-auth-userpass A /trunk/tests/smtpfront-auth-login A /trunk/tests/smtpfront-auth-plain A /trunk/tests.inc Added tests of the auth mechanisms. ------------------------------------------------------------------------ r59 | bruce | 2001-09-14 21:31:37 -0600 (Fri, 14 Sep 2001) | 2 lines Changed paths: M /trunk/NEWS *** empty log message *** ------------------------------------------------------------------------ r58 | bruce | 2001-09-14 21:31:30 -0600 (Fri, 14 Sep 2001) | 2 lines Changed paths: M /trunk/sasl-auth.c Abort the authentication if the response string starts with '*'. ------------------------------------------------------------------------ r57 | bruce | 2001-09-14 21:31:06 -0600 (Fri, 14 Sep 2001) | 2 lines Changed paths: M /trunk/sasl-auth.c Properly skip spaces after the mechanism name. ------------------------------------------------------------------------ r56 | bruce | 2001-09-14 21:29:56 -0600 (Fri, 14 Sep 2001) | 3 lines Changed paths: M /trunk/smtp-commands.c Log the sender and recipient addresses. Provide a success response when authentication succeeds. ------------------------------------------------------------------------ r55 | bruce | 2001-09-14 21:29:15 -0600 (Fri, 14 Sep 2001) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/smtp.h Moved several SMTP specific function declarations into smtp.h ------------------------------------------------------------------------ r54 | bruce | 2001-09-14 21:28:49 -0600 (Fri, 14 Sep 2001) | 2 lines Changed paths: M /trunk/smtp-respond.c Use the more efficient putsflush(CRLF) form. ------------------------------------------------------------------------ r53 | bruce | 2001-09-14 05:47:04 -0600 (Fri, 14 Sep 2001) | 2 lines Changed paths: M /trunk/README M /trunk/TODO M /trunk/VERSION *** empty log message *** ------------------------------------------------------------------------ r52 | bruce | 2001-09-14 05:45:26 -0600 (Fri, 14 Sep 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/qmail-validate.c Lowercase domain names before comparing them. ------------------------------------------------------------------------ r51 | bruce | 2001-09-13 00:03:25 -0600 (Thu, 13 Sep 2001) | 2 lines Changed paths: M /trunk/README M /trunk/pop3front-auth=x M /trunk/pop3front-maildir=x A /trunk/pop3front.html M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x *** empty log message *** ------------------------------------------------------------------------ r50 | bruce | 2001-09-09 05:35:20 -0600 (Sun, 09 Sep 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r49 | bruce | 2001-09-09 05:29:22 -0600 (Sun, 09 Sep 2001) | 2 lines Changed paths: M /trunk/pop3front-maildir.c Added support for TOP command. ------------------------------------------------------------------------ r48 | bruce | 2001-09-09 05:29:00 -0600 (Sun, 09 Sep 2001) | 2 lines Changed paths: M /trunk/pop3front-auth.c M /trunk/pop3front-auth=x Added support for the AUTH command. ------------------------------------------------------------------------ r47 | bruce | 2001-09-09 05:28:36 -0600 (Sun, 09 Sep 2001) | 2 lines Changed paths: M /trunk/mailfront.html *** empty log message *** ------------------------------------------------------------------------ r46 | bruce | 2001-09-09 05:28:21 -0600 (Sun, 09 Sep 2001) | 2 lines Changed paths: A /trunk/sasl-auth.c A /trunk/sasl-auth.h A /trunk/sasl-stub.c D /trunk/smtp-auth-stub.c D /trunk/smtp-auth.c M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/smtp.h M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject=x Moved the SMTP specific SASL AUTH code to a new more generic module. ------------------------------------------------------------------------ r45 | bruce | 2001-09-09 05:26:07 -0600 (Sun, 09 Sep 2001) | 2 lines Changed paths: M /trunk/pop3-response.c Use new CRLF constant. ------------------------------------------------------------------------ r44 | bruce | 2001-09-09 05:25:17 -0600 (Sun, 09 Sep 2001) | 2 lines Changed paths: A /trunk/constants.h M /trunk/mailfront.h M /trunk/pop3.h M /trunk/smtp.h Moved a bunch of the character constants into a seperate module. ------------------------------------------------------------------------ r43 | bruce | 2001-09-07 18:13:51 -0600 (Fri, 07 Sep 2001) | 2 lines Changed paths: M /trunk/NEWS *** empty log message *** ------------------------------------------------------------------------ r42 | bruce | 2001-09-07 06:41:57 -0600 (Fri, 07 Sep 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/README M /trunk/TODO A /trunk/VERSION *** empty log message *** ------------------------------------------------------------------------ r41 | bruce | 2001-09-07 06:40:17 -0600 (Fri, 07 Sep 2001) | 2 lines Changed paths: M /trunk/smtp-auth.c Revised to use new cvm-sasl structure. ------------------------------------------------------------------------ r40 | bruce | 2001-09-07 06:39:44 -0600 (Fri, 07 Sep 2001) | 2 lines Changed paths: M /trunk/smtp-mainloop.c Use ibuf_getstr_crlf in favour of smtp_get_line. ------------------------------------------------------------------------ r39 | bruce | 2001-09-07 06:39:26 -0600 (Fri, 07 Sep 2001) | 3 lines Changed paths: M /trunk/smtp.h Redefined the character macros to add type. Use the new ibuf_getstr_crlf function. ------------------------------------------------------------------------ r38 | bruce | 2001-09-07 06:34:32 -0600 (Fri, 07 Sep 2001) | 2 lines Changed paths: A /trunk/pop3=l *** empty log message *** ------------------------------------------------------------------------ r37 | bruce | 2001-09-07 06:34:11 -0600 (Fri, 07 Sep 2001) | 2 lines Changed paths: A /trunk/pop3-mainloop.c A /trunk/pop3-response.c A /trunk/pop3.h A /trunk/pop3front-auth.c A /trunk/pop3front-auth=x A /trunk/pop3front-maildir.c A /trunk/pop3front-maildir=x Added a new POP3 server pair. ------------------------------------------------------------------------ r36 | bruce | 2001-08-24 20:53:06 -0600 (Fri, 24 Aug 2001) | 2 lines Changed paths: M /trunk/smtpfront.html Added (temporary) link for cvm-sasl.html. ------------------------------------------------------------------------ r35 | bruce | 2001-08-24 20:37:13 -0600 (Fri, 24 Aug 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/README M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r34 | bruce | 2001-08-24 20:34:12 -0600 (Fri, 24 Aug 2001) | 2 lines Changed paths: M /trunk/smtpfront.html Noted use of SMTP AUTH. ------------------------------------------------------------------------ r33 | bruce | 2001-08-10 22:05:38 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r32 | bruce | 2001-08-10 20:05:57 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: M /trunk/smtp-respond.c Renamed NL to LF. ------------------------------------------------------------------------ r31 | bruce | 2001-08-10 20:05:43 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: M /trunk/README.CVS M /trunk/TODO M /trunk/mailfront.html *** empty log message *** ------------------------------------------------------------------------ r30 | bruce | 2001-08-10 20:05:26 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: M /trunk/mailfront.h Added an "authenticated" state variable. ------------------------------------------------------------------------ r29 | bruce | 2001-08-10 20:02:44 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: M /trunk/smtpfront-qmail.c Allow authenticated sessions to relay. ------------------------------------------------------------------------ r28 | bruce | 2001-08-10 20:02:08 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/smtp.h Added hooks for SMTP AUTH. ------------------------------------------------------------------------ r27 | bruce | 2001-08-10 20:01:55 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x Link against the full SMTP AUTH implementation. ------------------------------------------------------------------------ r26 | bruce | 2001-08-10 20:01:38 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: M /trunk/smtpfront-reject=x Link against the SMTP AUTH stubs. ------------------------------------------------------------------------ r25 | bruce | 2001-08-10 20:01:11 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: A /trunk/smtp-auth-stub.c First check-in of the dummy SMTP AUTH stub functions. ------------------------------------------------------------------------ r24 | bruce | 2001-08-10 20:00:56 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: A /trunk/smtp-auth.c First check-in of the main SMTP AUTH support module. ------------------------------------------------------------------------ r23 | bruce | 2001-08-10 19:54:02 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: M /trunk/qmail-validate.c Use the new dict_load_list to load the dictionaries. ------------------------------------------------------------------------ r22 | bruce | 2001-08-08 20:12:37 -0600 (Wed, 08 Aug 2001) | 2 lines Changed paths: M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject=x Added missing iopoll.o object. ------------------------------------------------------------------------ r21 | bruce | 2001-08-08 20:11:15 -0600 (Wed, 08 Aug 2001) | 2 lines Changed paths: M /trunk/README *** empty log message *** ------------------------------------------------------------------------ r20 | bruce | 2001-08-08 20:05:02 -0600 (Wed, 08 Aug 2001) | 2 lines Changed paths: A /trunk/makedist.py Added distribution file. ------------------------------------------------------------------------ r19 | bruce | 2001-08-08 20:04:54 -0600 (Wed, 08 Aug 2001) | 2 lines Changed paths: A /trunk/NEWS A /trunk/README A /trunk/README.CVS A /trunk/mailfront.html A /trunk/qmail-backend.html A /trunk/qmail-validate.html A /trunk/smtpfront.html Added documentation. ------------------------------------------------------------------------ r18 | bruce | 2001-08-08 20:04:36 -0600 (Wed, 08 Aug 2001) | 2 lines Changed paths: M /trunk/insthier.c *** empty log message *** ------------------------------------------------------------------------ r17 | bruce | 2001-08-08 20:01:53 -0600 (Wed, 08 Aug 2001) | 2 lines Changed paths: D /trunk/architecture.txt D /trunk/features.txt Translated into the HTML documentation and removed. ------------------------------------------------------------------------ r16 | bruce | 2001-08-08 19:59:02 -0600 (Wed, 08 Aug 2001) | 2 lines Changed paths: M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r15 | bruce | 2001-08-08 19:58:49 -0600 (Wed, 08 Aug 2001) | 2 lines Changed paths: A /trunk/smtpfront-echo.c A /trunk/smtpfront-echo=x D /trunk/smtpfront-test.c D /trunk/smtpfront-test=x Renamed smtpfront-test to smtpfront-echo. ------------------------------------------------------------------------ r14 | bruce | 2001-08-07 23:19:39 -0600 (Tue, 07 Aug 2001) | 2 lines Changed paths: M /trunk/features.txt M /trunk/smtp-commands.c Handle RFC 1869 extended RCPT TO: and MAIL FROM: parameters. ------------------------------------------------------------------------ r13 | bruce | 2001-08-07 23:18:36 -0600 (Tue, 07 Aug 2001) | 2 lines Changed paths: M /trunk/insthier.c Adapted to new insthier framework. ------------------------------------------------------------------------ r12 | bruce | 2001-08-07 22:48:17 -0600 (Tue, 07 Aug 2001) | 2 lines Changed paths: M /trunk/features.txt Added badrcptto handling to the qmail backend. ------------------------------------------------------------------------ r11 | bruce | 2001-08-07 22:47:31 -0600 (Tue, 07 Aug 2001) | 2 lines Changed paths: M /trunk/qmail-validate.c Added badrcptto handling. ------------------------------------------------------------------------ r10 | bruce | 2001-08-07 22:47:09 -0600 (Tue, 07 Aug 2001) | 2 lines Changed paths: M /trunk/smtpfront-reject.c Added a missing include. ------------------------------------------------------------------------ r9 | bruce | 2001-08-03 23:16:22 -0600 (Fri, 03 Aug 2001) | 2 lines Changed paths: M /trunk/smtpfront-qmail.c M /trunk/smtpfront-test.c Fixed up the program names. ------------------------------------------------------------------------ r8 | bruce | 2001-08-03 23:16:12 -0600 (Fri, 03 Aug 2001) | 2 lines Changed paths: M /trunk/qmail-validate.c Renamed an internal function. ------------------------------------------------------------------------ r7 | bruce | 2001-08-03 23:15:42 -0600 (Fri, 03 Aug 2001) | 2 lines Changed paths: A /trunk/smtpfront-reject.c A /trunk/smtpfront-reject=x Added a simple reject-everything server. ------------------------------------------------------------------------ r6 | bruce | 2001-08-03 23:15:12 -0600 (Fri, 03 Aug 2001) | 2 lines Changed paths: D /trunk/smtpfront-qmail-er.c D /trunk/smtpfront-qmail-er=x Removed this FutureQuest internal program. ------------------------------------------------------------------------ r5 | bruce | 2001-06-15 21:25:12 -0600 (Fri, 15 Jun 2001) | 2 lines Changed paths: M /trunk/qmail-validate.c M /trunk/smtpfront-qmail-er=x M /trunk/smtpfront-qmail=x Added support for verifying addresses against control/morercpthosts.cdb. ------------------------------------------------------------------------ r4 | bruce | 2001-06-15 21:24:48 -0600 (Fri, 15 Jun 2001) | 3 lines Changed paths: M /trunk/smtp-commands.c Totally rewrote the DATA command to handle the message content in fixed space (as opposed to allocated space for each line). ------------------------------------------------------------------------ r3 | bruce | 2001-06-15 21:23:52 -0600 (Fri, 15 Jun 2001) | 2 lines Changed paths: M /trunk/smtp-mainloop.c M /trunk/smtp.h Renamed databytes to maxdatabytes. ------------------------------------------------------------------------ r2 | bruce | 2001-06-15 21:23:16 -0600 (Fri, 15 Jun 2001) | 2 lines Changed paths: M /trunk/TODO M /trunk/features.txt *** empty log message *** ------------------------------------------------------------------------ r1 | bruce | 2001-06-15 19:33:05 -0600 (Fri, 15 Jun 2001) | 2 lines Changed paths: A /trunk A /trunk/TODO A /trunk/architecture.txt A /trunk/echo-backend.c A /trunk/features.txt A /trunk/insthier.c A /trunk/log.c A /trunk/log.h A /trunk/mailfront.h A /trunk/qmail-backend.c A /trunk/qmail-validate.c A /trunk/qmail.h A /trunk/qmail=l A /trunk/responses.c A /trunk/responses.h A /trunk/smtp-commands.c A /trunk/smtp-mainloop.c A /trunk/smtp-respond.c A /trunk/smtp.h A /trunk/smtp=l A /trunk/smtpfront-qmail-er.c A /trunk/smtpfront-qmail-er=x A /trunk/smtpfront-qmail.c A /trunk/smtpfront-qmail=x A /trunk/smtpfront-test.c A /trunk/smtpfront-test=x Initial revision ------------------------------------------------------------------------ mailfront-1.16/protocol-qmqp.c0000664000076400007640000000455011356700500015763 0ustar bruceguenter#include #include #include #include #include #include #include #include "mailfront.h" #include "qmtp.h" static const response* resp; static char buf[8192]; static str line; static void die(const char* msg) { response r = { 451, msg }; respond(&r); exit(111); } static void get_wrapper(ibuf* in) { unsigned long wraplen; switch (get_netstring_len(in, &wraplen)) { case -1: exit(0); case 0: die("Invalid wrapper netstring"); } } static void get_body(ibuf* in) { unsigned long bodylen; char nl; switch (get_netstring_len(in, &bodylen)) { case -1: exit(0); case 0: die("Invalid message body netstring"); } if (bodylen == 0) die("Zero length message"); if (response_ok(resp)) resp = handle_data_start(); while (bodylen > 0) { unsigned long len = sizeof buf; if (len > bodylen) len = bodylen; if (!ibuf_read(in, buf, len) && in->count == 0) die("EOF while reading body"); if (response_ok(resp)) handle_data_bytes(buf, in->count); bodylen -= in->count; } if (!ibuf_getc(in, &nl)) die("EOF while reading comma"); if (nl != ',') die("Invalid netstring terminator"); } static void get_sender(ibuf* in) { switch (get_netstring(in, &line)) { case -1: die("EOF while reading sender address"); case 0: die("Invalid sender netstring"); } msg3("sender <", line.s, ">"); if (response_ok(resp)) resp = handle_sender(&line); } static void get_recips(ibuf* in) { char ch; while (ibuf_peek(in, &ch)) { if (ch == ',') return; switch (get_netstring(in, &line)) { case -1: die("EOF while reading recipient list"); case 0: die("Invalid recipient netstring"); } msg3("recipient <", line.s, ">"); if (response_ok(resp)) resp = handle_recipient(&line); } die("EOF before end of recipient list"); } static void get_package(ibuf* in) { resp = handle_reset(); get_wrapper(in); get_body(in); get_sender(in); get_recips(in); if (response_ok(resp)) resp = handle_message_end(); if (!resp) resp = &resp_accepted; if (!respond(resp)) die("EOF while sending response"); } static int mainloop(void) { alarm(3600); get_package(&inbuf); return 0; } struct protocol protocol = { .version = PROTOCOL_VERSION, .name = "QMQP", .respond_line = qmtp_respond_line, .mainloop = mainloop, }; mailfront-1.16/plugin-add-received.c0000664000076400007640000000631711356700500016761 0ustar bruceguenter#include #include #include #include #include #include "mailfront.h" static str received; static str fixup_host; static str fixup_ip; static const char* linkproto; static const char* local_host; static const char* local_ip; static const char* remote_host; static const char* remote_ip; static const char* date_string(void) { static char datebuf[64]; time_t now = time(0); struct tm* tm = gmtime(&now); strftime(datebuf, sizeof datebuf - 1, "%d %b %Y %H:%M:%S -0000", tm); return datebuf; } static int str_catfromby(str* s, const char* helo_domain, const char* host, const char* ip) { if (helo_domain == 0) helo_domain = (host != 0) ? host : (ip != 0) ? ip : UNKNOWN; if (!str_cats(s, helo_domain)) return 0; if (host != 0 || ip != 0) { if (!str_cats(s, " (")) return 0; if (host != 0) { if (!str_cats(s, host)) return 0; if (ip != 0) if (!str_catc(s, ' ')) return 0; } if (ip != 0) if (!str_catc(s, '[') || !str_cats(s, ip) || !str_catc(s, ']')) return 0; if (!str_catc(s, ')')) return 0; } return 1; } static int fixup_received(str* s) { if (local_host && local_ip && fixup_host.len > 0 && fixup_ip.len > 0 && (strcasecmp(local_host, fixup_host.s) != 0 || strcasecmp(local_ip, fixup_ip.s) != 0)) { if (!str_cat3s(s, "Received: from ", local_host, " (")) return 0; if (!str_cat4s(s, local_host, " [", local_ip, "])\n" " by ")) return 0; if (!str_cat(s, &fixup_host)) return 0; if (!str_cats(s, " ([")) return 0; if (!str_cat(s, &fixup_ip)) return 0; if (!str_cat3s(s, "]); ", date_string(), "\n")) return 0; } return 1; } static int add_header_add(str* s) { const char* add = session_getenv("HEADER_ADD"); if (add != 0) { if (!str_cats(s, add)) return 0; if (!str_catc(s, '\n')) return 0; } return 1; } static int build_received(str* s) { if (!str_cats(s, "Received: from ")) return 0; if (!str_catfromby(s, session_getstr("helo_domain"), remote_host, remote_ip)) return 0; if (!str_cats(s, "\n by ")) return 0; if (!str_catfromby(s, local_host, 0, local_ip)) return 0; if (!str_cat4s(s, "\n with ", session_protocol(), " via ", linkproto)) return 0; if (!str_cat3s(s, "; ", date_string(), "\n")) return 0; return 1; } static const response* init(void) { const char* tmp; linkproto = getprotoenv(0); local_ip = getprotoenv("LOCALIP"); remote_ip = getprotoenv("REMOTEIP"); local_host = getprotoenv("LOCALHOST"); remote_host = getprotoenv("REMOTEHOST"); if ((tmp = getenv("FIXUP_RECEIVED_HOST")) != 0) { if (!str_copys(&fixup_host, tmp)) return &resp_oom; str_strip(&fixup_host); } if ((tmp = getenv("FIXUP_RECEIVED_IP")) != 0) { if (!str_copys(&fixup_ip, tmp)) return &resp_oom; str_strip(&fixup_ip); } return 0; } static const response* data_start(int fd) { received.len = 0; if (!fixup_received(&received) || !add_header_add(&received) || !build_received(&received)) return &resp_internal; return backend_data_block(received.s, received.len); (void)fd; } struct plugin plugin = { .version = PLUGIN_VERSION, .init = init, .data_start = data_start, }; mailfront-1.16/mailrules.html0000664000076400007640000001523011356700500015662 0ustar bruceguenter

MailFront

SMTP Front Ends

Mail Rules Specification


Selection

The use of mail rules is controlled by the environment variable $MAILRULES. This variable specifies the path to the mail rules file. If $MAILRULES is set but the path that it points to cannot be opened, processing will fail with a temporary error. There is no default value -- if it is not set, mail rules processing is disabled.

The rules listed are applied before any other sender or recipient processing is done (such as checking against qmail's badmailfrom file).

Syntax

Each rule in the file occupies a single line. Blank lines and lines starting with "#" are ignored as comments.

Selector Lines

Selector lines specify when the following rules are to be applied. A selector line starts with a colon (":"). The following selectors are defined:

:sender
Apply the following rules only to senders. Any recipient pattern present in the rule is ignored.
:recipient
Apply the following rules only to recipients.
Rules that precede a selector are categorized as follows (for compatibility with existing rules:
  • If the rule has a recipient pattern of "*" (which matches everything), it will be applied as a sender only rule.
  • All other rules are applied as recipient rules.

Rule Lines

Each rule line starts with one of the following prefixes:

k
Accept the sender or recipient.
z
Reject the sender or recipient with a temporary error code.
d
Reject the sender or recipient with a permanent error code.
n
NO-OP: apply the databytes, relayclient, and/or environment settings, but continue processing further rules.
p
Pass the sender or recipient on to the next processing state (ie $RELAYCLIENT or back-end validation).
The remainder of the line consists of a series of fields seperated by colons (":"). The fields are:
  1. Sender: A pattern applied to the envelope sender address.
  2. Recipient: A pattern applied to the envelope recipient address.
  3. Response: The response message that will be given to the client with the numerical code. The default for this message depends on the line's prefix.
  4. Data Bytes: Reduces the maximum message size to the lesser of the current limit (as set at startup by $DATABYTES) and the specified number. This message size limit is reset to its original value before after each message. If empty or missing, no changes are made.
  5. Relay Client: If present, the current recipient address is suffixed with this string. Only useful for "k" rules.
  6. Environment: Environment variables to set as a result of matching this rule. This field contains a list of assignments seperated by commas. Each assignment is formatted as NAME=VALUE. If a value needs to contain a comma, it must be quoted as follows: \..

Escaping

The following escape sequences are recognized in all the fields:

  • \n newline (replaced with a CR+LF pair on output)
  • \### character with octal value ### (exactly 3 digits)
  • \\ backslash
  • \: colon

Patterns

Pattern Syntax

Patterns are globs, similar to UNIX shell-style wildcards (but quite different from full regular expressions).
Pattern Matches
* Any sequence of characters (including the empty sequence).
? Any single character.
[seq] A single occurance of any character in seq.
[!seq] A single occurance of any character not in seq.
Any other character matches itself, without regard for case. Patterns containing only "*" match anything. Note: An empty pattern matches only the empty string.

Special Patterns

The following patterns are treated specially:

[[@filename]]
Matches the domain portion of the address against the control file named filename. Typical uses would be "[[@rcpthosts]]" and "[[@morercpthosts.cdb]]" in the recipient field.
[[filename]]
Matches the entire address against the control file named filename. A typical use would be "[[badmailfrom]]" in the sender field.
If filename ends with .cdb, the control file is opened as a CDB file. Addresses are translated to lower-case before doing CDB lookups. Otherwise, control files are plain text lists, with one entry per line. Empty lines and lines starting with "#" are ignored. Lines starting with "@" match only the domain portion of the address. All comparisons are case insensitive. Missing CDB files are silently ignored. Missing text files cause an error message at startup.

Negation

Prefixing the pattern with a ! inverts the result of the match. That is, if the pattern match does not succeed, the rule will succeed instead of failing. This applies to all patterns including the special patterns above.

Semantics

Each rule is applied in the order they are listed in the rules file until one matches. At that point, the command that triggered the rule search is accepted, deferred, or rejected depending on the rule type. If the sender is not accepted, no recipients can be accepted, as usual. As long as at least one recipient is accepted the message data may be accepted.

Examples

qmail Rules

The following rules provide the functionality similar to that available in qmail-smtpd. Please note that the qmail validation routines already provide this functionality. These rules are listed for illustrative purposes only.

:sender
d[[/var/qmail/control/badmailfrom]]:*:sorry, your envelope sender is in my badmailfrom list (#5.7.1)
:recipient
k*:[[@/var/qmail/control/rcpthosts]]
k*:[[@/var/qmail/control/morercpthosts.cdb]]

Abused Patterns

The following rules block old exploitable addresses that are still commonly probed: bang paths, multiple domains, and percent hacks.

d*:*!*: Sorry, we don't allow that here
d*:*@*@*: Sorry, we don't allow that here
d*:*%*: Sorry, percent hack not accepted here
mailfront-1.16/README0000664000076400007640000000733511356700500013666 0ustar bruceguentermailfront Mail server network protocol front-ends Bruce Guenter Version 1.16 2010-04-06 This is mailfront, a package containing customizeable network front-ends for mail servers. It contains complete SMTP, QMQP, QMTP, and POP3 front-ends as well as an authentication module for IMAP. The mail delivery front-ends also contain internal address filtering features. Two SMTP back-ends are provided. One delivers mail to qmail-queue, mimicking most of the behavior of qmail-smtpd, with the addition of support for SMTP AUTH. The other rejects all SMTP commands if $SMTPREJECT is set, and execs its command line otherwise (in order to run the above program). A mailing list has been set up to discuss this and other packages. To subscribe, send an email to: bgware-subscribe@lists.untroubled.org A mailing list archive is available at: http://lists.untroubled.org/?list=bgware Development versions of mailfront are available via git at: http://bruce-guenter.dyndns.org/git/mailfront.git Requirements: - bglibs version 1.101 - cvm version 0.81 Installation: - Build the sources by running "make". - After the package has been compiled, run "make install" as root. Configuration: - To take advantage of the SMTP AUTH features, make sure you have a CVM authentication program (some are included with the cvm package itself). - Run a CVM authentication module to provide the AUTH feature. Example: To run cvm-vmailmgr as a daemon: exec /usr/local/bin/softlimit -m 9000000 \ /usr/local/bin/cvm-vmailmgr /tmp/.cvm-vmailmgr 2>&1 - Configure your mail system to use the SMTP back-end with the appropriate environment variables. Example using tcpserver (highly recommended): #!/bin/sh QMAILDUID=`id -u qmaild` NOFILESGID=`id -g qmaild` MAXSMTPD=`head -1 /var/qmail/control/concurrencyincoming` if [ -z "$QMAILDUID" -o -z "$NOFILESGID" -o -z "$MAXSMTPD" ]; then echo $0: QMAILDUID, NOFILESGID, or MAXSMTPD is unset exit 1 fi exec \ /usr/local/bin/envdir /etc/smtpfront \ /usr/local/bin/softlimit -m 2000000 \ /usr/local/bin/tcpserver -v -R -H \ -l "`head -1 /var/qmail/control/me`" -x /etc/tcp.smtp.cdb \ -c "$MAXSMTPD" -u "$QMAILDUID" -g "$NOFILESGID" 0 25 \ /usr/local/bin/smtpfront-qmail 2>&1 /etc/smtpfront/CVM_SASL_PLAIN: cvm-local:/tmp/.cvm-vmailmgr Example using xinetd with TCP Wrappers: /etc/xinetd.d/smtp: # default: on # description: smtp service smtp { disable = no flags = REUSE NAMEINARGS socket_type = stream protocol = tcp wait = no user = qmaild server = /usr/sbin/tcpd server_args = /var/qmail/bin/tcp-env -R /usr/local/sbin/smtpfront-wrapper log_on_success += USERID log_on_failure += USERID } /usr/local/sbin/smtpfront-wrapper: #!/bin/sh CVM_SASL_PLAIN=cvm-local:/tmp/.cvm-unix export CVM_SASL_PLAIN CVM_SASL_LOGIN=cvm-local:/tmp/.cvm-unix export CVM_SASL_LOGIN exec /usr/local/bin/smtpfront-qmail 2>> /tmp/smtpfront-errs.txt This project was initiated at FutureQuest, Inc. We are releasing it as an open-source project because we felt it would be useful to others, as well as to repay our debt of gratitude to the larger open-source community for the excellent packages we have enjoyed. For more details, you may contact FutureQuest, Inc. at: FutureQuest, Inc. PO BOX 623127 Oviedo FL 32762-3127 USA http://www.FutureQuest.net/ ossi@FutureQuest.net This package is Copyright(C) 2010 Bruce Guenter or FutureQuest, Inc., and may be copied according to the GNU GENERAL PUBLIC LICENSE (GPL) Version 2 or a later version. A copy of this license is included with this package. This package comes with no warranty of any kind. mailfront-1.16/plugin-force-file.c0000664000076400007640000000117011356700500016450 0ustar bruceguenter#include #include #include #include "mailfront.h" static RESPONSE(no_file,451,"4.3.0 No temporary file was created"); static RESPONSE(stat,451,"4.3.0 Could not fstat temporary file"); static RESPONSE(not_file,451,"4.3.0 Temporary file is not a regular file"); static const response* data_start(int fd) { struct stat st; if (fd < 0) return &resp_no_file; if (fstat(fd, &st) != 0) return &resp_stat; if (!S_ISREG(st.st_mode)) return &resp_not_file; return 0; } struct plugin plugin = { .version = PLUGIN_VERSION, .flags = FLAG_NEED_FILE, .data_start = data_start, }; mailfront-1.16/responses.h0000664000076400007640000000067211356700500015175 0ustar bruceguenter#ifndef MAIL_FRONT__RESPONSES__H__ #define MAIL_FRONT__RESPONSES__H__ struct response { unsigned number; const char* message; }; typedef struct response response; extern const response resp_accepted; extern const response resp_internal; extern const response resp_oom; #define RESPONSE(NAME,CODE,MSG) const response resp_##NAME = {CODE,MSG} extern int number_ok(const response* r); extern int response_ok(const response* r); #endif mailfront-1.16/pop3-mainloop.c0000664000076400007640000000431611356700500015643 0ustar bruceguenter/* pop3-mainloop.c - POP3 server main loop * Copyright (C) 2008 Bruce Guenter or FutureQuest, Inc. * Development of this program was sponsored by FutureQuest, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact information: * FutureQuest Inc. * PO BOX 623127 * Oviedo FL 32762-3127 USA * http://www.FutureQuest.net/ * ossi@FutureQuest.net */ #include #include #include #include #include "pop3.h" const int msg_show_pid = 1; static str line; static str cmd; static str arg; static int parse_line(void) { unsigned i; i = 0; while (i < line.len && line.s[i] != SPACE) ++i; if (!str_copyb(&cmd, line.s, i)) return 0; while (i < line.len && line.s[i] == SPACE) ++i; if (!str_copyb(&arg, line.s+i, line.len-i)) return 0; str_upper(&cmd); return 1; } static void dispatch_line(void) { command* c; for (c = commands; c->name != 0; ++c) { if (str_diffs(&cmd, c->name) == 0) { logmsg(c->sanitized ? c->sanitized : line.s); if (arg.len == 0) { if (c->fn0 == 0) respond(err_syntax); else c->fn0(); } else { if (c->fn1 == 0) respond(err_syntax); else c->fn1(&arg); } return; } } logmsg(line.s); respond(err_unimpl); } extern void set_timeout(void); int main(int argc, char* argv[]) { set_timeout(); if (!startup(argc, argv)) return 0; respond(ok); while (ibuf_getstr_crlf(&inbuf, &line)) { if (!parse_line()) respond(err_internal); else dispatch_line(); } if (ibuf_timedout(&inbuf)) respond("-ERR Connection timed out"); return 0; } mailfront-1.16/plugin-mailrules.html0000664000076400007640000000134011356700500017153 0ustar bruceguenter

mailfront

Plugin: mailrules


This plugin applies a list of rules to sender and/or recipient addresses. See the mail rules specification for a description of how the rules are specified and applied.

Configuration

$MAILRULES
The location of the mail rules file. If not set, no processing is done.

Sender Action

See the mail rules specification.

Recipient Action

See the mail rules specification.

Data Action

None

Message Action

None

mailfront-1.16/SRCFILES0000664000076400007640000000136511356700500014140 0ustar bruceguenterINSTHIER backend-echo.c backend-qmail.c builtins.c conf-modules constants.h getprotoenv.c imapfront-auth.c iobytes.c mailfront-internal.h mailfront.c mailfront.h modules.c netstring.c plugin-add-received.c plugin-check-fqdn.c plugin-clamav.c plugin-counters.c plugin-cvm-validate.c plugin-force-file.c plugin-mailrules.c plugin-patterns.c plugin-qmail-validate.c plugin-reject.c plugin-relayclient.c plugin-require-auth.c plugin-spamassassin.c pop3-capa.c pop3-mainloop.c pop3-response.c pop3.h pop3front-auth.c pop3front-maildir.c protocol-qmqp.c protocol-qmtp.c protocol-smtp.c qmqpfront-echo.sh qmqpfront-qmail.sh qmtp-respond.c qmtp.h qmtpfront-echo.sh qmtpfront-qmail.sh responses.c responses.h session.c smtpfront-echo.sh smtpfront-qmail.sh timeout.c mailfront-1.16/protocol-qmtp.c0000664000076400007640000000530211356700500015762 0ustar bruceguenter#include #include #include #include #include #include #include #include "mailfront.h" #include "qmtp.h" static const response* resp; static char buf[8192]; static str line; static str tmp; static void die(const char* msg) { response r = { 451, msg }; respond(&r); exit(111); } static void get_body(ibuf* in) { unsigned long bodylen; char nl; switch (get_netstring_len(in, &bodylen)) { case -1: exit(0); case 0: die("Invalid message body netstring"); } if (bodylen == 0) die("Zero length message"); --bodylen; if (!ibuf_getc(in, &nl)) die("EOF while reading body NL"); if (nl != LF) die("Cannot handle non-LF line terminator"); if (response_ok(resp)) resp = handle_data_start(); while (bodylen > 0) { unsigned long len = sizeof buf; if (len > bodylen) len = bodylen; if (!ibuf_read(in, buf, len) && in->count == 0) die("EOF while reading body"); if (response_ok(resp)) handle_data_bytes(buf, in->count); bodylen -= in->count; } if (!ibuf_getc(in, &nl)) die("EOF while reading comma"); if (nl != ',') die("Invalid netstring terminator"); } static void get_sender(ibuf* in) { switch (get_netstring(in, &line)) { case -1: die("EOF while reading sender address"); case 0: die("Invalid sender netstring"); } msg3("sender <", line.s, ">"); if (response_ok(resp)) resp = handle_sender(&line); } static void get_recips(ibuf* in) { unsigned long i; switch (get_netstring(in, &line)) { case -1: die("EOF while reading recipient list"); case 0: die("Invalid recipient netstring"); } for (i = 0; response_ok(resp) && i < line.len; i++) { unsigned long j; unsigned long len; for (len = 0, j = i; j < line.len; ++j) { if (line.s[j] == ':') break; if (line.s[j] < '0' || line.s[j] > '9') die("Invalid netstring length"); len = len * 10 + line.s[j] - '0'; } ++j; if (j + len > line.len) die("Netstring length too long"); if (line.s[j+len] != ',') die("Netstring missing comma"); str_copyb(&tmp, line.s+j, len); msg3("recipient <", tmp.s, ">"); if (response_ok(resp)) resp = handle_recipient(&tmp); i = j + len; } } static void get_package(ibuf* in) { resp = handle_reset(); get_body(in); get_sender(in); get_recips(in); if (response_ok(resp)) resp = handle_message_end(); if (!resp) resp = &resp_accepted; if (!respond(resp)) die("EOF while sending response"); } static int mainloop(void) { alarm(3600); for (;;) get_package(&inbuf); } struct protocol protocol = { .version = PROTOCOL_VERSION, .name = "QMTP", .respond_line = qmtp_respond_line, .mainloop = mainloop, }; mailfront-1.16/msa.html0000664000076400007640000001176211356700500014453 0ustar bruceguenter

MailFront

SMTP Front Ends

Message Submission Agent


Summary

An MSA (message submission agent) is a mail component specifically designed to accept mail submitted by an MUA (message user agent, or mail client) for further delivery or relaying. This is in contrast to a MTA (message transfer agent) which is designed to accept mail from other MTAs primarily for local delivery. The most important standard governing the behavior of an MSA is RFC 2476. All modules described as being "MSA compliant" can fill the role described by the standard.

RFC 2476 Details

Section Description Status
Requirements
3.2 A null return path, that is, MAIL FROM:<>, is permitted and MUST be accepted. (MUAs need to generate null return-path messages for a variety of reasons, including disposition notifications.) Yes
4.1 Unless covered by a more precise response code, response code 554 is to be used to reject a MAIL FROM, RCPT TO, or DATA command that contains something improper. Enhanced status code 5.6.0 is to be used if no other code is more specific. Yes
4.2 The MSA MUST ensure that all domains in the envelope are fully-qualified. Yes
4.2 If the MSA examines or alters the message text in way, except to add trace header fields [RFC 821 / RFC 2821], it MUST ensure that all domains in address header fields are fully-qualified. N/A
4.2 Reply code 554 is to be used to reject a MAIL FROM, RCPT TO, or DATA command which contains improper domain references. Yes
5.1 Reply code 501 is to be used to reject a MAIL FROM or RCPT TO command that contains a detectably improper address. N/A
5.1 When addresses are resolved after submission of the message body, reply code 554 with enhanced status code 5.6.2 is to be used after end-of-data, if the message contains invalid addresses in the header. N/A
6.4 Reply code 554 is used for syntactic problems in the data. Reply code 501 is used if the command itself is not syntactically valid. Reply code 550 with enhanced status code 5.7.1 is used to reject based on the submitting user. Reply code 550 with enhanced status code 5.7.0 is used if the message violates site policy. N/A
7 The MSA MUST NOT accept ETRN. [RFC 1985] Yes
7 The MSA MUST NOT send the SMTP 521 Reply Code [RFC 1845] Yes
8.1 The MSA MUST ensure that any address it places in a 'Sender' field is in fact a valid mail address. N/A
Recommendations
3.2 If an MSA is not able to determine a return path to the submitting user, from a valid MAIL FROM, a valid source IP address, or based on authenticated identity, then the MSA SHOULD immediately reject the message. A message can be immediately rejected by returning a 550 code to the MAIL FROM command. N/A
4.2 Local conventions that permit single-level domains SHOULD reject, rather than expand, incomplete multi-level domains. N/A
5.1 An MSA SHOULD reject messages with illegal syntax in a sender or recipient envelope address. N/A
5.1 If the MSA examines or alters the message text in way, except to add trace header fields, it SHOULD reject messages with illegal address syntax in address header fields. N/A
5.2 The MSA SHOULD log message errors, especially apparent misconfigurations of client software. No
7 The MSA SHOULD accept pipelining. [RFC 2197] Yes
7 The MSA SHOULD send error codes. [RFC 2034] Yes
7 The MSA SHOULD send extended response codes. [RFC 1893] Yes
7 The MSA SHOULD support DSN. [RFC 1891] No
7 The MSA SHOULD accept 8-bit MIME data. [RFC 1652] Yes?
mailfront-1.16/qmqpfront-qmail.sh0000664000076400007640000000023111356700500016456 0ustar bruceguenterexec "$(dirname $0)"/mailfront qmqp qmail check-fqdn counters mailrules relayclient cvm-validate qmail-validate add-received patterns accept-sender "$@" mailfront-1.16/TARGETS0000664000076400007640000000147511356700500014041 0ustar bruceguenterall backend-echo.so backend-qmail.so builtins.o clean clean-spac compile conf_modules.c conf_qmail.c dl.lib docs getprotoenv.o imapfront-auth imapfront-auth.o install iobytes.o libraries load mailfront mailfront.o makelib makeso modules.o plugin-add-received.so plugin-check-fqdn.so plugin-clamav.so plugin-counters.so plugin-cvm-validate.so plugin-force-file.so plugin-mailrules.so plugin-patterns.so plugin-qmail-validate.so plugin-reject.so plugin-relayclient.so plugin-require-auth.so plugin-spamassassin.so pop3-capa.o pop3-mainloop.o pop3-response.o pop3.a pop3front-auth pop3front-auth.o pop3front-maildir pop3front-maildir.o programs protocol-qmqp.so protocol-qmtp.so protocol-smtp.so qmqpfront-echo qmqpfront-qmail qmtpfront-echo qmtpfront-qmail responses.o session.o smtpfront-echo smtpfront-qmail socket.lib timeout.o mailfront-1.16/plugin-patterns.html0000664000076400007640000000442011356700500017020 0ustar bruceguenter

MailFront

SMTP Front Ends

Plugin: patterns


This module provides an ability for rejecting messages based on simple patterns in their content.

Configuration

$PATTERNS
If set, the named file is loaded and parsed (see below), and pattern matching is enabled.
$PATTERNS_LINEMAX
Line buffer size (defaults to 256)
$PATTERNS_RESP
Response message to give when a pattern is matched (defaults to "This message contains prohibited content")

Sender Action

None

Recipient Action

None

Data Action

Each line of the data sent from the client is loaded into a line buffer (with a maximum size as above) and then scanned against the patterns listed in the configuration file. If any pattern matches, the message is rejected.

Message Action

None

Patterns File Format

The patterns file contains a list of standard glob-style patterns. Each line of the file starts with a control character, which is not part of the pattern itself:

#
Comment line, ignored.
=
Sets the response text given when a message is rejected. All following patterns use this response until the next response line. Including this in the patterns file overrides the value of $PATTERNS_RESP.
:
The pattern will be applied only in the header.
\
The pattern will be applied only after a blank line.
Anything else
A normal pattern, applied to any non-blank line.

The following patterns list is a much simplified version of Russell Nelson's qmail-smtpd virus scan patch. In particular, it doesn't actually do any kind of checking if the blank line really marked a MIME boundary or not.

=We don't accept email with executable content (#5.3.4)
\TVqQAAMAA*
\TVpQAAIAA*
\TVpAALQAc*
\TVpyAXkAX*
\TVrmAU4AA*
\TVrhARwAk*
\TVoFAQUAA*
\TVoAAAQAA*
\TVoIARMAA*
\TVouARsAA*
\TVrQAT8AA*
\TVoAAAEAAA*
mailfront-1.16/conf-modules0000664000076400007640000000010711356700500015312 0ustar bruceguenter/usr/local/lib/mailfront Modules will be installed in this directory. mailfront-1.16/backend-qmail.html0000664000076400007640000000144111356700500016354 0ustar bruceguenter

Mailfront

Backend: qmail


Features:

  • The qmail home directory is compiled into the program, and defaults to /var/qmail, but may be overridden by $QMAILHOME.
  • Messages are delivered through the executable named in $QMAILQUEUE, or $QMAILHOME/bin/qmail-queue if it is not set.
  • If qmail-queue exits non-zero, the qmail backend looks for an error message in $QQERRMSG_#, where # is the exit code of qmail-queue. As usual, exit codes between 11 and 40 indicate permanent errors, and all others indicate temporary errors.
  • The qmail-queue PID is logged in success messages for correlation with the qmail logs.
mailfront-1.16/mailfront-internal.h0000664000076400007640000000154711356700500016763 0ustar bruceguenter#ifndef MAIL_FRONT__MAILFRONT_INTERNAL__H__ #define MAIL_FRONT__MAILFRONT_INTERNAL__H__ #include "mailfront.h" #include struct session { struct protocol* protocol; struct plugin* backend; struct ghash strs; struct ghash nums; str env; int fd; struct plugin* plugin_list; struct plugin* plugin_tail; unsigned flags; const char* module_path; }; GHASH_DECL(session_strs,const char*,const char*); GHASH_DECL(session_nums,const char*,unsigned long); extern struct session session; /* From builtins.c */ extern struct plugin builtin_plugins[]; /* From modules.c */ extern void add_plugin(struct plugin*); extern const response* load_modules(const char* protocol_name, const char* backend_name, const char** plugins); /* From session.c */ extern void session_init(void); #endif /* MAIL_FRONT__MAILFRONT_INTERNAL__H__ */ mailfront-1.16/qmtp.h0000664000076400007640000000024611356700500014132 0ustar bruceguenter#ifndef MAIL_FRONT__QMTP__H__ #define MAIL_FRONT__QMTP__H__ #include "responses.h" extern int qmtp_respond_line(unsigned, int, const char*, unsigned long); #endif mailfront-1.16/plugin-require-auth.c0000664000076400007640000000054011356700500017050 0ustar bruceguenter#include "mailfront.h" static RESPONSE(mustauth, 530, "5.7.1 You must authenticate first."); static const response* sender(str* s) { if (!session_getnum("authenticated", 0) && session_getenv("RELAYCLIENT") == 0) return &resp_mustauth; return 0; (void)s; } struct plugin plugin = { .version = PLUGIN_VERSION, .sender = sender, }; mailfront-1.16/conf-bglibs0000664000076400007640000000002611356700500015104 0ustar bruceguenter/usr/local/bglibs/lib mailfront-1.16/pop3front-maildir.c0000664000076400007640000002570611356700500016525 0ustar bruceguenter/* pop3front-maildir.c -- POP3 main program * Copyright (C) 2008 Bruce Guenter or FutureQuest, Inc. * Development of this program was sponsored by FutureQuest, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact information: * FutureQuest Inc. * PO BOX 623127 * Oviedo FL 32762-3127 USA * http://www.FutureQuest.net/ * ossi@FutureQuest.net */ #include #include #include #include #include #include #include #include #include #include #include #include "pop3.h" typedef struct { const char* filename; unsigned long size; int read; int deleted; int uid_len; } msg; #define MSG_DELETED ((unsigned long)-1) const char program[] = "pop3front-maildir"; const int authenticating = 0; static str msg_filenames; static msg* msgs; static long max_count; static long max_new_count; static long max_cur_count; static long new_count; static long cur_count; static long del_count; static long msg_count; static long msg_bytes; static long del_bytes; static str tmp; static long scan_dir(const char* subdir, str* list, long* countptr, long max) { DIR* dir; direntry* entry; long count; if ((dir = opendir(subdir)) == 0) return 0; count = 0; while (!(max_count > 0 && msg_count >= max_count) && !(max > 0 && count >= max) && (entry = readdir(dir)) != 0) { if (entry->d_name[0] == '.') continue; if (!str_copys(&tmp, subdir)) return 0; if (!str_catc(&tmp, '/')) return 0; if (!str_cats(&tmp, entry->d_name)) return 0; if (!str_cat(list, &tmp)) return 0; if (!str_catc(list, 0)) return 0; ++count; ++msg_count; } closedir(dir); *countptr = count; return 1; } static void make_msg(msg* m, const char* filename) { struct stat s; const char* c; const char* base = filename + 4; m->filename = filename; m->size = 0; m->read = 0; m->deleted = 0; m->uid_len = strlen(base); /* Parse out flags */ if ((c = memchr(base, ':', m->uid_len)) != 0) { if (c[1] == '2' && c[2] == ',') if (strchr(c+3, 'S') != 0) m->read = 1; m->uid_len = c - base; } /* Parse out Maildir++ message size indicators */ if ((c = memchr(base, ',', m->uid_len)) != 0 && c[1] != 0 && c[2] == '=') { long left = m->uid_len - (c - base); m->uid_len = c - base; /* There may be more than one size indicator, like "UID,W=###,S=###" */ /* Prefer the W (RFC822.SIZE) size over S (raw byte count). */ while (c != 0) { const char* end = memchr(c + 1, ',', left - 1); if ((c[1] == 'W' || (c[1] == 'S' && m->size == 0)) && c[2] == '=') { m->size = strtoul(c + 3, 0, 10); } left -= end - c; c = end; } } /* The UID length is limited to 70 characters RFC 1939 section 7 */ if (m->uid_len > 70) m->uid_len = 70; /* If no size indicator, stat the message to find the size */ if (m->size == 0) { if (stat(filename, &s) == -1) m->size = 0, m->deleted = 1; else m->size = s.st_size; } msg_bytes += m->size; } static int fn_compare(const str_sortentry* a, const str_sortentry* b) { if (a->str[4] < '0' || a->str[4] > '9' || b->str[4] < '0' || b->str[4] > '9') return strcmp(a->str+4, b->str+4); else { int at = atoi(a->str+4); int bt = atoi(b->str+4); return at - bt; } } static int scan_maildir(void) { long pos; long i; msg_bytes = 0; if (!str_truncate(&msg_filenames, 0)) return 0; msg_count = 0; if (!scan_dir("cur", &msg_filenames, &cur_count, max_cur_count)) return 0; if (!scan_dir("new", &msg_filenames, &new_count, max_new_count)) return 0; if (msg_count == 0) return 1; if (!str_sort(&msg_filenames, 0, -1, fn_compare)) return 0; del_count = 0; del_bytes = 0; if (msgs != 0) free(msgs); if ((msgs = malloc(msg_count * sizeof msgs[0])) == 0) return 0; for (i = pos = 0; i < msg_count; pos += strlen(msg_filenames.s+pos)+1, ++i) make_msg(&msgs[i], msg_filenames.s + pos); return 1; } static int msgnum_check(long i) { if (i <= 0 || i > msg_count) respond("-ERR Message number out of range"); else if (msgs[i-1].deleted) respond("-ERR Message was deleted"); else return 1; return 0; } static long msgnum(const str* arg) { long i; char* end; if ((i = strtol(arg->s, &end, 10)) < 0 || *end != 0) respond(err_syntax); else if (msgnum_check(i)) return i; return 0; } static void dump_msg(long num, long bodylines) { ibuf in; static char buf[4096]; int in_header; /* True until a blank line is seen */ int sol; /* True if at start of line */ if (!ibuf_open(&in, msgs[num-1].filename, 0)) return respond("-ERR Could not open that message"); respond(ok); sol = in_header = 1; while (ibuf_read(&in, buf, sizeof buf) || in.count) { const char* ptr = buf; const char* end = buf + in.count; while (ptr < end) { const char* lfptr; if (sol) { if (!in_header) if (--bodylines < 0) break; if (*ptr == '.') obuf_putc(&outbuf, '.'); } if ((lfptr = memchr(ptr, LF, end-ptr)) == 0) { obuf_write(&outbuf, ptr, end-ptr); ptr = end; sol = 0; } else { if (in_header && lfptr == ptr) in_header = 0; obuf_write(&outbuf, ptr, lfptr-ptr); obuf_puts(&outbuf, CRLF); ptr = lfptr + 1; sol = 1; } } } ibuf_close(&in); obuf_puts(&outbuf, CRLF); respond("."); } /* Mark a maildir filename with the named flag */ static int add_flag(str* fn, char flag) { int c; /* If the filename has no flags, append them */ if ((c = str_findfirst(fn, ':')) == -1) { if (!str_cats(fn, ":2,")) return 0; } else { /* If it has a colon (start of flags), see if they are a type we * recognize, and bail out if they aren't */ if (fn->s[c+1] != '2' || fn->s[c+2] != ',') return 1; /* Scan through the flag characters and return success * if the message is already marked with the flag */ if (strchr(fn->s+c+3, flag) != 0) return 1; } return str_catc(fn, flag); } /* Commands ******************************************************************/ static void cmd_dele(const str* arg) { long i; if ((i = msgnum(arg)) == 0) return; --i; del_bytes += msgs[i].size; del_count++; msgs[i].deleted = 1; respond(ok); } static void cmd_last(void) { long last; long i; for (last = i = 0; i < msg_count; i++) if (msgs[i].read) last = i + 1; if (!str_copys(&tmp, "+OK ") || !str_cati(&tmp, last)) respond(err_internal); respond(tmp.s); } static void cmd_list(void) { long i; respond(ok); for (i = 0; i < msg_count; i++) { if (!msgs[i].deleted) { obuf_putu(&outbuf, i+1); obuf_putc(&outbuf, SPACE); obuf_putu(&outbuf, msgs[i].size); obuf_puts(&outbuf, CRLF); } } respond("."); } static void cmd_list_one(const str* arg) { long i; if ((i = msgnum(arg)) == 0) return; if (!str_copys(&tmp, "+OK ") || !str_catu(&tmp, i) || !str_catc(&tmp, SPACE) || !str_catu(&tmp, msgs[i-1].size)) respond(err_internal); else respond(tmp.s); } static void cmd_noop(void) { respond(ok); } static void cmd_quit(void) { long i; for (i = 0; i < msg_count; i++) { const char* fn = msgs[i].filename; if (msgs[i].deleted) unlink(fn); /* Logic: * 1. move all messages into "cur" * 2. tag all read messages without flags with a read flag (:2,S) * Note: no real opportunity to report errors, * so just continue when we hit one. */ else { if (!str_copys(&tmp, "cur/")) continue; if (!str_cats(&tmp, fn+4)) continue; if (msgs[i].read && !add_flag(&tmp, 'S')) continue; rename(fn, tmp.s); } } respond(ok); exit(0); } static void cmd_rset(void) { if (!scan_maildir()) { respond(err_internal); exit(1); } respond(ok); } static void cmd_stat(void) { if (!str_copys(&tmp, "+OK ") || !str_catu(&tmp, msg_count - del_count) || !str_catc(&tmp, SPACE) || !str_catu(&tmp, msg_bytes - del_bytes)) respond(err_internal); else respond(tmp.s); } static void cmd_top(const str* arg) { long num; long lines; char* end; if ((num = strtol(arg->s, &end, 10)) < 0) return respond(err_syntax); if (!msgnum_check(num)) return; while (*end == SPACE) ++end; if (*end == 0) { msgs[num-1].read = 1; return dump_msg(num, LONG_MAX); } if ((lines = strtol(end, &end, 10)) < 0 || *end != 0) return respond(err_syntax); dump_msg(num, lines); } static void cmd_uidl(void) { long i; respond(ok); for (i = 0; i < msg_count; i++) { msg* m = &msgs[i]; if (!m->deleted) { const char* fn = m->filename + 4; obuf_putu(&outbuf, i+1); obuf_putc(&outbuf, SPACE); obuf_write(&outbuf, fn, m->uid_len); obuf_puts(&outbuf, CRLF); } } respond("."); } static void cmd_uidl_one(const str* arg) { long i; if ((i = msgnum(arg)) != 0) { msg* m = &msgs[i-1]; const char* fn = m->filename + 4; if (!str_copys(&tmp, "+OK ") || !str_catu(&tmp, i) || !str_catc(&tmp, SPACE) || !str_catb(&tmp, fn, m->uid_len)) respond(err_internal); else respond(tmp.s); } } command commands[] = { { "CAPA", cmd_capa, 0, 0 }, { "DELE", 0, cmd_dele, 0 }, { "LAST", cmd_last, 0, 0 }, { "LIST", cmd_list, cmd_list_one, 0 }, { "NOOP", cmd_noop, 0, 0 }, { "QUIT", cmd_quit, 0, 0 }, { "RETR", 0, cmd_top, 0 }, { "RSET", cmd_rset, 0, 0 }, { "STAT", cmd_stat, 0, 0 }, { "TOP", 0, cmd_top, 0 }, { "UIDL", cmd_uidl, cmd_uidl_one, 0 }, { 0, 0, 0, 0 } }; extern void report_io_bytes(void); int startup(int argc, char* argv[]) { const char* env; if (argc > 2) { msg3("usage: ", program, " [default-maildir]"); return 0; } if ((env = getenv("MAX_MESSAGES")) != 0) max_count = atol(env); if ((env = getenv("MAX_CUR_MESSAGES")) != 0) max_cur_count = atol(env); if ((env = getenv("MAX_NEW_MESSAGES")) != 0) max_new_count = atol(env); if ((env = getenv("MAILBOX")) == 0) { if (argc < 2) { error1("Mailbox not specified"); return 0; } env = argv[1]; } if (chdir(env) == -1) { respond("-ERR Could not chdir to maildir"); return 0; } if (!scan_maildir()) { respond("-ERR Could not access maildir"); return 0; } atexit(report_io_bytes); return 1; } mailfront-1.16/plugin-accept-recipient.html0000664000076400007640000000075611356700500020407 0ustar bruceguenter

mailfront

Plugin: accept-recipient


This plugin is used to explicitly accept all recipients. As such, it only makes sense to place this module following all others that may reject recipients.

Configuration

None

Sender Action

None

Recipient Action

Accepts all recipients.

Data Action

None

Message Action

None

mailfront-1.16/builtins.c0000664000076400007640000000062111356700500014772 0ustar bruceguenter#include "mailfront-internal.h" static RESPONSE(accept,250,0); static const response* accept(str* s) { return &resp_accept; (void)s; } struct plugin builtin_plugins[] = { { .name = "accept", .sender = accept, .recipient = accept, }, { .name = "accept-recipient", .recipient = accept, }, { .name = "accept-sender", .sender = accept, }, { .name = 0 } }; mailfront-1.16/conf-qmail0000664000076400007640000000005611356700500014750 0ustar bruceguenter/var/qmail This is the qmail home directory. mailfront-1.16/plugin-mailrules.c0000664000076400007640000002373311356700500016443 0ustar bruceguenter#include #include #include #include "mailfront.h" #include #include #include #include #include static RESPONSE(erropen,421,"4.3.0 Could not open $MAILRULES file"); static RESPONSE(syntax,421,"4.3.0 Syntax error in $MAILRULES"); static RESPONSE(erropenref,421,"4.3.0 Error opening file referenced from $MAILRULES"); #define NUL 0 /* rule tables ************************************************************* */ struct pattern { str pattern; dict* file; struct cdb* cdb; int negated; }; struct rule { int code; struct pattern sender; struct pattern recipient; str response; str relayclient; str environment; unsigned long databytes; struct rule* next; }; static struct rule* sender_rules = 0; static struct rule* recip_rules = 0; static struct rule** current_rules = 0; static void append_rule(struct rule* r) { static struct rule* sender_tail = 0; static struct rule* recip_tail = 0; struct rule** head; struct rule** tail; if (current_rules != 0) tail = ((head = current_rules) == &sender_rules) ? &sender_tail : &recip_tail; else if (r->recipient.pattern.len == 1 && r->recipient.pattern.s[0] == '*') { head = &sender_rules; tail = &sender_tail; } else { head = &recip_rules; tail = &recip_tail; } if (*tail == 0) *head = r; else (*tail)->next = r; *tail = r; } static struct rule* alloc_rule(void) { struct rule* r; if ((r = malloc(sizeof *r)) != 0) memset(r, 0, sizeof *r); return r; } #if 0 static void free_rule(struct rule* r) { str_free(&r->sender.pattern); str_free(&r->recipient.pattern); str_free(&r->response); str_free(&r->relayclient); str_free(&r->environment); free(r); } #endif /* embeded filename handling *********************************************** */ static dict cdb_files; static struct cdb* open_cdb(const str* filename) { int fd; struct cdb* c; if ((c = malloc(sizeof *c)) == 0) return 0; fd = open(filename->s, O_RDONLY); cdb_init(c, fd); if (!dict_add(&cdb_files, filename, c)) return 0; return c; } static int lower(str* s) { str_lower(s); return 1; } static dict text_files; static dict* load_text(const str* filename) { dict* d; if ((d = malloc(sizeof *d)) == 0) return 0; memset(d, 0, sizeof *d); if (!dict_load_list(d, filename->s, 1, lower)) return 0; if (!dict_add(&text_files, filename, d)) return 0; return d; } static int is_special(const str* pattern) { long len = pattern->len; return len > 5 && pattern->s[0] == '[' && pattern->s[1] == '[' && pattern->s[len-2] == ']' && pattern->s[len-1] == ']'; } static int is_cdb(const str* filename) { const char* end = filename->s + filename->len; return filename->len > 4 && end[-4] == '.' && end[-3] == 'c' && end[-2] == 'd' && end[-1] == 'b'; } static str filename; static int extract_filename(const str* pattern) { if (!is_special(pattern)) return 0; if (pattern->s[2] == '@') str_copyb(&filename, pattern->s+3, pattern->len-5); else str_copyb(&filename, pattern->s+2, pattern->len-4); return 1; } static int try_load(struct pattern* pattern) { if (extract_filename(&pattern->pattern)) { if (is_cdb(&filename)) return (pattern->cdb = open_cdb(&filename)) != 0; else return (pattern->file = load_text(&filename)) != 0; } return 1; } static void apply_environment(const str* s) { unsigned i; unsigned len; for (i = 0; i < s->len; i += len + 1) { len = strlen(s->s + i); session_putenv(s->s + i); } } /* file parsing ************************************************************ */ static int isoctal(int ch) { return ch >= '0' && ch <= '8'; } static const char* parse_uint(const char* ptr, char sep, unsigned long* out) { for (*out = 0; *ptr != 0 && *ptr != sep; ++ptr) { if (*ptr >= '0' && *ptr <= '9') *out = (*out * 10) + (*ptr - '0'); else return 0; } return ptr; } static const char* parse_char(const char* ptr, char* out) { int o; switch (*ptr) { case 0: return ptr; case '\\': switch (*++ptr) { case 'n': *out = '\n'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': o = *ptr - '0'; if (isoctal(ptr[1])) { o = (o << 3) | (*++ptr - '0'); if (isoctal(ptr[1])) o = (o << 3) | (*++ptr - '0'); } *out = 0; break; default: *out = *ptr; } break; default: *out = *ptr; } return ptr + 1; } static const char* parse_str(const char* ptr, char sep, str* out) { char ch = 0; /* str_truncate(out, 0); */ for (;;) { if (*ptr == sep || *ptr == NUL) return ptr; ptr = parse_char(ptr, &ch); str_catc(out, ch); } return ptr; } static const char* parse_pattern(const char* ptr, char sep, struct pattern* out) { while (*ptr != sep && *ptr == '!') { out->negated = !out->negated; ++ptr; } return parse_str(ptr, sep, &out->pattern); } static void parse_env(const char* ptr, str* out) { while (ptr && *ptr != 0) if ((ptr = parse_str(ptr, ',', out)) != 0) { str_catc(out, 0); if (*ptr == ',') ++ptr; } } static const response* add(const char* l) { struct rule* r; if (*l != 'k' && *l != 'd' && *l != 'z' && *l != 'p' && *l != 'n') return 0; r = alloc_rule(); r->code = *l++; if ((l = parse_pattern(l, ':', &r->sender)) != 0 && *l == ':') if ((l = parse_pattern(l+1, ':', &r->recipient)) != 0 && *l == ':') if ((l = parse_str(l+1, ':', &r->response)) != 0 && *l == ':') if ((l = parse_uint(l+1, ':', &r->databytes)) != 0) if (*l == ':' && (l = parse_str(l+1, ':', &r->relayclient)) != 0 && *l == ':') parse_env(l+1, &r->environment); if (l == 0) return &resp_syntax; append_rule(r); /* Pre-load text files and pre-open CDB files */ if (!try_load(&r->sender)) return &resp_erropenref; if (!try_load(&r->recipient)) return &resp_erropenref; return 0; } static int loaded = 0; static const response* init(void) { const char* path; str rule = {0,0,0}; ibuf in; const response* r; if ((path = getenv("MAILRULES")) == 0) return 0; loaded = 1; if (!ibuf_open(&in, path, 0)) return &resp_erropen; while (ibuf_getstr(&in, &rule, LF)) { str_strip(&rule); if (rule.len == 0) continue; if (rule.s[0] == ':') { switch (rule.s[1]) { case 's': current_rules = &sender_rules; break; case 'r': current_rules = &recip_rules; break; default: return &resp_syntax; } } else if ((r = add(rule.s)) != 0) return r; } ibuf_close(&in); str_free(&rule); return 0; } static const response* reset(void) { if (loaded) { session_resetenv(); session_delnum("maxdatabytes"); } return 0; } /* rule application ******************************************************** */ static int matches(const struct pattern* pattern, const str* addr, const str* atdomain) { static str domain; int result; if (pattern->cdb != 0) { if (pattern->pattern.s[2] == '@') { result = (atdomain->len == 0) ? 0 : cdb_find(pattern->cdb, atdomain->s+1, atdomain->len-1) != 0; } else { result = (cdb_find(pattern->cdb, addr->s, addr->len) != 0) ? 1 : cdb_find(pattern->cdb, atdomain->s, atdomain->len) != 0; } } else if (pattern->file != 0) { if (pattern->pattern.s[2] == '@') { if (atdomain->len > 0) { str_copyb(&domain, atdomain->s+1, atdomain->len-1); result = dict_get(pattern->file, &domain) != 0; } else result = 0; } else { result = (dict_get(pattern->file, addr) != 0) ? 1 : dict_get(pattern->file, atdomain) != 0; } } else result = str_case_glob(addr, &pattern->pattern); if (pattern->negated) result = !result; return result; } static const response* build_response(int type, const str* message) { static response resp; unsigned code; const char* defmsg; switch (type) { case 'p': return 0; case 'n': return 0; case 'k': code = 250; defmsg = "OK"; break; case 'd': code = 553; defmsg = "Rejected"; break; case 'z': code = 451; defmsg = "Deferred"; break; default: code = 451; defmsg = "Temporary failure"; break; } resp.number = code; resp.message = (message->len == 0) ? defmsg : message->s; return &resp; } static const response* apply_rule(const struct rule* rule) { const response* resp; unsigned long maxdatabytes; resp = build_response(rule->code, &rule->response); apply_environment(&rule->environment); maxdatabytes = session_getnum("maxdatabytes", ~0UL); if (maxdatabytes == 0 || (rule->databytes > 0 && maxdatabytes > rule->databytes)) session_setnum("maxdatabytes", rule->databytes); return resp; } static void copy_addr(const str* addr, str* saved, str* domain) { int at; str_copy(saved, addr); str_lower(saved); if ((at = str_findlast(saved, '@')) != -1) str_copyb(domain, saved->s + at, saved->len - at); else str_truncate(domain, 0); } static str saved_sender; static str sender_domain; static const response* validate_sender(str* sender) { struct rule* rule; const response* r; if (!loaded) return 0; copy_addr(sender, &saved_sender, &sender_domain); for (rule = sender_rules; rule != 0; rule = rule->next) if (matches(&rule->sender, &saved_sender, &sender_domain)) { r = apply_rule(rule); if (rule->code != 'n') return r; } return 0; } static str laddr; static str rdomain; static const response* validate_recipient(str* recipient) { struct rule* rule; const response* r; if (!loaded) return 0; copy_addr(recipient, &laddr, &rdomain); for (rule = recip_rules; rule != 0; rule = rule->next) if (matches(&rule->sender, &saved_sender, &sender_domain) && matches(&rule->recipient, &laddr, &rdomain)) { str_cat(recipient, &rule->relayclient); r = apply_rule(rule); if (rule->code != 'n') return r; } return 0; } struct plugin plugin = { .version = PLUGIN_VERSION, .init = init, .reset = reset, .sender = validate_sender, .recipient = validate_recipient, }; mailfront-1.16/pop3.h0000664000076400007640000000105111356700500014025 0ustar bruceguenter#ifndef MAIL_FRONT__POP3__H__ #define MAIL_FRONT__POP3__H__ #include "constants.h" struct str; struct command { const char* name; void (*fn0)(void); void (*fn1)(const struct str* s); const char* sanitized; }; typedef struct command command; extern const char err_internal[]; extern const char err_unimpl[]; extern const char ok[]; extern const char err_syntax[]; extern void logmsg(const char* msg); extern void respond(const char*); extern void cmd_capa(void); extern command commands[]; extern int startup(int argc, char* argv[]); #endif mailfront-1.16/INSTHIER0000664000076400007640000000153711356700500014154 0ustar bruceguenter>bin c:::755::imapfront-auth c:::755::mailfront c:::755::pop3front-auth c:::755::pop3front-maildir c:::755::qmqpfront-echo c:::755::qmqpfront-qmail c:::755::qmtpfront-echo c:::755::qmtpfront-qmail c:::755::smtpfront-echo c:::755::smtpfront-qmail >modules c:::755::backend-echo.so c:::755::backend-qmail.so c:::755::plugin-add-received.so c:::755::plugin-check-fqdn.so c:::755::plugin-clamav.so c:::755::plugin-counters.so c:::755::plugin-cvm-validate.so c:::755::plugin-mailrules.so c:::755::plugin-patterns.so c:::755::plugin-qmail-validate.so c:::755::plugin-reject.so c:::755::plugin-relayclient.so c:::755::plugin-require-auth.so c:::755::plugin-spamassassin.so c:::755::protocol-qmqp.so c:::755::protocol-qmtp.so c:::755::protocol-smtp.so >include d:::755:mailfront c:::755:mailfront:constants.h c:::755:mailfront:mailfront.h c:::755:mailfront:responses.h mailfront-1.16/backend-echo.html0000664000076400007640000000056511356700500016175 0ustar bruceguenter

Mailfront

Backend: echo


The echo backend is a very simple module that does no delivery at all. Instead it just echos the sender, recipients, data, and the number of bytes in the message into the logs. Its primary use is for testing, when delivering a message is not necessary.

mailfront-1.16/plugin-template.c0000664000076400007640000000434611356700500016260 0ustar bruceguenter/* Prototype plugin file. * Remove any functions that are not needed. */ #include "mailfront.h" /* The init function is called once after the plugin is loaded. */ static const response* init(void) { return 0; } /* The helo function is called once by the SMTP protocol when either the * HELO or EHLO command is issued. The parameter is the hostname given * in the command. */ static const response* helo(str* hostname) { return 0; } /* The reset function is called at least once per message before any of * the envelope or data is processed. */ static const response* reset(void) { return 0; } /* The sender function is called exactly once per message. The parameter * is the sender email addres, and may be modified. */ static const response* sender(str* address) { return 0; } /* The recipient function is called one or more times per message, once * for each recipient. The parameter is the recipient email address, * and may be modified. */ static const response* recipient(str* address) { return 0; } /* The data_start function is called when the sender starts transmitting * data. Depending on the protocol, this may happen before (QMTP) or * after (SMTP) the envelope is processed. The parameter is the file * descriptor of the temporary file, or -1 if none was created. */ static const response* data_start(int fd) { return 0; } /* The data_block function is called once for each block of data * received by the protocol. If this function returns an error * response, further data blocks will be received but not processed. */ static const response* data_block(const char* bytes, unsigned long len) { } /* The message_end function is called after both the message envelope * and data have been completely transmitted. The parameter is the file * descriptor of the temporary file, or -1 if none was created. */ static const response* message_end(int fd) { return 0; } /* Plugins must export this structure. * Remove any of the entries that are not used (ie 0 or NULL). */ struct plugin plugin = { .version = PLUGIN_VERSION, .flags = 0, .init = init, .helo = helo, .reset = reset, .sender = sender, .recipient = recipient, .data_start = data_start, .data_block = data_block, .message_end = message_end, }; mailfront-1.16/mailfront.html0000664000076400007640000001070211356700500015657 0ustar bruceguenter

MailFront

POP3 Front End
IMAP Front End
Plugin API


Overview

The mailfront program acts as a driver container, loading up a protocol module, a backend module, and a list of plugins at run time. All protocols are completely interchangeable, as are the backends.

Configuration

The protocol and backend modules are specified as the first two command line arguments. The remainder of the command line arguments specify lists of plugins.

If $PLUGINS is set, it contains a list of plugins, separated by colons, that will be loaded after the plugins specified on the command line. If $MODULE_PATH is set, it specifies the directory in which modules will be loaded. Otherwise, the built in module path will be used, which is configured by editing the file conf-modules before building.

Each plugin name may be one of following three forms:

-name
The previously loaded plugin called "name" is removed from list. The special name "*" means to empty the entire list.
+name
The named plugin is loaded and placed at the front of the list.
name
The named plugin is loaded and placed at the back of the list.

Note that in both cases where a plugin is loaded, it is first removed from the list if it was previously loaded. It is not possible for the same module to be loaded multiple times.

A configuration that would match previous installations of mailfront using the qmail backend would use the following list of plugins:

check-fqdn:counters:mailrules:relayclient:cvm-validate:qmail-validate:add-received:patterns:accept-sender

The included *front-qmail shell script wrappers for the mailfront program are preconfigured to load the above list of plugins before any of their command line arguments or $PLUGINS.

Protocols

The protocol module is responsible for all interaction at the network I/O level with the client. It links into the system by calling down to the handler wrappers provided by mailfront, which in turn dispatches calls to the plugins and finally the backend. The following protocols are available:

Plugins

Plugins are used to enhance or alter the behavior of mailfront. Without any plugins loaded, mailfront does not accept any senders or recipients. Plugins may intercept and modify all aspects of a message. The following plugins are included in the main package:

Backends

The backend is the final stage in incoming mail handling, and is responsible for passing the message on to the mail system. It is invoked only if no plugin generated an error. The following backends are available:

Temporary Files

Some plugins require the use of a temporary file, either to be able to modify contents after receiving a message or to fulfill external timing requirements. These plugins are noted in their documentation above. The temporary files are created in the directory named by $TMPDIR (defaults to "/tmp").

mailfront-1.16/protocol-qmtp.html0000664000076400007640000000065411356700500016511 0ustar bruceguenter

MailFront

Protocol: qmtp


The QMTP protocol module implements the Quick Mail Transfer Protocol created by D. J. Bernstein, the creator of qmail. The protocol is designed for high speed mail transmission between MTAs.

mailfront-1.16/iobytes.c0000664000076400007640000000214111356700500014616 0ustar bruceguenter/* iobytes.c - Report the number of I/O bytes * Copyright (C) 2008 Bruce Guenter * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include void report_io_bytes(void) { static str tmp; if (str_copys(&tmp, "bytes in: ") && str_catu(&tmp, inbuf.io.offset) && str_cats(&tmp, " bytes out: ") && str_catu(&tmp, outbuf.io.offset)) msg1(tmp.s); } mailfront-1.16/plugin-spamassassin.c0000664000076400007640000001206011356700500017142 0ustar bruceguenter#include "mailfront.h" #include #include #include #include #include #include #include static RESPONSE(no_hostname,451,"4.3.0 Could not resolve SpamAssassin hostname"); static RESPONSE(no_scan,451,"4.3.0 Could not SpamAssassin scan message"); static response resp_isspam = { 554, "5.3.0 Spam detected, message refused" }; #define MAX_IPS 16 static str line; static int try_connect(const ipv4addr* ip, ipv4port port, unsigned long timeout) { int sock; if ((sock = socket_tcp()) >= 0) { if (socket_connect4_timeout(sock, ip, port, timeout)) return sock; close(sock); } return -1; } static int try_connect_unix(const char* path, unsigned long timeout) { int sock; if ((sock = socket_unixstr()) >= 0) { if (socket_connectu_timeout(sock, path, timeout)) return sock; close(sock); } return -1; } static unsigned long timeout; static unsigned long connect_timeout; static unsigned long send_timeout; static unsigned long maxsize; static const char* user; static int reject_spam; static int isspam; static int copyit(ibuf* netin, int fdout) { unsigned i; while (ibuf_getstr(netin, &line, LF)) { if (write(fdout, line.s, line.len) != line.len) return 0; if (str_case_starts(&line, "X-Spam-Status:")) { for (i = 14; i < line.len && line.s[i] == ' '; ++i) ; isspam = line.s[i] == 'Y' || line.s[i] == 'y'; break; } if (line.s[0] == LF) break; } return ibuf_copytofd(netin, fdout); } static int scanit(int fd, int fdout, int sock, const struct stat* st) { ibuf netin; obuf netout; if (ibuf_init(&netin, sock, 0, IOBUF_NEEDSCLOSE, 0)) { netin.io.timeout = timeout; if (obuf_init(&netout, sock, 0, 0, 0)) { netout.io.timeout = send_timeout; obuf_putf(&netout, "{PROCESS SPAMC/1.2\r\n}" "{Content-Length: }lu{\r\n}", st->st_size); if (user) obuf_putf(&netout, "{User: }s{\r\n}", user); obuf_puts(&netout, "\r\n"); obuf_copyfromfd(fd, &netout); if (obuf_flush(&netout)) { if (socket_shutdown(sock, 0, 1)) { if (ibuf_getstr(&netin, &line, LF)) { str_rstrip(&line); if (str_diffs(&line, "SPAMD/1.1 0 EX_OK") == 0) { while (ibuf_getstr(&netin, &line, LF)) { str_rstrip(&line); if (line.len == 0) { if (copyit(&netin, fdout)) { dup2(fdout, fd); close(fdout); obuf_close(&netout); ibuf_close(&netin); return 1; } } } } } } } obuf_close(&netout); } ibuf_close(&netin); } return 0; } static const response* message_end(int fd) { const char* hostname; const char* path; const char* tmp; ipv4port port; ipv4addr ips[MAX_IPS]; int ip_count; int i; int offset; struct timeval tv; int sock; struct stat st; int fdout; hostname = 0; if ((path = session_getenv("SPAMD_PATH")) != 0 || (hostname = session_getenv("SPAMD_HOST")) != 0) { if ((tmp = session_getenv("SPAMD_MAXSIZE")) != 0 && (maxsize = strtoul(tmp, (char**)&tmp, 10)) != 0 && *tmp == 0) { if (fstat(fd, &st) != 0) return &resp_internal; if (st.st_size > (ssize_t)maxsize){ warn1("SpamAssassin scanning skipped: message larger than maximum"); return 0; } } if ((tmp = session_getenv("SPAMD_PORT")) == 0 || (port = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) port = 783; if ((tmp = session_getenv("SPAMD_TIMEOUT")) == 0 || (timeout = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) timeout = 5000; if ((tmp = session_getenv("SPAMD_CONNECT_TIMEOUT")) == 0 || (connect_timeout = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) connect_timeout = timeout; if ((tmp = session_getenv("SPAMD_SEND_TIMEOUT")) == 0 || (send_timeout = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) send_timeout = timeout; user = session_getenv("SPAMD_USER"); if ((tmp = session_getenv("SPAMD_REJECT")) != 0) { reject_spam = 1; if (tmp[0] != 0) resp_isspam.message = tmp; } else reject_spam = 0; isspam = 0; if ((ip_count = resolve_ipv4name_n(hostname, ips, MAX_IPS)) <= 0) return &resp_no_hostname; if ((fdout = scratchfile()) == -1) return &resp_internal; if (path != 0) { if (lseek(fd, 0, SEEK_SET) != 0) return &resp_internal; if ((sock = try_connect_unix(path, connect_timeout)) >= 0) if (scanit(fd, fdout, sock, &st)) { return (reject_spam && isspam) ? &resp_isspam : 0; } } else { gettimeofday(&tv, 0); offset = (tv.tv_sec ^ tv.tv_usec) % ip_count; for (i = 0; i < ip_count; ++i) { const ipv4addr* addr = &ips[(i + offset) % ip_count]; if (lseek(fd, 0, SEEK_SET) != 0) return &resp_internal; if ((sock = try_connect(addr, port, connect_timeout)) < 0) continue; if (scanit(fd, fdout, sock, &st)) { return (reject_spam && isspam) ? &resp_isspam : 0; } } } } return &resp_no_scan; } struct plugin plugin = { .version = PLUGIN_VERSION, .flags = FLAG_NEED_FILE, .message_end = message_end, }; mailfront-1.16/warn-auto.sh0000664000076400007640000000010011356700500015236 0ustar bruceguenter#!/bin/sh # WARNING: This file was auto-generated. Do not edit! mailfront-1.16/mailfront.h0000664000076400007640000000502011356700500015137 0ustar bruceguenter#ifndef MAIL_FRONT__MAILFRONT__H__ #define MAIL_FRONT__MAILFRONT__H__ #include "responses.h" #include #include #include "constants.h" #define FLAG_NEED_FILE (1<<0) #define PLUGIN_VERSION 2 struct plugin { unsigned version; struct plugin* next; const char* name; unsigned flags; const response* (*init)(void); const response* (*helo)(str*); const response* (*reset)(void); const response* (*sender)(str*); const response* (*recipient)(str*); const response* (*data_start)(int fd); const response* (*data_block)(const char* bytes, unsigned long len); const response* (*message_end)(int fd); }; #define PROTOCOL_VERSION 2 struct protocol { unsigned version; const char* name; int (*respond_line)(unsigned number, int final, const char* msg, unsigned long len); int (*init)(void); int (*mainloop)(void); }; /* From getprotoenv.c */ extern const char* getprotoenv(const char*); /* From mailfront.c */ extern const char UNKNOWN[]; extern const response* handle_helo(str* host); extern const response* handle_init(void); extern const response* handle_reset(void); extern const response* handle_sender(str* sender); extern const response* handle_recipient(str* recip); extern const response* handle_data_start(void); extern void handle_data_bytes(const char* bytes, unsigned len); extern const response* handle_message_end(void); extern int respond(const response*); extern int respond_line(unsigned number, int final, const char* msg, unsigned long len); extern const response* backend_data_block(const char* data, unsigned long len); extern int scratchfile(void); /* From netstring.c */ int get_netstring_len(ibuf* in, unsigned long* i); int get_netstring(ibuf* in, str* s); /* From session.c */ extern const char* session_protocol(void); extern const char* session_getenv(const char* name); extern unsigned long session_getenvu(const char* name); extern int session_exportenv(void); extern int session_putenv(const char* s); extern int session_setenv(const char* name, const char* value, int overwrite); extern void session_resetenv(void); extern void session_delnum(const char* name); extern void session_delstr(const char* name); extern unsigned long session_getnum(const char* name, unsigned long dflt); extern int session_hasnum(const char* name, unsigned long* num); extern const char* session_getstr(const char* name); extern void session_setnum(const char* name, unsigned long value); extern void session_setstr(const char* name, const char* value); #endif /* MAIL_FRONT__MAILFRONT__H__ */ mailfront-1.16/plugin-require-auth.html0000664000076400007640000000104611356700500017574 0ustar bruceguenter

mailfront

Plugin: require-auth


This plugin requires that the connection be authenticated.

Configuration

$RELAYCLIENT
See below.

Sender Action

If SMTP authentication has not been completed and $RELAYCLIENT is not set, the sender is rejected. Otherwise no action.

Recipient Action

None

Data Action

None

Message Action

None

mailfront-1.16/pop3-response.c0000664000076400007640000000321211356700500015655 0ustar bruceguenter/* pop3-response.c - POP3 responses * Copyright (C) 2008 Bruce Guenter or FutureQuest, Inc. * Development of this program was sponsored by FutureQuest, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact information: * FutureQuest Inc. * PO BOX 623127 * Oviedo FL 32762-3127 USA * http://www.FutureQuest.net/ * ossi@FutureQuest.net */ #include #include #include #include #include #include #include "pop3.h" const char err_internal[] = "-ERR Internal error"; const char err_unimpl[] = "-ERR Unimplemented"; const char ok[] = "+OK "; const char err_syntax[] = "-ERR Syntax error"; void logmsg(const char* msg) { obuf_puts(&errbuf, program); obuf_putc(&errbuf, '['); obuf_putu(&errbuf, getpid()); obuf_puts(&errbuf, "]: "); obuf_puts(&errbuf, msg); obuf_putc(&errbuf, '\n'); obuf_flush(&errbuf); } void respond(const char* msg) { logmsg(msg); if (!obuf_puts(&outbuf, msg) || !obuf_putsflush(&outbuf, CRLF)) exit(1); } mailfront-1.16/COPYING0000664000076400007640000004311011356700500014030 0ustar bruceguenter GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. mailfront-1.16/constants.h0000664000076400007640000000045211356700500015164 0ustar bruceguenter#ifndef MAIL_FRONT__CONSTANTS__H__ #define MAIL_FRONT__CONSTANTS__H__ #define AT '@' #define CR ((char)13) #define LF ((char)10) #define SPACE ((char)32) #define TAB ((char)9) #define COLON ':' #define LBRACE '<' #define RBRACE '>' #define PERIOD '.' #define ESCAPE '\\' #define QUOTE '"' #endif mailfront-1.16/getprotoenv.c0000664000076400007640000000073111356700500015517 0ustar bruceguenter#include #include #include #include "mailfront.h" static const char* proto; const char* getprotoenv(const char* name) { static str fullname; const char* env; if (proto == 0) if ((proto = getenv("PROTO")) == 0) proto = "TCP"; if (name == 0 || *name == 0) return proto; if (!str_copy2s(&fullname, proto, name)) die_oom(111); if ((env = getenv(fullname.s)) != 0 && env[0] == 0) env = 0; return env; } mailfront-1.16/conf-include0000664000076400007640000000011011356700500015257 0ustar bruceguenter/usr/local/include C header files will be installed in this directory. mailfront-1.16/TODO0000664000076400007640000000242311356700500013467 0ustar bruceguenter- Fix SASL "Authentication failed" message to include EMSS code - Write install document. - Build up TLS support. - Tests: - Test application of environment variables in mail rules Plugin: clamav - Add tests (not sure how to emulate the daemon properly) Plugin: patterns - Add better MIME attachment discrimination to patterns, instead of just keying on a blank line. Plugin: mailrules - Add variable substitution to rule variable setting (ie x=${y} etc) - Allow selecting based on authentication state. Protocol: SMTP - Build a shared routine for breaking out the domain name. - When verifying senders, check if $DOMAIN(?) is set, and only allow sender addresses from that domain. - Add RFC 2034/3463 enhanced status codes to all responses. - Add support for RFC 2487 STARTTLS - Segment the SMTP code into seperate files - Add some information about authentication into the headers (?) - Handle $LOCALIPHOST (all back-ends): rewrite envelope recipient addresses of the form box@[a.b.c.d], where a.b.c.d is a local IP address, to box@$LOCALIPHOST. (low priority) - pop3front: - Properly re-parse flags in cmd_quit - Split the generic protocol handling bits from pop3front-maildir (low priority -- who wants anything but maildir?) mailfront-1.16/VERSION0000664000076400007640000000001711356700500014044 0ustar bruceguentermailfront 1.16 mailfront-1.16/timeout.c0000664000076400007640000000350111356700500014627 0ustar bruceguenter/* timeout.c - Timeout setup function * Copyright (C) 2008 Bruce Guenter or FutureQuest, Inc. * Development of this program was sponsored by FutureQuest, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact information: * FutureQuest Inc. * PO BOX 623127 * Oviedo FL 32762-3127 USA * http://www.FutureQuest.net/ * ossi@FutureQuest.net */ #include #include #include #include #include unsigned long timeout; unsigned long session_timeout; extern const int authenticating; static void handle_alarm(int unused) { exit(0); (void)unused; } void set_timeout(void) { const char* tmp; timeout = 0; if ((authenticating && (tmp = getenv("AUTH_TIMEOUT")) != 0) || (tmp = getenv("TIMEOUT")) != 0) timeout = strtoul(tmp, 0, 10); if (timeout <= 0) timeout = 1200; inbuf.io.timeout = timeout * 1000; outbuf.io.timeout = timeout * 1000; session_timeout = 0; if ((authenticating && (tmp = getenv("AUTH_SESSION_TIMEOUT")) != 0) || (tmp = getenv("SESSION_TIMEOUT")) != 0) session_timeout = strtoul(tmp, 0, 10); if (session_timeout <= 0) timeout = 86400; sig_alarm_catch(handle_alarm); alarm(session_timeout); } mailfront-1.16/qmtpfront-echo.sh0000664000076400007640000000005611356700500016301 0ustar bruceguenterexec "$(dirname $0)"/mailfront qmtp echo "$@" mailfront-1.16/pop3-capa.c0000664000076400007640000000305211356700500014725 0ustar bruceguenter/* pop3-capa.c -- POP3 CAPA command * Copyright (C) 2008 Bruce Guenter or FutureQuest, Inc. * Development of this program was sponsored by FutureQuest, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact information: * FutureQuest Inc. * PO BOX 623127 * Oviedo FL 32762-3127 USA * http://www.FutureQuest.net/ * ossi@FutureQuest.net */ #include #include #include #include #include "pop3.h" static const char caps[] = "PIPELINING\r\n" "TOP\r\n" "UIDL\r\n" "USER\r\n"; static str auth_resp; void cmd_capa(void) { int sasl; if ((sasl = sasl_auth_caps(&auth_resp)) == -1 || (sasl == 1 && auth_resp.len <= 5)) { respond(err_internal); return; } respond(ok); if (sasl) { obuf_puts(&outbuf, "SASL "); obuf_write(&outbuf, auth_resp.s + 5, auth_resp.len - 5); obuf_puts(&outbuf, CRLF); } obuf_puts(&outbuf, caps); respond("."); } mailfront-1.16/plugin-clamav.c0000664000076400007640000000723511356700500015710 0ustar bruceguenter#include "mailfront.h" #include #include #include #include #include #include #include static RESPONSE(no_hostname,451,"4.3.0 Could not resolve virus scanner hostname"); static RESPONSE(no_scan,451,"4.3.0 Could not virus scan message"); static response resp_virus = { 554, 0 }; #define MAX_IPS 16 static str line; static int try_connect(const ipv4addr* ip, ipv4port port, unsigned long timeout) { int sock; if ((sock = socket_tcp()) >= 0) { if (socket_connect4_timeout(sock, ip, port, timeout)) return sock; close(sock); } return -1; } static const response* message_end(int fd) { const char* hostname; const char* tmp; ipv4port cmdport; ipv4port dataport; ipv4addr ips[MAX_IPS]; int ip_count; int i; int offset; struct timeval tv; int sock; unsigned long timeout; unsigned long connect_timeout; unsigned long send_timeout; unsigned long maxsize; ibuf netin; obuf netout; struct stat st; if ((hostname = session_getenv("CLAMAV_HOST")) != 0 || (hostname = session_getenv("CLAMD_HOST")) != 0) { if ((tmp = session_getenv("CLAMAV_MAXSIZE")) != 0 && (maxsize = strtoul(tmp, (char**)&tmp, 10)) != 0 && *tmp == 0) { if (fstat(fd, &st) != 0) return &resp_internal; if (st.st_size > (ssize_t)maxsize){ warn1("ClamAV scanning skipped: message larger than maximum"); return 0; } } if (((tmp = session_getenv("CLAMAV_PORT")) == 0 && (tmp = session_getenv("CLAMD_PORT")) == 0) || (cmdport = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) cmdport = 3310; if (((tmp = session_getenv("CLAMAV_TIMEOUT")) == 0 && (tmp = session_getenv("CLAMD_TIMEOUT")) == 0) || (timeout = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) timeout = 5000; if ((tmp = session_getenv("CLAMAV_CONNECT_TIMEOUT")) == 0 || (connect_timeout = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) connect_timeout = timeout; if ((tmp = session_getenv("CLAMAV_SEND_TIMEOUT")) == 0 || (send_timeout = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) send_timeout = timeout; if ((ip_count = resolve_ipv4name_n(hostname, ips, MAX_IPS)) <= 0) return &resp_no_hostname; gettimeofday(&tv, 0); offset = (tv.tv_sec ^ tv.tv_usec) % ip_count; for (i = 0; i < ip_count; ++i) { const ipv4addr* addr = &ips[(i + offset) % ip_count]; if (lseek(fd, 0, SEEK_SET) != 0) return &resp_internal; if ((sock = try_connect(addr, cmdport, connect_timeout)) < 0) continue; if (ibuf_init(&netin, sock, 0, IOBUF_NEEDSCLOSE, 0)) { netin.io.timeout = timeout; if (write(sock, "STREAM\n", 7) == 7 && ibuf_getstr(&netin, &line, LF) && memcmp(line.s, "PORT ", 5) == 0 && (dataport = strtoul(line.s+5, 0, 10)) > 0) { if ((sock = try_connect(addr, dataport, connect_timeout)) >= 0) { if (obuf_init(&netout, sock, 0, IOBUF_NEEDSCLOSE, 0)) { netout.io.timeout = send_timeout; if (obuf_copyfromfd(fd, &netout) && obuf_close(&netout) && ibuf_getstr(&netin, &line, LF)) { ibuf_close(&netin); if (memcmp(line.s, "stream: ", 8) == 0) { str_lcut(&line, 8); str_rstrip(&line); if (str_diffs(&line, "OK") == 0) return 0; str_splices(&line, 0, 0, "5.7.0 Virus scan failed: "); resp_virus.message = line.s; return &resp_virus; } } obuf_close(&netout); } if (sock >= 0) close(sock); } } ibuf_close(&netin); } if (sock >= 0) close(sock); } } return &resp_no_scan; } struct plugin plugin = { .version = PLUGIN_VERSION, .flags = FLAG_NEED_FILE, .message_end = message_end, }; mailfront-1.16/plugin-clamav.html0000664000076400007640000000452011356700500016424 0ustar bruceguenter

mailfront

Plugin: clamav


This plugin scans messages against a ClamAV server. If the message data is detected as having a virus, the message is rejected, and the error response contains the virus name as detected by ClamAV. This scanner only operates over TCP/IP sockets (either remotely or locally).

Note: This plugin causes mailfront to save messages to temporary files.

Configuration

$CLAMAV_CONNECT_TIMEOUT
The maximum amount of time to wait for a response when connecting to a ClamAV scanner, in milliseconds. (defaults to $CLAMAV_TIMEOUT below)
$CLAMAV_MAXSIZE
The maximum message size to be scanned, in bytes. This limit is useful for avoiding overloading the scanning system(s). If the incoming message is larger than this threshold, a warning is printed and no scanning is done. If unset or set to "0", there is no limit.
$CLAMAV_HOST
The hostname of the ClamAV scanner. If this name resolves to multiple IP addresses, all of them are tried in sequence (starting at a random point) until one scans the message.
$CLAMAV_PORT
Use this TCP port number for the command/response data. (defaults to 3310)
$CLAMAV_SEND_TIMEOUT
The maximum amount of time to wait for the output buffer to clear when sending data to a ClamAV scanner, in milliseconds. (defaults to $CLAMAV_TIMEOUT below)
$CLAMAV_TIMEOUT
The maximum amount of time to wait for a response from the ClamAV scanner, in milliseconds. (defaults to 5000)
$CLAMD_HOST
Sets the scanner host address if $CLAMAV_HOST is unset.
$CLAMD_PORT
Sets the scanner port address if $CLAMAV_PORT is unset.
$CLAMD_TIMEOUT
Sets the timeout value if $CLAMAV_TIMEOUT is unset.

Sender Action

None

Recipient Action

None

Data Action

None

Message Action

The message is scanned when all the data has been completely transmitted (to prevent timeout issues with sending data to the ClamAV server).

mailfront-1.16/plugin-qmail-validate.c0000664000076400007640000000463611356700500017341 0ustar bruceguenter#include #include "mailfront.h" #include #include #include #include "conf_qmail.c" #include static RESPONSE(accept,250,0); static RESPONSE(no_chdir,451,"4.3.0 Could not change to the qmail directory."); static RESPONSE(badmailfrom,553,"5.1.0 Sorry, your envelope sender is in my badmailfrom list."); static RESPONSE(bmt,553,"5.1.1 Sorry, that address is in my badrcptto list."); static dict bmf; static dict rh; static dict brt; static str tmp; static int mrh_fd; static struct cdb mrh; static int lower(str* s) { str_lower(s); return 1; } static const response* validate_init(void) { const char* qh; if ((qh = getenv("QMAILHOME")) == 0) qh = conf_qmail; if (chdir(qh) == -1) return &resp_no_chdir; if (!dict_load_list(&bmf, "control/badmailfrom", 0, lower)) return &resp_internal; if (!dict_load_list(&rh, "control/rcpthosts", 0, lower)) return &resp_internal; if (!dict_load_list(&brt, "control/badrcptto", 0, lower)) return &resp_internal; if ((mrh_fd = open("control/morercpthosts.cdb", O_RDONLY)) != -1) cdb_init(&mrh, mrh_fd); return 0; } static const response* validate_sender(str* sender) { int at; str_copy(&tmp, sender); str_lower(&tmp); if (dict_get(&bmf, &tmp) != 0) return &resp_badmailfrom; if ((at = str_findlast(sender, '@')) > 0) { str_copyb(&tmp, sender->s + at, sender->len - at); str_lower(&tmp); if (dict_get(&bmf, &tmp)) return &resp_badmailfrom; } return 0; } static const response* validate_recipient(str* recipient) { int at; str_copy(&tmp, recipient); str_lower(&tmp); if (dict_get(&brt, &tmp) != 0) return &resp_bmt; if ((at = str_findlast(recipient, '@')) > 0) { str_copyb(&tmp, recipient->s + at, recipient->len - at); str_lower(&tmp); if (dict_get(&brt, &tmp)) return &resp_bmt; ++at; str_copyb(&tmp, recipient->s + at, recipient->len - at); str_lower(&tmp); for (;;) { if (dict_get(&rh, &tmp)) return &resp_accept; /* NOTE: qmail-newmrh automatically lowercases the keys in this CDB */ if (mrh_fd != -1 && cdb_find(&mrh, tmp.s, tmp.len) == 1) return &resp_accept; if ((at = str_findnext(&tmp, '.', 1)) <= 0) break; str_lcut(&tmp, at); } } return 0; } struct plugin plugin = { .version = PLUGIN_VERSION, .init = validate_init, .sender = validate_sender, .recipient = validate_recipient, }; mailfront-1.16/plugin-check-fqdn.c0000664000076400007640000000154411356700500016445 0ustar bruceguenter#include "mailfront.h" static RESPONSE(nodomain,554,"5.1.2 Address is missing a domain name"); static RESPONSE(nofqdn,554,"5.1.2 Address does not contain a fully qualified domain name"); static const response* either(str* s) { int at; int dot; const char* name; if (s->len > 0) { if ((at = str_findlast(s, '@')) <= 0) { if ((name = session_getenv("DEFAULTHOST")) != 0) { at = s->len; if (!str_catc(s, '@') || !str_cats(s, name)) return &resp_oom; } else return &resp_nodomain; } if ((dot = str_findlast(s, '.')) < at) { if ((name = session_getenv("DEFAULTDOMAIN")) != 0) { if (!str_catc(s, '.') || !str_cats(s, name)) return &resp_oom; } else return &resp_nofqdn; } } return 0; } struct plugin plugin = { .version = PLUGIN_VERSION, .sender = either, .recipient = either, }; mailfront-1.16/protocol-smtp.c0000664000076400007640000002415311356700500015771 0ustar bruceguenter#include #include #include #include "mailfront.h" #include #include #include #include #include extern struct protocol protocol; static RESPONSE(authfail, 421, "4.3.0 Failed to initialize AUTH"); static str line = {0,0,0}; static str domain_name = {0,0,0}; static struct sasl_auth saslauth = { .prefix = "334 " }; static unsigned long maxnotimpl = 0; static str str_welcome; static str cmd; static str arg; static str addr; static str params; static RESPONSE(no_mail, 503, "5.5.1 You must send MAIL FROM: first"); static RESPONSE(vrfy, 252, "2.5.2 Send some mail, I'll try my best."); static RESPONSE(help, 214, "2.0.0 Help not available."); static RESPONSE(mail_ok, 250, "2.1.0 Sender accepted."); static RESPONSE(rcpt_ok, 250, "2.1.5 Recipient accepted."); static RESPONSE(no_rcpt, 503, "5.5.1 You must send RCPT TO: first"); static RESPONSE(data_ok, 354, "End your message with a period on a line by itself."); static RESPONSE(ok, 250, "2.3.0 OK"); static RESPONSE(unimp, 500, "5.5.1 Not implemented."); static RESPONSE(needsparam, 501, "5.5.2 That command requires a parameter."); static RESPONSE(auth_already, 503, "5.5.1 You are already authenticated."); static RESPONSE(toobig, 552, "5.2.3 The message would exceed the maximum message size."); static RESPONSE(toomanyunimp, 503, "5.5.0 Too many unimplemented commands.\n5.5.0 Closing connection."); static RESPONSE(goodbye, 221, "2.0.0 Good bye."); static RESPONSE(authenticated, 235, "2.7.0 Authentication succeeded."); static RESPONSE(ehlo, 250, "8BITMIME\nENHANCEDSTATUSCODES\nPIPELINING"); static int saw_mail = 0; static int saw_rcpt = 0; static int parse_addr_arg(void) { unsigned i; char term; int quoted; if (!str_truncate(&addr, 0)) return 0; if (!str_truncate(¶ms, 0)) return 0; addr.len = 0; if ((i = str_findfirst(&arg, LBRACE) + 1) != 0) term = RBRACE; else { term = SPACE; if ((i = str_findfirst(&arg, COLON) + 1) == 0) if ((i = str_findfirst(&arg, SPACE) + 1) == 0) return 0; while (i < arg.len && arg.s[i] == SPACE) ++i; } for (quoted = 0; i < arg.len && (quoted || arg.s[i] != term); ++i) { switch (arg.s[i]) { case QUOTE: quoted = !quoted; break; case ESCAPE: ++i; /* fall through */ default: if (!str_catc(&addr, arg.s[i])) return 0; } } ++i; while (i < arg.len && arg.s[i] == SPACE) ++i; if (!str_copyb(¶ms, arg.s+i, arg.len-i)) return 0; str_subst(¶ms, ' ', 0); /* strip source routing */ if (addr.s[0] == AT && (i = str_findfirst(&addr, COLON) + 1) != 0) str_lcut(&addr, i); return 1; } static const char* find_param(const char* name) { const long len = strlen(name); striter i; for (striter_start(&i, ¶ms, 0); striter_valid(&i); striter_advance(&i)) { if (strncasecmp(i.startptr, name, len) == 0) { if (i.startptr[len] == '0') return i.startptr + len; if (i.startptr[len] == '=') return i.startptr + len + 1; } } return 0; } static int QUIT(void) { respond(&resp_goodbye); exit(0); return 0; } static int HELP(void) { return respond(&resp_help); } static int HELO(void) { const response* resp; if ((resp = handle_reset()) != 0 || (resp = handle_helo(&arg)) != 0) return respond(resp); return respond_line(250, 1, domain_name.s, domain_name.len); } static int EHLO(void) { static str auth_resp; const response* resp; protocol.name = "ESMTP"; if ((resp = handle_reset()) != 0 || (resp = handle_helo(&arg)) != 0) return respond(resp); if (!respond_line(250, 0, domain_name.s, domain_name.len)) return 0; switch (sasl_auth_caps(&auth_resp)) { case 0: break; case 1: if (!respond_line(250, 0, auth_resp.s, auth_resp.len)) return 0; break; default: return respond(&resp_internal); } if (!str_copys(&line, "SIZE ")) return 0; if (!str_catu(&line, session_getnum("maxdatabytes", 0))) return 0; if (!respond_line(250, 0, line.s, line.len)) return 0; return respond(&resp_ehlo); } static void do_reset(void) { const response* resp; if ((resp = handle_reset()) != 0) { respond(resp); exit(0); } saw_rcpt = 0; saw_mail = 0; } // FIXME: if rules_reset fails, exit static int MAIL(void) { const response* resp; const char* param; unsigned long size; unsigned long maxdatabytes; msg2("MAIL ", arg.s); do_reset(); parse_addr_arg(); if ((resp = handle_sender(&addr)) == 0) resp = &resp_mail_ok; if (number_ok(resp)) { /* Look up the size limit after handling the sender, in order to honour limits set in the mail rules. */ maxdatabytes = session_getnum("maxdatabytes", ~0UL); if ((param = find_param("SIZE")) != 0 && (size = strtoul(param, (char**)¶m, 10)) > 0 && *param == 0 && size > maxdatabytes) return respond(&resp_toobig); saw_mail = 1; } return respond(resp); } static int RCPT(void) { const response* resp; msg2("RCPT ", arg.s); if (!saw_mail) return respond(&resp_no_mail); parse_addr_arg(); if ((resp = handle_recipient(&addr)) == 0) resp = &resp_rcpt_ok; if (number_ok(resp)) saw_rcpt = 1; return respond(resp); } static int RSET(void) { do_reset(); return respond(&resp_ok); } static char data_buf[4096]; static unsigned long data_bytes; static unsigned data_bufpos; static void data_start(void) { data_bytes = data_bufpos = 0; } static void data_byte(char ch) { data_buf[data_bufpos++] = ch; ++data_bytes; if (data_bufpos >= sizeof data_buf) { handle_data_bytes(data_buf, data_bufpos); data_bufpos = 0; } } static void message_end(void) { if (data_bufpos) handle_data_bytes(data_buf, data_bufpos); } static int copy_body(void) { int sawcr = 0; /* Was the last character a CR */ unsigned linepos = 0; /* The number of bytes since the last LF */ int sawperiod = 0; /* True if the first character was a period */ char ch; data_start(); while (ibuf_getc(&inbuf, &ch)) { switch (ch) { case LF: if (sawperiod && linepos == 0) { message_end(); return 1; } data_byte(ch); sawperiod = sawcr = linepos = 0; break; case CR: if (sawcr) { data_byte(CR); ++linepos; } sawcr = 1; break; default: if (ch == PERIOD && !sawperiod && linepos == 0) sawperiod = 1; else { sawperiod = 0; if (sawcr) { data_byte(CR); ++linepos; sawcr = 0; } data_byte(ch); ++linepos; } } } return 0; } static int DATA(void) { const response* resp; if (!saw_mail) return respond(&resp_no_mail); if (!saw_rcpt) return respond(&resp_no_rcpt); if ((resp = handle_data_start()) != 0) return respond(resp); if (!respond(&resp_data_ok)) return 0; if (!copy_body()) { do_reset(); return 0; } if ((resp = handle_message_end()) == 0) resp = &resp_accepted; return respond(resp); } static int NOOP(void) { return respond(&resp_ok); } static int VRFY(void) { return respond(&resp_vrfy); } static int AUTH(void) { int i; if (session_getnum("authenticated", 0)) return respond(&resp_auth_already); if (arg.len == 0) return respond(&resp_needsparam); if ((i = sasl_auth1(&saslauth, &arg)) != 0) { const char* msg = sasl_auth_msg(&i); return respond_line(i, 1, msg, strlen(msg)); } else { session_setnum("authenticated", 1); session_delstr("helo_domain"); session_setstr("auth_user", cvm_fact_username); session_setnum("auth_uid", cvm_fact_userid); session_setnum("auth_gid", cvm_fact_groupid); if (cvm_fact_realname != 0) session_setstr("auth_realname", cvm_fact_realname); if (cvm_fact_domain != 0) session_setstr("auth_domain", cvm_fact_domain); if (cvm_fact_mailbox != 0) session_setstr("auth_mailbox", cvm_fact_mailbox); respond(&resp_authenticated); } return 1; } typedef int (*dispatch_fn)(void); struct dispatch { const char* cmd; dispatch_fn fn; }; static struct dispatch dispatch_table[] = { { "DATA", DATA }, { "EHLO", EHLO }, { "HELO", HELO }, { "HELP", HELP }, { "MAIL", MAIL }, { "NOOP", NOOP }, { "QUIT", QUIT }, { "RCPT", RCPT }, { "RSET", RSET }, { "VRFY", VRFY }, { "AUTH", AUTH }, { 0, 0 } }; static int parse_line(void) { unsigned i; for (i = 0; i < line.len; i++) { if (line.s[i] == SPACE || line.s[i] == TAB) { unsigned j = i; while (j < line.len && (line.s[j] == SPACE || line.s[j] == TAB)) ++j; return str_copyb(&cmd, line.s, i) && str_copyb(&arg, line.s+j, line.len-j); } } return str_copy(&cmd, &line) && str_truncate(&arg, 0); } int smtp_dispatch(void) { static unsigned long notimpl = 0; struct dispatch* d; if (!parse_line()) return 1; for (d = dispatch_table; d->cmd != 0; ++d) if (strcasecmp(d->cmd, cmd.s) == 0) { notimpl = 0; return d->fn(); } msg3(cmd.s, " ", arg.s); if (maxnotimpl > 0 && ++notimpl > maxnotimpl) { respond(&resp_toomanyunimp); return 0; } return respond(&resp_unimp); } static int init(void) { const char* tmp; if ((tmp = getprotoenv("LOCALHOST")) == 0) tmp = UNKNOWN; str_copys(&domain_name, tmp); if ((tmp = getenv("SMTPGREETING")) != 0) str_copys(&str_welcome, tmp); else { str_copy(&str_welcome, &domain_name); str_cats(&str_welcome, " mailfront"); } str_cats(&str_welcome, " ESMTP"); if ((tmp = getenv("MAXNOTIMPL")) != 0) maxnotimpl = strtoul(tmp, 0, 10); return 0; } static int mainloop(void) { if (!sasl_auth_init(&saslauth)) return respond(&resp_authfail); if (!respond_line(220, 1, str_welcome.s, str_welcome.len)) return 0; while (ibuf_getstr_crlf(&inbuf, &line)) if (!smtp_dispatch()) { if (ibuf_eof(&inbuf)) msg1("Connection dropped"); if (ibuf_timedout(&inbuf)) msg1("Timed out"); return 1; } return 0; } static int smtp_respond_line(unsigned num, int final, const char* msg, unsigned long len) { return obuf_putu(&outbuf, num) && obuf_putc(&outbuf, final ? ' ' : '-') && obuf_write(&outbuf, msg, len) && obuf_puts(&outbuf, CRLF); } struct protocol protocol = { .version = PROTOCOL_VERSION, .name = "SMTP", .respond_line = smtp_respond_line, .init = init, .mainloop = mainloop, }; mailfront-1.16/qmqpfront-echo.sh0000664000076400007640000000005611356700500016276 0ustar bruceguenterexec "$(dirname $0)"/mailfront qmqp echo "$@" mailfront-1.16/smtpfront-qmail.sh0000664000076400007640000000023111356700500016463 0ustar bruceguenterexec "$(dirname $0)"/mailfront smtp qmail check-fqdn counters mailrules relayclient cvm-validate qmail-validate add-received patterns accept-sender "$@" mailfront-1.16/Makefile0000664000076400007640000002030511356700500014436 0ustar bruceguenter# Don't edit Makefile! Use conf-* for configuration. # # Generated by spac see http://untroubled.org/spac/ SHELL=/bin/sh DEFAULT: all all: libraries programs docs backend-echo.so: makeso backend-echo.c mailfront.h responses.h constants.h ./makeso backend-echo.c -lbg -lbg-sysdeps backend-qmail.so: makeso backend-qmail.c mailfront.h responses.h constants.h conf_qmail.c ./makeso backend-qmail.c -lbg -lbg-sysdeps builtins.o: compile builtins.c mailfront-internal.h mailfront.h responses.h constants.h ./compile builtins.c clean: TARGETS rm -f `cat TARGETS` clean-spac: clean AUTOFILES rm -f `cat AUTOFILES` compile: conf-cc conf-bgincs ( bgincs=`head -n 1 conf-bgincs`; \ echo '#!/bin/sh'; \ echo 'source=$$1; shift'; \ echo 'base=`echo "$$source" | sed -e s:\\\\.c$$::`'; \ echo exec `head -n 1 conf-cc` -I. "-I'$${bgincs}'" '-o $${base}.o -c $$source $${1+"$$@"}'; \ ) >compile chmod 755 compile conf_modules.c: conf-modules head -n 1 conf-modules | \ sed -e 's/"/\\"/g' \ -e 's/^/const char conf_modules[] = "/' \ -e 's/$$/";/' >conf_modules.c conf_qmail.c: conf-qmail head -n 1 conf-qmail | \ sed -e 's/"/\\"/g' \ -e 's/^/const char conf_qmail[] = "/' \ -e 's/$$/";/' >conf_qmail.c dl.lib: compile load @echo -n 'Checking for -ldl: ' @echo 'main() { ; }' >trylib-ldl.c @{ ./compile trylib-ldl.c && ./load trylib-ldl -ldl; } >/dev/null 2>&1 \ && { echo -ldl >dl.lib; echo yes; } \ || { echo -n >dl.lib; echo no; } @rm -f trylib-ldl.c trylib-ldl.o trylib-ldl docs: getprotoenv.o: compile getprotoenv.c mailfront.h responses.h constants.h ./compile getprotoenv.c imapfront-auth: imapfront-auth.o load timeout.o socket.lib ./load imapfront-auth timeout.o -lcvm-sasl -lcvm-v2client -lbg `cat socket.lib` imapfront-auth.o: compile imapfront-auth.c ./compile imapfront-auth.c install: INSTHIER conf-bin conf-modules conf-include bg-installer -v load chmod 755 load mailfront: mailfront.o load builtins.o getprotoenv.o iobytes.o modules.o responses.o session.o timeout.o socket.lib dl.lib ./load mailfront builtins.o getprotoenv.o iobytes.o modules.o responses.o session.o timeout.o -lbg -rdynamic `cat socket.lib` `cat dl.lib` mailfront.o: compile mailfront.c mailfront-internal.h mailfront.h responses.h constants.h ./compile mailfront.c makelib: ( echo '#!/bin/sh'; \ echo 'lib="$$1"; shift';\ echo 'rm -f "$$lib"';\ echo 'ar cr "$$lib" $${1+"$$@"}';\ echo 'ranlib "$$lib"';\ ) >makelib chmod 755 makelib makeso: conf-ccso conf-ld conf-bgincs conf-bglibs ( bgincs=`head -n 1 conf-bgincs`; \ bglibs=`head -n 1 conf-bglibs`; \ echo '#!/bin/sh'; \ echo 'source=$$1; shift'; \ echo 'base=`echo "$$source" | sed -e s:\\\\.c$$::`'; \ echo exec `head -n 1 conf-ccso` -DSHARED -I. "-I'$${bgincs}'" -L. "-L'$${bglibs}'" '-o $${base}.so $$source $${1+"$$@"}'; \ ) >makeso chmod 755 makeso modules.o: compile modules.c mailfront-internal.h mailfront.h responses.h constants.h conf_modules.c ./compile modules.c plugin-add-received.so: makeso plugin-add-received.c mailfront.h responses.h constants.h ./makeso plugin-add-received.c -lbg -lbg-sysdeps plugin-check-fqdn.so: makeso plugin-check-fqdn.c mailfront.h responses.h constants.h ./makeso plugin-check-fqdn.c -lbg -lbg-sysdeps plugin-clamav.so: makeso plugin-clamav.c mailfront.h responses.h constants.h ./makeso plugin-clamav.c -lbg -lbg-sysdeps plugin-counters.so: makeso plugin-counters.c mailfront.h responses.h constants.h ./makeso plugin-counters.c -lbg -lbg-sysdeps plugin-cvm-validate.so: makeso plugin-cvm-validate.c mailfront.h responses.h constants.h ./makeso plugin-cvm-validate.c -lcvm-v2client -lbg -lbg-sysdeps plugin-force-file.so: makeso plugin-force-file.c mailfront.h responses.h constants.h ./makeso plugin-force-file.c plugin-mailrules.so: makeso plugin-mailrules.c mailfront.h responses.h constants.h ./makeso plugin-mailrules.c -lbg -lbg-sysdeps plugin-patterns.so: makeso plugin-patterns.c mailfront.h responses.h constants.h ./makeso plugin-patterns.c -lbg -lbg-sysdeps plugin-qmail-validate.so: makeso plugin-qmail-validate.c mailfront.h responses.h constants.h conf_qmail.c ./makeso plugin-qmail-validate.c -lbg -lbg-sysdeps plugin-reject.so: makeso plugin-reject.c mailfront.h responses.h constants.h ./makeso plugin-reject.c plugin-relayclient.so: makeso plugin-relayclient.c mailfront.h responses.h constants.h ./makeso plugin-relayclient.c -lbg -lbg-sysdeps plugin-require-auth.so: makeso plugin-require-auth.c mailfront.h responses.h constants.h ./makeso plugin-require-auth.c plugin-spamassassin.so: makeso plugin-spamassassin.c mailfront.h responses.h constants.h ./makeso plugin-spamassassin.c -lbg -lbg-sysdeps pop3-capa.o: compile pop3-capa.c pop3.h constants.h ./compile pop3-capa.c pop3-mainloop.o: compile pop3-mainloop.c pop3.h constants.h ./compile pop3-mainloop.c pop3-response.o: compile pop3-response.c pop3.h constants.h ./compile pop3-response.c pop3.a: makelib iobytes.o timeout.o pop3-capa.o pop3-mainloop.o pop3-response.o ./makelib pop3.a iobytes.o timeout.o pop3-capa.o pop3-mainloop.o pop3-response.o pop3front-auth: pop3front-auth.o load pop3.a socket.lib ./load pop3front-auth pop3.a -lcvm-sasl -lcvm-v2client -lbg `cat socket.lib` pop3front-auth.o: compile pop3front-auth.c pop3.h constants.h ./compile pop3front-auth.c pop3front-maildir: pop3front-maildir.o load pop3.a ./load pop3front-maildir pop3.a -lbg -lcvm-sasl -lcvm-v2client pop3front-maildir.o: compile pop3front-maildir.c pop3.h constants.h ./compile pop3front-maildir.c programs: mailfront pop3front-auth imapfront-auth pop3front-maildir qmtpfront-echo qmtpfront-qmail smtpfront-echo smtpfront-qmail qmqpfront-qmail qmqpfront-echo protocol-qmqp.so: makeso protocol-qmqp.c mailfront.h responses.h constants.h qmtp.h qmtp-respond.c netstring.c ./makeso protocol-qmqp.c qmtp-respond.c netstring.c -lbg -lbg-sysdeps protocol-qmtp.so: makeso protocol-qmtp.c mailfront.h responses.h constants.h qmtp.h qmtp-respond.c netstring.c ./makeso protocol-qmtp.c qmtp-respond.c netstring.c -lbg -lbg-sysdeps protocol-smtp.so: makeso protocol-smtp.c mailfront.h responses.h constants.h ./makeso protocol-smtp.c -lcvm-sasl -lcvm-v2client -lbg -lbg-sysdeps qmqpfront-echo: warn-auto.sh qmqpfront-echo.sh cat warn-auto.sh qmqpfront-echo.sh >qmqpfront-echo chmod 755 qmqpfront-echo qmqpfront-qmail: warn-auto.sh qmqpfront-qmail.sh cat warn-auto.sh qmqpfront-qmail.sh >qmqpfront-qmail chmod 755 qmqpfront-qmail qmtpfront-echo: warn-auto.sh qmtpfront-echo.sh cat warn-auto.sh qmtpfront-echo.sh >qmtpfront-echo chmod 755 qmtpfront-echo qmtpfront-qmail: warn-auto.sh qmtpfront-qmail.sh cat warn-auto.sh qmtpfront-qmail.sh >qmtpfront-qmail chmod 755 qmtpfront-qmail responses.o: compile responses.c responses.h ./compile responses.c session.o: compile session.c mailfront-internal.h mailfront.h responses.h constants.h ./compile session.c smtpfront-echo: warn-auto.sh smtpfront-echo.sh cat warn-auto.sh smtpfront-echo.sh >smtpfront-echo chmod 755 smtpfront-echo smtpfront-qmail: warn-auto.sh smtpfront-qmail.sh cat warn-auto.sh smtpfront-qmail.sh >smtpfront-qmail chmod 755 smtpfront-qmail socket.lib: compile load @echo -n 'Checking for socket libraries: ' @echo 'main() { ; }' >trylib-lsocket.c @{ ./compile trylib-lsocket.c && ./load trylib-lsocket -lsocket -lnsl; } >/dev/null 2>&1 \ && { echo -lsocket -lnsl >socket.lib; echo -lsocket -lnsl; } \ || { : >socket.lib; echo no; } @rm -f trylib-lsocket.c trylib-lsocket.o trylib-lsocket timeout.o: compile timeout.c ./compile timeout.c mailfront-1.16/AUTOFILES0000664000076400007640000000020411356700500014250 0ustar bruceguenterAUTOFILES Makefile SRCFILES TARGETS conf-bgincs conf-bglibs conf-bin conf-cc conf-ccso conf-include conf-ld conf-qmail warn-auto.sh mailfront-1.16/plugin-cvm-validate.html0000664000076400007640000000156711356700500017545 0ustar bruceguenter

mailfront

Plugin: cvm-validate


This plugin uses a CVM to validate recipient addresses.

Configuration

$CVM_LOOKUP
The name of the CVM to invoke
$CVM_LOOKUP_SECRET
The secret to pass to the CVM (defaults to the value of $LOOKUP_SECRET)
$LOOKUP_SECRET
The secret to pass to the CVM

Sender Action

None

Recipient Action

Calls the given CVM, passing the recipient address as the account and domain name along with the lookup secret. If the CVM rejects the recipient, the plugin rejects the recipient. Otherwise no action.

Data Action

None

Message Action

None

mailfront-1.16/modules.c0000664000076400007640000000763211356700500014622 0ustar bruceguenter#include #include #include #include #include "mailfront-internal.h" #include "conf_modules.c" static response resp_load = { 451, 0 }; static RESPONSE(backend_version,451,"4.3.0 Backend ABI version mismatch"); static RESPONSE(plugin_version,451,"4.3.0 Plugin ABI version mismatch"); static RESPONSE(protocol_version,451,"4.3.0 Protocol ABI version mismatch"); static void append_plugin(struct plugin* plugin) { plugin->next = 0; if (session.plugin_tail == 0) session.plugin_list = plugin; else session.plugin_tail->next = plugin; session.plugin_tail = plugin; } static void prepend_plugin(struct plugin* plugin) { plugin->next = session.plugin_list; session.plugin_list = plugin; if (session.plugin_tail == 0) session.plugin_tail = plugin; } static struct plugin* remove_plugin(const char* name) { struct plugin* curr; struct plugin* prev; if (name[0] == '*' && name[1] == 0) session.plugin_list = session.plugin_tail = 0; else { for (prev = 0, curr = session.plugin_list; curr != 0; prev = curr, curr = curr->next) { if (strcmp(curr->name, name) == 0) { if (((prev == 0) ? (session.plugin_list = curr->next) : (prev->next = curr->next)) == 0) session.plugin_tail = prev; return curr; } } } return 0; } static void* load_object(const char* type, const char* name) { static str tmpstr; void* handle; void* ptr; str_copyf(&tmpstr, "s{/}s{-}s{.so}", session.module_path, type, name); if ((handle = dlopen(tmpstr.s, RTLD_NOW | RTLD_LOCAL)) == 0 || (ptr = dlsym(handle, type)) == 0) { str_copyf(&tmpstr, "{4.3.0 Error loading }s{ }s{: }s", type, name, dlerror()); resp_load.message = tmpstr.s; return 0; } return ptr; } static struct plugin* find_builtin_plugin(const char* name) { int i; for (i = 0; builtin_plugins[i].name != 0; ++i) { if (strcmp(builtin_plugins[i].name, name) == 0) return &builtin_plugins[i]; } return 0; } static const response* load_plugin(const char* name) { struct plugin* plugin; void (*add)(struct plugin*); if (name[0] == '-') { remove_plugin(++name); return 0; } if (name[0] == '+') { ++name; add = prepend_plugin; } else add = append_plugin; if ((plugin = remove_plugin(name)) == 0) { if ((plugin = find_builtin_plugin(name)) == 0) { if ((plugin = load_object("plugin", name)) == 0) return &resp_load; if (plugin->version != PLUGIN_VERSION) return &resp_plugin_version; if ((plugin->name = strdup(name)) == 0) return &resp_oom; } } add(plugin); session.flags |= plugin->flags; return 0; } static const response* load_plugins(const char* list) { const char* start; const char* end; long len; const response* resp; for (start = list; *start != 0; start = end) { end = start; while (*end != 0 && *end != ':') ++end; len = end - start; if (len > 0) { char copy[len+1]; memcpy(copy, start, len); copy[len] = 0; if ((resp = load_plugin(copy)) != 0) return resp; } if (*end == ':') ++end; } return 0; } const response* load_modules(const char* protocol_name, const char* backend_name, const char** plugins) { const char* env; const response* r; if ((session.module_path = getenv("MODULE_PATH")) == 0) session.module_path = conf_modules; if ((session.protocol = load_object("protocol", protocol_name)) == 0) return &resp_load; if (session.protocol->version != PROTOCOL_VERSION) return &resp_protocol_version; if ((session.backend = load_object("backend", backend_name)) == 0) return &resp_load; if (session.backend->version != PLUGIN_VERSION) return &resp_backend_version; session.flags |= session.backend->flags; while (*plugins != 0) if ((r = load_plugins(*plugins++)) != 0) return r; if ((env = getenv("PLUGINS")) != 0) return load_plugins(env); return 0; } mailfront-1.16/ANNOUNCEMENT0000664000076400007640000001036311356700500014616 0ustar bruceguenterVersion 1.16 of mailfront is now available at: http://untroubled.org/mailfront/ ------------------------------------------------------------------------------ Changes in version 1.16 - Added missing plugin-spamassassin.so to installation. - Fix bug in handling invalid message numbers in retrieving messages in pop3front-maildir. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- mailfront Mail server network protocol front-ends Bruce Guenter Version 1.16 2010-04-06 This is mailfront, a package containing customizeable network front-ends for mail servers. It contains complete SMTP, QMQP, QMTP, and POP3 front-ends as well as an authentication module for IMAP. The mail delivery front-ends also contain internal address filtering features. Two SMTP back-ends are provided. One delivers mail to qmail-queue, mimicking most of the behavior of qmail-smtpd, with the addition of support for SMTP AUTH. The other rejects all SMTP commands if $SMTPREJECT is set, and execs its command line otherwise (in order to run the above program). A mailing list has been set up to discuss this and other packages. To subscribe, send an email to: bgware-subscribe@lists.untroubled.org A mailing list archive is available at: http://lists.untroubled.org/?list=bgware Development versions of mailfront are available via git at: http://bruce-guenter.dyndns.org/git/mailfront.git Requirements: - bglibs version 1.101 - cvm version 0.81 Installation: - Build the sources by running "make". - After the package has been compiled, run "make install" as root. Configuration: - To take advantage of the SMTP AUTH features, make sure you have a CVM authentication program (some are included with the cvm package itself). - Run a CVM authentication module to provide the AUTH feature. Example: To run cvm-vmailmgr as a daemon: exec /usr/local/bin/softlimit -m 9000000 \ /usr/local/bin/cvm-vmailmgr /tmp/.cvm-vmailmgr 2>&1 - Configure your mail system to use the SMTP back-end with the appropriate environment variables. Example using tcpserver (highly recommended): #!/bin/sh QMAILDUID=`id -u qmaild` NOFILESGID=`id -g qmaild` MAXSMTPD=`head -1 /var/qmail/control/concurrencyincoming` if [ -z "$QMAILDUID" -o -z "$NOFILESGID" -o -z "$MAXSMTPD" ]; then echo $0: QMAILDUID, NOFILESGID, or MAXSMTPD is unset exit 1 fi exec \ /usr/local/bin/envdir /etc/smtpfront \ /usr/local/bin/softlimit -m 2000000 \ /usr/local/bin/tcpserver -v -R -H \ -l "`head -1 /var/qmail/control/me`" -x /etc/tcp.smtp.cdb \ -c "$MAXSMTPD" -u "$QMAILDUID" -g "$NOFILESGID" 0 25 \ /usr/local/bin/smtpfront-qmail 2>&1 /etc/smtpfront/CVM_SASL_PLAIN: cvm-local:/tmp/.cvm-vmailmgr Example using xinetd with TCP Wrappers: /etc/xinetd.d/smtp: # default: on # description: smtp service smtp { disable = no flags = REUSE NAMEINARGS socket_type = stream protocol = tcp wait = no user = qmaild server = /usr/sbin/tcpd server_args = /var/qmail/bin/tcp-env -R /usr/local/sbin/smtpfront-wrapper log_on_success += USERID log_on_failure += USERID } /usr/local/sbin/smtpfront-wrapper: #!/bin/sh CVM_SASL_PLAIN=cvm-local:/tmp/.cvm-unix export CVM_SASL_PLAIN CVM_SASL_LOGIN=cvm-local:/tmp/.cvm-unix export CVM_SASL_LOGIN exec /usr/local/bin/smtpfront-qmail 2>> /tmp/smtpfront-errs.txt This project was initiated at FutureQuest, Inc. We are releasing it as an open-source project because we felt it would be useful to others, as well as to repay our debt of gratitude to the larger open-source community for the excellent packages we have enjoyed. For more details, you may contact FutureQuest, Inc. at: FutureQuest, Inc. PO BOX 623127 Oviedo FL 32762-3127 USA http://www.FutureQuest.net/ ossi@FutureQuest.net This package is Copyright(C) 2010 Bruce Guenter or FutureQuest, Inc., and may be copied according to the GNU GENERAL PUBLIC LICENSE (GPL) Version 2 or a later version. A copy of this license is included with this package. This package comes with no warranty of any kind.