Commit graph

26 commits

Author SHA1 Message Date
schmonz
ba5b394c46 Update to 4.0.10. From the changelog:
This version adds a workaround for a bug in Plesk 9 that provides
the text "localhost" instead of the IP address for some connections.
Thanks to Medovarszky Zoltan and Christian Aust for reporting this
one.
2008-12-25 16:43:35 +00:00
schmonz
ae3ed970a9 Update to 4.0.9. From the changelog:
This version fixes a bug in the address parser that was preventing
some sender/recipient whitelist/blacklist entries from matching.
Thanks to John Devenport for reporting this one. This version also
fixes a bug in the "config-test" feature that prevented spamdyke
from finding its own binary when the file is not in the current
directory. Thanks to John Hallam for reporting this one.
2008-12-02 16:24:58 +00:00
schmonz
59fb2ad132 Update to 4.0.8. From the changelog:
Changed spamdyke_log() to send all messages to stderr (when appropriate) using
  a single call to vfprintf() by adding newline characters and PID prefixes to
  the format before outputting anything.  This is necessary to work around a
  problem with the design of DJB's multilog program, which uses a single pipe
  to accept input from all processes and thus cannot keep log messages
  separate.  This means partial output from some spamdyke processes could
  overlap output from other spamdyke processes when the load rises (a race
  condition).  Thanks to Philip Nix Guru for reporting this one.
2008-11-06 16:57:41 +00:00
schmonz
5c86445c96 Update to 4.0.7. From the changelog:
VERSION 4.0.7: 10/17/2008
  Changed Makefile.in to compile configuration.c in two steps: first use gcc
    to produce the preprocessed source, then use gcc to compile it.  For some
    reason, gcc crashes on FreeBSD 6.0 when the file is compiled in one step.
    Thanks to K. Shantanu for reporting this one and Felix Buenemann for
    suggesting the fix.

VERSION 4.0.6: 10/16/2008
  Fixed a problem in examine_ip_in_rdns_keyword_entry() that was not correctly
    terminating the end of the keyword buffer, causing strstr() to search too
    far, leading to false negatives (and potentially segmentation faults).
    Thanks to Erald Troja for reporting this one.
  Fixed another problem in middleman() that was not correctly replacing _all_
    of qmail's AUTH advertisements when the "smtp-auth-level" option is
    "always" or "always-encrypted".  Thanks to Youri Kravatsky for reporting
    this one (again).
  Fixed the fix to a bug in nihdns_query() that was setting
    return_target_name_index to 0 in all cases.  This was causing log messages
    to print the first RBL/RHSBL name instead of the one that actually matched.
    Thanks to Arthur Girardi for reporting this one (again).
  Reverted a change from 4.0.5 -- removing the usable_buf_input flag from
    middleman() meant could only tell if there was input in the buffer, not if
    any of it was actually usable.  If the remote server delays sending its
    data for any reason, middleman() will loop rapidly to continually check if
    its buffered data can be sent to qmail.  Removing the flag meant spamdyke
    was consuming 100% CPU while receiving messages with large attachments.
    Thanks to Paulo Henrique Fonseca for reporting this one.
  Added the "cputime" program to the "tests" folder to measure the CPU time
    used by a process.  Neither the shell "time" command nor the POSIX "time"
    command seem to do that.
  Changed sendrecv to always wait() for its child processes so CPU accounting
    will be performed correctly.
  Fixed check_rhsbl() to correctly return the name of the matching RHSBL instead
    of an index that could be beyond the end of the array.
  Changed the values of LOG_USE_CONFIG_TEST, LOG_USE_STDERR and LOG_USE_SYSLOG
    to make none of them equal to 0.  Because the "log-target" option is a
    CONFIG_TYPE_NAME_MULTIPLE option, it is set to 0 until the command line and
    all configuration files are parsed.  When LOG_USE_CONFIG_TEST is 0, the
    progress messages from process_config_file() are sent to stderr until the
    configuration file is completely loaded.  For Plesk users, xinetd sends
    stderr to the network connection, so the remote server gets the output.
    Thanks to Arthur Girdari for reporting this one and helping track it down.
2008-10-18 04:51:01 +00:00
schmonz
bbf6acfdda Update to 4.0.5. From the changelog:
- If the idle timeout is not configured, it is now set to 20 minutes
    after qmail exits to prevent never-ending spamdyke processing.
    Thanks to Matthew Kettlewell for reporting this one.
- Fixed the AUTH advertisements to display correctly when
    "smtp-auth-level" is "always" or "always-encrypted". Thanks
    to Youri Kravatsky for reporting this one.
- Fixed a sequencing error that would cause qmail to exit prematurely,
    even if valid recipients could still possibly be given. Thanks
    to David Stiller for reporting this one.
- Fixed the handling of unencoded null characters in messages
    (technically not legal) so spamdyke does become confused and
    timeout. Thanks to Arthur Girardi for reporting this one.
- Fixed an issue in the DNS query code that was setting array indexes
    beyond the end of the array, resulting in garbage log messages
    and segmentation faults. Thanks to Arthur Girardi for reporting
    this one.
- Fixed verbose logging in the RHSBL filter to print the correct
    log message. Thanks to Arthur Girardi for reporting this one.
- Rewrote the address parser to correctly handle strange/invalid
    email addresses. Thanks to Erald Troja for reporting this one.
- Fixed a serious error in the code that loads array values from
    files that was returning pointers to unallocated memory, causing
    segmentation faults. Many, many thanks to David Stiller for
    reporting this one and providing tons of help to nail it down.
- Fixed a serious error that was attempting to move data by
    dereferencing the NULL address when the remote server disconnected
    unexpectedly, causing segmentation faults. Many, many thanks
    to David Stiller for reporting this one and providing tons of
    help to nail it down.
2008-10-13 15:24:37 +00:00
schmonz
e6ac7cef92 Update to 4.0.4. From the changelog:
Moved the code for loading configuration files into prepare_settings() from
  do_spamdyke().  When the default value for the "log-target" option was
  being set before the configuration files were read, the syslog option
  could be incorrectly set, even if stderr was specified in a file.
  Thanks to Eric Shubert for reporting this one.
Changed the configure script to detect environments where printf()/scanf()
  use "%ld" for 64-bit integers instead of "%lld" (CentOS 64-bit).  This
  wouldn't be necessary if the gcc authors could grasp the idea that
  "long int" and "long long int" may be interchangable and not emit warnings.
  Thanks to kjl for reporting this one.
2008-09-05 20:33:53 +00:00
schmonz
8cbb22fa2c Add MESSAGE explaining how to enable spamdyke with qmail-smtpd. 2008-08-15 16:51:59 +00:00
schmonz
e8fb770de4 Update to 4.0.3. From the changelog:
This version fixes two bugs. The first is an integer argument
parsing bug on some systems (FreeBSD). Thanks to Shane Bywater for
reporting this one. The second is a bug parsing invalid nameserver
entries in /etc/resolv.conf that prevented spamdyke from defaulting
to 127.0.0.1. Thanks to slamp slamp for reporting this one.
2008-08-15 16:48:16 +00:00
schmonz
bdfbbb76ca Update to 4.0.2. From the changelog:
Fixed a bug in filter_graylist() that was creating infinitely deep "_none"
    directories.  The special-case conversion code added in 4.0.1 was not
    checking to see if "_none" was a file or a directory and performing the
    conversion every time.  Thanks to Bob Alanis for reporting this one.
2008-08-07 13:36:05 +00:00
schmonz
bec87225f8 Update to 4.0.1. This version fixes several bugs:
- The automatic conversion of a graylist directory structure could
  generate errors for empty sender addresses (commonly used for
  bounce messages). Thanks to David Stiller for reporting this one.

- Connections encrypted with TLS (not decrypted by spamdyke) weren't
  always being rejected, even if there was no chance they should
  be accepted. Thanks to Sergio Minini for reporting this one.

- A double-free() problem could result in crashes if the
  "rejection-text-graylist" option was used within a configuration
  directory.

- Compiling on Solaris was generating a warning.
2008-07-18 01:22:39 +00:00
schmonz
b2a47b9701 Update to 4.0.0. The changelog is unwieldy; highlights:
* Several options have changed names, behaviors, defaults, and/or
  possible settings, all of which are explained in the upgrade
  instructions.

* Many new options have been added:
  config-dir
  config-dir-search
  dns-blacklist-file
  dns-level
  dns-max-retries-total
  dns-max-retries-primary
  dns-server-ip
  dns-server-ip-primary
  dns-timeout-secs
  dns-whitelist-file
  filter-level
  graylist-exception-ip-entry
  graylist-exception-rdns-entry
  graylist-level
  ip-blacklist-entry
  ip-in-rdns-keyword-blacklist-entry
  ip-in-rdns-keyword-whitelist-entry
  ip-in-rdns-keyword-whitelist-file
  ip-whitelist-entry
  local-domain-entry
  rdns-blacklist-entry
  rdns-whitelist-entry
  recipient-blacklist-entry
  recipient-whitelist-entry
  rejection-text-access-denied
  rejection-text-dns-blacklist
  rejection-text-earlytalker
  rejection-text-empty-rdns
  rejection-text-graylist
  rejection-text-ip-blacklist
  rejection-text-ip-in-cc-rdns
  rejection-text-ip-in-rdns-keyword-blacklist
  rejection-text-local-recipient
  rejection-text-max-recipients
  rejection-text-missing-sender-mx
  rejection-text-rdns-blacklist
  rejection-text-recipient-blacklist
  rejection-text-reject-all
  rejection-text-relaying-denied
  rejection-text-rhs-blacklist
  rejection-text-sender-blacklist
  rejection-text-smtp-auth-required
  rejection-text-timeout
  rejection-text-unresolvable-rdns
  relay-level
  rhs-blacklist-file
  rhs-whitelist-file
  run-as-user
  sender-blacklist-entry
  sender-whitelist-entry
  smtp-auth-level
  tls-level

* An example spamdyke.conf has been provided.
2008-07-16 07:03:21 +00:00
schmonz
b8e1dd02d4 Update to 3.1.8. From the changelog:
This version fixes a bug with the recipient filters that could allow
a clever sender to use a spamdyke-protected server as an open relay.
The sequence of commands are not legal SMTP, so the sender would
have to know the server was running a vulnerable version of spamdyke
to exploit this bug.  Thanks to Mirko Buffoni for reporting this
one.

This version also fixes two problems with the idle timeout filter.
The first could cause the connection to be rejected because qmail
is slow to respond (which isn't fair).  The second was a tricky
issue where large messages from fast remote servers could be
improperly rejected because the idle timer wasn't being reset.
Thanks to Eric Shubert for reporting and helping me fix this one.

This version also fixes two compiling problems.  The first was a
problem in the "configure" script on older Gentoo installations
running gcc 3.4.6 that was treating a preprocessor warning as an
error.  Thanks to Thorsten Puzich for reporting and helping me fix
this one.  The second was a problem with CentOS 3.8, which doesn't
install the OpenSSL headers in the system include folder.  Thanks
to Bruce Schreiber for reporting this one.
2008-05-28 23:57:27 +00:00
schmonz
f53c20bfb1 Update to 3.1.7. From the changelog:
This version fixes a bug in the white/blacklist file processor that
was incorrectly matching domains when wildcards were used. Thanks
to Tom for reporting this one.
2008-04-08 05:18:24 +00:00
schmonz
89cec61b88 Add two missing system includes to fix the build on NetBSD 4.0. 2008-03-30 17:04:48 +00:00
jlam
a80fd13efc Mechanical changes to add DESTDIR support to packages that install
their files via a custom do-install target.
2008-03-04 17:57:17 +00:00
schmonz
64d16023fe Update to 3.1.6. Note that some command-line options and the format
of some log entries have changed since 2.6.3; see UPGRADING.txt.
Also, pkgsrc no longer installs the random extra utilities that are
explicitly marked as unnecessary for spamdyke operation. From the
changelog:

VERSION 3.1.6 -- 2/11/2008
  Fixed a serious bug in middleman() -- when the remote server sent its message
    data and QUIT command in a burst and disconnected before spamdyke read() all
    of the data, the last data returned from read() was printed twice.  This
    could cause message corruption, especially in the case of attachments.
  Fixed a serious bug in middleman() -- when the remote server sent its data
    in bursts of 4096 bytes AND there were two lines of text in the data
    AND the 4096th character was not a newline AND there was a delay between the
    data bursts, memmove()ing the buffered data was causing corruption because
    the moved data was not being properly re-terminated.  While processing the
    remaining buffered data (and waiting for another burst from the remote
    server), strchr() would seek past the end of the data to an old newline
    character and middleman() would erroneously conclude the next line of data
    was complete, ready for processing.  Many thanks to Andreas Galatis and
    Dragomir Denev for reporting and helping me reproduce this one.
  Added a -W flag to sendrecv to introduce a delay between message data bursts.
  Added a -o flag to smtpdummy to save the message data to a file.

VERSION 3.1.5 -- 1/22/2008
  Fixed sendrecv to correctly process corrupted TLS negotiations instead of
    covering up bugs in spamdyke.
  Fixed spamdyke to not add garbage output at the beginning of TLS passthrough
    negotiations.  This was causing SSL handshakes to fail.  Thanks to Ronnie
    Tartar for reporting this one.

VERSION 3.1.4 -- 1/21/2008
  Fixed all of the Makefiles to remove a symbols directory Leopard's gcc seems
    to create when compiling in debug mode.
  Fixed middleman() to log the timeout message only once.
  Fixed middleman() to not expect input from the child process when the child
    process' input is being ignored or after the child process has exited.
  Fixed middleman() to correctly handle a rare situation -- when the child
    process was too slow responding that spamdyke's idle timeout was passed
    AND spamdyke was processing TLS data AND there was still data in the SSL
    buffer, spamdyke would loop infinitely, consuming 100% CPU.  This was a
    very tricky bug to find and fix.  Thanks to Pablo Gonzalez and Paolo for
    reporting this one and helping me debug it.
  Fixed middleman() to send message data to the child process line-by-line,
    even when the buffer is full.
  Added a new test program: smtpdummy.  This one simulates an SMTP server and
    can add delays after specific commands.
  Changed sendrecv to use a 64K buffer for input and output data.
  Changed sendrecv to kill the its child process after its timeout expires.
  Changed sendrecv to optionally continue sending data in bursts after the end
    for the message data.  Some mail servers do this.
  Changed sendrecv to deliberately send corrupt data while TLS is active.
  Changed test regression_009 to build its message payload at runtime instead
    of including a 0.75M file.  This file was unnecesarily increasing the size
    of the spamdyke tarball.
  Fixed compiling on Solaris.  Again.  Thanks to Davide Bozzelli for reporting
    this.  Again.  Sigh.

VERSION 3.1.3 -- 1/3/2008
  Fixed the format string LOG_INFO_DNS_TXT to assign the parameters correctly
    and prevent bus errors when the DNS response text is long.  Thanks to
    Stephan Rosenke for reporting this one.

VERSION 3.1.2 -- 12/11/2007
  Fixed smtp_filter() to set a flag after some SMTP commands to force
    middleman() to wait for input from the child process before proceeding.
    Some (nonspammer) mail servers send their data in bursts without waiting for
    responses.  This was causing spamdyke to skip logging (but not filtering)
    if the DATA command was sent in a burst with RCPT TO.  Thanks to Sebastien
    Guilbaud and Bucky Carr for reporting this one.
  Added a "-b" flag to sendrecv to simulate servers that send their message data
    (but not their SMTP commands) in bursts.

VERSION 3.1.1 -- 11/12/2007
  Added excessive logging to search_domain_directory() to log the directory
    search pattern.
  Changed all calls to spamdyke_log() to use the macros SPAMDYKE_LOG_NONE(),
    SPAMDYKE_LOG_ERROR(), SPAMDYKE_LOG_INFO(), SPAMDYKE_LOG_DEBUG() and
    SPAMDYKE_LOG_EXCESSIVE() instead.  The macro tests the current log level
    without forcing a function call and also paves the way toward eliminating
    some logging code at compile-time.
  Fixed process_access() to correctly search for the RELAYCLIENT variable in
    spamdyke's environment.  Thanks to Steve Cole for reporting this one.

VERSION 3.1.0 -- 11/5/2007
  Changed the "graylist-dir" and "no-graylist-dir" options to take multiple
    directories for servers that are hosting so many domains that they can't
    create enough domain folders in one place (wow).
  Added minimum and maximum values to all integer options and changed
    set_config_value() to generate error messages when values are out of range.
  Change usage() to print minimum and maximum integer values.
  Alphabetized the option list by long option name and changed
    process_config_file() to use a binary search algorithm when identifying
    directives, a theoretical improvement from O(n/2) to O(log n).
  Changed prepare_settings() to create an array of options indexed by the short
    option code.  This introduces some constant-time work (O(1)) and greater
    memory usage.
  Changed process_command_line() to use the indexed array of options,
    theoretically reducing command line parsing work from O(n/2) to O(1).
    This is a win if the command line has many parameters or if it has
    parameters that are near the end of the unindexed option array.
    Testing confirms a small performance gain.
  Added command line options "config-test-smtpauth-username" and
    "config-test-smtpauth-password".
  Changed config_test_smtpauth() to run the authentication command(s) if a
    username and password are provided.  This incorporates the functionality of
    checkpassword into spamdyke.
  Added the command line option "config-test-user" to change user and group IDs
    before running the configuration tests.  This makes it easier to simulate
    running as the mail server.
  Changed process_config_file() and process_command_line() to print errors and
    stop when they encounter an option that is not legal in that location.  At
    the moment, "help", "version", "config-test",
    "config-test-smtpauth-username", "config-test-smtpauth-password" and
    "config-test-user" are not valid in files; all options are valid on the
    command line.
  Changed config_test_dir_read() and config_test_graylist() to never examine the
    "." or ".." folders, even if readdir() and/or stat() report they are not
    folders.  Thanks to Paulo Henrique for reporting this one.
  Changed set_config_value() to remove trailing slashes from directory paths.
  Added test_spamdyke_binary() to check if the spamdyke binary is setuid root
    (it should not be).
  Renamed test_settings() to config_test().
  Moved all of the configuration test functions to config_test.[ch] -- they were
    cluttering up configuration.c.
  Made a few small updates to the help message text.
  Added additional vchkpw exit codes to exec_checkpassword() to explain why
    vchkpw exited, since it doesn't follow DJB's published checkpassword API.
  Moved md5.[ch] from the "utils" folder to the "spamdyke" folder and updated
    Makefile to compile them into spamdyke.
  Removed passwordcheck from the "utils" folder since spamdyke now contains its
    functionality.
  Added a README file to the "utils" folder to answer the biggest FAQ about
    those utilities.
  Fixed exec_command() to connect the output pipe to the child process's stdin
    instead of file descriptor 3.  The bug was due to copying
    exec_checkpassword() and forgetting to change the value.
  Renamed exec_checkpassword() to exec_checkpassword_argv() and changed its
    arguments to expect a filename and an argument array.
  Added exec_checkpassword() to parse a command string into an argument array
    and call exec_checkpassword_argv().
  Renamed exec_command() to exec_command_argv() and changed its
    arguments to expect a filename and an argument array.
  Added exec_command() to parse a command string into an argument array
    and call exec_command_argv().
  Fixed numerous bugs in exec_command_argv() that were preventing it from
    actually gathering any input from the child process.
  Changed exec_command_argv() and exec_checkpassword_argv() to always log their
    child process errors to syslog, regardless of the user's preferences.
    Otherwise, the errors will be lost.
  Added the function find_path() to search the PATH for the given command
    without executing it.
  Changed exec_command_argv() and exec_checkpassword_argv() to use find_path()
    to locate the executable before fork()ing to catch typos.  The child
    processes then use execve() to execute the command instead of exec_path().
    Otherwise, the parent has a hard time determining that the child process
    quit because the command path was invalid.
  Changed exec_command_argv() and exec_checkpassword_argv() not to wait
    indefinitely for the child to exit after the timeout expires.
  Changed dns_txt(), dns_ptr_lookup() and dns_mx() to limit the total number of
    queries they will recursively perform.  This is to prevent a DoS situation
    where some domain has an unreasonable number of chained (non-circular) CNAME
    records.  The limit is (arbitrarily) set at 16.
  Added the function config_test_child_capabilities() to test the qmail binary
    for SMTP AUTH and TLS patches.  Depending on what is found, recommendations
    for spamdyke flags are made.
  Changed check_rdns_keywords() to allow top-level domains (like .com) to be
    used as keywords.  This allows a way to reject connections from remote
    servers with rDNS names that contain the IP address and a two-letter country
    code.  Unlike check_country_code(), specific country codes can now be
    chosen.
  Fixed do_spamdyke() not to wait indefinitely for all child processes to exit.
    This behavior was causing problems with DJB's recordio because recordio
    fork()s and uses its parent process to exec() spamdyke.  This is very
    unusual.  Changing wait(NULL) to waitpid() fixes the problem.  Thanks to
    Bob Hutchinson for reporting this one.
  Added dns_initialize() and dns_get() to perform DNS queries by sending UDP
    packets instead of using the resolver library to do it.  The resolver
    functions are just too slow and they try to do too much unnecessary work.
    dns_get() performs multiple requests for records (one for each kind of
    desired record) and, if no responses are received, sends requests to the
    secondary nameservers as well.  Timeouts and retransmission times can now
    be controlled.  This has resulted in a significant speedup in DNS
    resolutions; testing shows as much as a 10x performance increase in some
    situations.
  Changed dns_txt(), dns_ptr_lookup() and dns_mx() to search all of the answers
    for the desired answer type before recursively querying CNAME answers.  Some
    nameservers always put the CNAME answers first, even if other answer types
    are also given.  This should allow spamdyke to find answers faster when
    domain admins have used a lot of CNAMEs.
  Added dns_a() to perform A record queries and changed all uses of
    gethostbyname() to use dns_a() instead.
  Changed dnsa, dnsmx, dnsns, dnsptr, dnssoa and dnstxt in the "utils" folder to
    only perform their specific queries, not ask for CNAME records as well.
  Changed dnsa, dnsmx, dnsns, dnsptr, dnssoa and dnstxt in the "utils" folder to
    send their own UDP packets instead of using the resolver library.
  Added dnscname to the "utils" folder to perform CNAME queries.
  Added dnsany to the "utils" folder to perform ANY queries and perform
    recursive CNAME lookups.
  Added "log-target" option to allow logging to stderr instead of syslog.  Some
    people apparently like using the qmail-style "multilog" instead of syslog.
    I can't understand why but I'm here to serve.  Thanks to John Hallam for
    suggesting this one.
  Changed all of the error messages about unexpected file types to specify what
    file type was found -- "non-regular file" was too vague to be useful.
  Changed the header in the files created by full logging to include the
    spamdyke version.
  Changed tls_end_inner() to use SSL_get_shutdown() to see if a shutdown signal
    has already been received.  If SSL_shutdown() is used on a closed file
    descriptor, spamdyke will crash with SIGPIPE.
  Changed all instances of read(), write(), SSL_read() and SSL_write() to read
    or write as many bytes as possible in each call.  This should provide a
    significant performance increase.  The single-byte read()s and write()s
    were only used because I had badly misunderstood the relationship between
    select() and read()/write() -- blocking only occurs when select() indicates
    a file descriptor is not ready.  If it is ready, read() and write() will
    handle as many bytes as they can without blocking.  Thanks to Trog for
    setting me straight on this one.
  Rewrote most of sendrecv in the "tests" folder to use a multi-byte read().
    Also took the opportunity to make sendrecv much faster and more polite, so
    it doesn't consume 100% CPU while waiting for qmail output.
  Fixed compiling errors on 64 bit Linux systems (Debian Etch x86_64 and Gentoo
    AMD64).  Thanks to Juha-Pekka Jarvenpaa and FireBall for reporting this.
  Added config_test_file_type() to use stat() to find a file's type if readdir()
    either doesn't report it (Solaris) or reports "unknown" for all files (XFS).
    Thanks to Paulo Henrique for reporting this one.
  Fixed compiling errors on Solaris.  Thanks to Limperis Antonis for reporting
    this.
  Changed the logging severity of the "unable to write X bytes to file
    descriptor" to debug instead of error.  99% of the time, the error occurs
    because the remote client disconnected unexpectedly and there's nothing
    the administrator can do about it anyway.
  Changed do_spamdyke() to ignore SIGPIPE signals.
  Changed do_spamdyke(), exec_command_argv() and exec_command_checkpassword()
    to change the SIGPIPE signal handler back to default for child processes
    after fork()ing but before exec()ing.
  Added a new logging level: excessive (4).  It's to be used for printing very
    detailed debugging statements.
  Changed process_access() to permit access when no matching lines are found in
    the access file.  Although DJB's tcprules documentation doesn't explicitly
    say so, no matching lines should allow access.  Thanks to Steve Cole for
    reporting this one.

VERSION 3.0.1 -- 9/12/2007
  Fixed "configure" to remove the "_beta1" tag from the version number.  That
    should never have been published.
  Changed usage() to show that optional values to long commands must be
    separated by an equals sign.  getopt_long() is really becoming a hassle.
    Thanks to Richard Kreider for reporting this one.
  Fixed find_address() to accept addresses that aren't correctly delimited with
    <> characters and/or have multiple (illegal) spaces after the colon.  Thanks
    to Davide Bozzelli for reporting this one.
  Fixed prepare_settings() to set the idle timeout seconds to the correct
    variable instead of setting the connection timeout variable.  Thanks to
    Carlo Blohm for reporting this one.
  Fixed smtp_filter() to print the rejection message to HELO and EHLO, even if
    those commands appear in an improper place in the protocol.
  Fixed smtp_filter() to print the rejection message with an error code in
    response to STARTTLS if the command is given in an improper place in the
    protocol.
  Added some regression tests to find these bugs in the future.
  Fixed the usage statement in sendrecv to show the -w flag.

VERSION 3.0.0 -- 9/11/2007
  Added command line options never-graylist-rdns-dir, always-graylist-rdns-dir
    and rdns-whitelist-dir to search domain directory structures just like
    rdns-blacklist-dir.
  Added the command line option rdns-blacklist-file to search a file just like
    rdns-whitelist-file.
  Moved the command line option labels into configuration.c so they can be
    shared with the config file parser.
  Changed process_command_line() to build the list of short options from the
    list of long options instead of hardcoding them.  Less maintenance this way.
  Modified check_rdns_keywords(), search_file() and search_tcprules_file() to
    correctly track line numbers and return the matching line number instead of
    just 1.
  Changed logging to allow the amount of information to be turned up or down.
    This should make spamdyke less chatty in the syslog for small errors.
  Modified smtp_filter() and run_tests() to report the matching filename and
    line number from check_rdns_keywords(), search_file() and
    search_tcprules_file() in syslog if the logging level is high enough.
  Fixed find_address() to locate the real email address and ignore BATV tags,
    relay paths and bang paths.  Thanks to Walter Russo for reporting this one
    (again).
  Changed middleman() to obey minimums and maximums for the amount of time to
    select() for traffic.  If spamdyke waits too long, the qmail process might
    not get wait()ed for a while, leaving a lot of defunct/zombie processes
    around.  On a busy server, this could be a problem.  Thanks to Jason M for
    reporting this one.
  Added process_config_file() to process configuration files instead of
    requiring all configuration to be done on the command line.  At the moment,
    the file just uses the same (long option) directives as the command line.
  Added test_settings() to run tests on every configuration option and
    (hopefully) identify misconfigurations before someone makes them on a live
    server.
  Added the command line option "config-test" to run test_settings().
  Renamed log_writeln() and log_write_rejection() to output_writeln() and
    output_write_rejection(), respectively, to make it clearer what they're
    doing.
  Changed smtp_filter() to allow multiple authentication attempts.  Some
    clients retry authentication several times, presumably to deal with servers
    that can't use the authentication method they prefer.
  Changed middleman() to collect (and send) whole lines of input instead of
    single characters.  Single character write()s were causing problems with
    Nagios and Windows clients.
  Changed output_write_rejection() to create a single output line and send it
    to output_writeln() all at once instead of sending a piece at a time.  This
    keeps packets together for stupid Windows clients that just can't handle
    reassembling TCP packets correctly.
  Changed main() to always run spamdyke (as opposed to starting qmail without
    spamdyke listening) even if a whitelist is matched.  This way, spamdyke
    can report all traffic to syslog, not just traffic that _may_ be filtered.
  Changed smtp_filter() and middleman() to catch the return codes from qmail
    when the remote client gives the recipient address.  Now, if spamdyke
    doesn't block the recipient command but qmail does (e.g. for relaying),
    spamdyke will log the correct message.
  Incorporated GNU autoconf to create a "configure" script for spamdyke and the
    "utils" folder.  The days of "make no_tls" and "make bsd" are thankfully
    over.
  Renamed all of the test folders to group them by function so it's easier to
    see what tests exist.  Sequential numbers just weren't working.
  Changed dns_mx() to lookup the MX record before returning success.  This means
    the sender MX filter now requires a mail exchanger record _and_ at least one
    mail exchanger must have an IP address.  Before, the MX record was enough,
    even if there was no corresponding A record.
  Changed usage() to read the options and help text from get_spamdyke_options()
    in configuration.c so the help message won't ever be out of sync with the
    available options again.
  Added the command line option "tls-privatekey-password-file" to allow the SSL
    private key password to be read from a file instead of the command line.
    This way, the password isn't visible to everyone who can view a process
    list.
  Changed search_file(), search_tcprules_file() and check_rdns_keywords() so
    they no longer build their fscanf() patterns into a stack variable but
    instead use a literal search pattern assembled at compile time with
    STRINGIFY().
  Added the command line options "hostname-file" and "hostname-command" to
    support reading the local hostname from a file or from a command (e.g.
    "hostname -f") instead of forcing it to be specified on the command line.
  Changed middleman() and smtp_filter() to always monitor and trust
    authentication carried out by qmail, even if "smtp-auth-command" was not
    given.  This means spamdyke will always disable its filters for
    authenticated users even if it can't check the authentication itself.
    I'm not sure why I didn't design spamdyke this way in the first place.
  Added command line options recipient-whitelist-file and sender-whitelist-file
    so specific sender and recipient addresses can bypass the filters.  Sender
    addresses are very easy to fake and recipient addresses are, of course,
    known to spammers, so both of these options are ill-advised.  I've only
    added them due to popular demand.
  Added command line option check-rhsbl to check righthand-side blacklists.
    Both the server's rDNS domain name and the sender's email domain name are
    checked.
  Added command line options check-dns-whitelist and check-rhs-whitelist to
    allow DNS RBLs and RHSBLs to act as whitelists instead of blacklists.
    Anyone using DNS-based blacklists _and_ whitelists had better have some
    seriously fast DNS servers.
  Changed dns_txt(), dns_mx() and dns_ptr_lookup() to pass a stack of previous
    queries whenever they recursively lookup CNAME records, to prevent a cylical
    CNAME structure from leading to infinite recursion.
  NOT BACKWARDS COMPATIBLE: Changed the syslog entry format: renamed "origin" to
    "origin_ip", added "origin_rdns:" before the rDNS name, added "auth:"
    before the authenticated username and added "reason:" before the rejection
    reason when a timeout occurs.
  Changed process_command_line() to assume the remote IP address is 0.0.0.0 if
    the environment variable TCPREMOTEIP is not set.
  Added a ton more test scripts for all of the new options and for testing
    config files.
  Added dnsa, dnsns and dnssoa to the "utils" folder for performing DNS queries
    of A, NS and SOA records, respectively.  Wouldn't it be AMAZING if the
    libc maintainers added standard functions to do these queries?!
  NOT BACKWARDS COMPATIBLE: Changed the "flag" options to take optional
    arguments instead of simply assuming "true" when the option was given.
    Unfortunately, getopt_long() is too stupid to handle them properly, which
    means clustered options (e.g. -rRc) can no longer be used.  They must be
    separated (e.g. -r -R -c).  Also, arguments given with the short version
    must not be separated by a space (e.g. -l3).
  NOT BACKWARDS COMPATIBLE: Renamed the long command line option "use-syslog"
    to "log-level".
  Fixed middleman() to completely bypass all processing when TLS passthrough is
    active.  The additional processing was buffering TLS traffic until the data
    contained a newline character (purely by coincidence).  This buffering was
    preventing the passthrough from functioning properly.  Thanks to Dominik
    Dausch for reporting this one.
2008-02-25 07:38:00 +00:00
joerg
82bdfe81ee Fix typo. Thanks schmonz@ 2007-07-03 14:42:33 +00:00
joerg
e24209d145 Add common handling for libresolv similiar to dlopen(3) wrapping.
For now, DragonFly and FreeBSD use the libc version, it is not reentrant,
but thread-safe. NetBSD 3.0+ and Darwin 8.0+ use libresolv from base
(the BIND9 resolver), all other fall back to net/bind9. Feel free to add
your favorite platform if it has a thread-safe resolver in base.

Modify mail/libspf-alf, mail/milter-greylist, mail/spamdyke and
net/nocol accordingly. Testing on !DragonFly and feedback from tron@
2007-07-03 13:54:45 +00:00
schmonz
e399928025 Update to 2.6.3. From the changelog:
Fixed a serious bug where spamdyke was closing the connection to qmail and
    exiting as soon as the remote host exited.  When the remote host sends its
    SMTP data in one burst and closes the connection without waiting for the
    response code from the DATA segment, qmail doesn't accept the message and
    nothing gets delivered.
  Added some code to log_writeln() to translate bare carriage returns into
    carriage return/linefeed combinations.  This allows poorly written remote
    servers to send mail, most notably Microsoft web servers.  Dogmatically
    refusing to accept mail by refusing to be more flexible than RFC 822
    will never change the world; let's be reasonable instead of bouncing
    messages back to our friends who can't change their mail servers anyway.
  Fixed smtp_filter() to accept parameters to AUTH LOGIN when the MUA sends the
    authentication information with the command instead of waiting for the
    prompts.  Thanks to Carlo Blohm for reporting this one.
2007-06-21 19:08:45 +00:00
schmonz
5e34cbf654 Update to 2.6.2. From the changelog:
Fixed smtp_filter() to accept parameters to AUTH PLAIN when the MUA sends the
    authentication information with the command instead of waiting for another
    prompt.
  Changed find_address() to strip BATV tags from addresses so whitelist/
    blacklist matching can still take place.  Reported by Walter Russo.
  Added utils/passwordcheck to help troubleshoot SMTP AUTH problems.
  Added more logging to exec_checkpassword() to aid troubleshooting.
2007-06-08 01:08:29 +00:00
schmonz
88398b2bc2 Update to 2.6.1. From the changelog:
* Changed calls to tolower() and isalnum() to eliminate warnings
    from gcc 3.3.3 on NetBSD 3.1.  Thanks to David Frese for reporting
    this one.

* Fixed a very small typo in the new mask/flag system that was
    preventing spamdyke from advertising SMTP AUTH on unpatched
    qmail servers -- FILTER_FLAG_AUTH_ADD had the same value as
    FILTER_FLAG_AUTH_NONE.  Oops.  Thanks to Renato Franzin for
    reporting this one.

* Fixed an oversight in the use of gethostbyname() to perform DNS
    lookups for A records.  If the server is configured to search
    a domain for matching names ("search" in /etc/resolv.conf) and
    the domain has a wildcard DNS entry, the DNS RBL code was always
    matching because an A record was always found.  Adding a dot
    to the end of the queried name prevents the domain searching
    and returns correct results.  Thanks to "Paolo", Alexander
    Fordyce and Jens Mickerts for reporting and helping me troubleshoot
    this one.
2007-06-04 21:54:05 +00:00
schmonz
50d9979579 Update to 2.6.0. From the changelog:
Added support for STARTTLS, similar to the way SMTP AUTH is implemented -- if
    a server certificate is available, spamdyke takes care of the TLS.  If not
    but qmail supports TLS, spamdyke passes it through.
  Changed the read() and write() calls to the network to use macros named
    NETWORK_READ() and NETWORK_WRITE() that are replaced by TLS routines when
    TLS support has been compiled in.
  Changed the smtp_filter() return codes to use a mask/flag system because the
    possible permutations of PASS/INTERCEPT/QUIT with ADD/REMOVE/CAPTURE AUTH
    and ADD/REMOVE/CAPTURE TLS and CHILD QUIT/CONTINUE were getting too complex.
  Fixed search_file() to match a file entry where the search text matches the
    entry completely but the entry has wildcard markers at the start and/or end.
  Added TLS support to tests/sendrecv so TLS can be tested from scripts.
  Fixed numerous small bugs in tests/sendrecv that were causing inaccurate test
    results (false positives and false negatives).
  Updated all of the test scripts to make renumbering them easier.
  Added a new test script to exercise a small whitelist wildcard bug I found.
  Added 10 new test scripts to exercise the new TLS features.
  Changed process_command_line() and usage() to print a brief usage message if
    no parameters are given.
  Changed process_command_line() and usage() to print a brief error message if
    a bad parameter is given.
  Changed process_command_line() and usage() to print the full usage message if
    -h or --help is given.
  Changed process_command_line() and usage() to print the version header if -v
    or --version is given.
  Renamed test_smtpauth_crammd5, test_smtpauth_login and test_smtpauth_plain to
    smtpauth_crammd5, smtpauth_login and smtpauth_plain, respectively.
  Moved smtpauth_crammd5, smtpauth_login and smtpauth_plain from the utils
    folder to tests/smtpauth, since they're only used by the test scripts
    anyway.
  Added alternate command line options for people who spell "gray" with an "e".
    They do the same thing.
  Updated the documentation.
2007-05-30 05:58:10 +00:00
schmonz
6c9c63a232 Update to 2.5.0. From the changelog:
Moved portions of spamdyke's code from spamdyke.c into new .c and .h files to
    make it a little easier to understand and maintain.
  Added base64_encode() and base64_decode() to transfer data to/from base64
    format.
  Added md5() to produce an MD5 digest of a data block.  Turns out this wasn't
    necessary for spamdyke, only for test_smtpauth_crammd5.  Oops.
  Renamed the "make openbsd" command to "make bsd" since apparently all *BSD
    distributions don't need -lresolv.
  Renamed search_ip_file() to search_tcprules_file() and extended it to support
    IP ranges, rDNS names and remote info like tcprules does (according to
    http://cr.yp.to/ucspi-tcp/tcprules.html).  This makes the IP black/
    whitelist files much more flexible.  This will be much handier in the next
    version (AKA The Great Configuration Overhaul).
  Modified middleman() and smtp_filter(), added exec_checkpassword() so spamdyke
    can do SMTP AUTH, either by offering it itself or observing the qmail
    traffic.  LOGIN, PLAIN and CRAM-MD5 are supported.
  Changed the STRLEN_ macros in spamdyke.h to use a single STRLEN() macro so the
    preprocessor will count characters instead of doing it by hand.  Much safer
    this way.
  Removed "-a"'s (max number of recipients per message) dependence on "-d"
    (local domains file).  With SMTP AUTH, the local access file and whitelists,
    this shouldn't be necessary.
  Added process_access() to process local access files (e.g. /etc/tcp.smtp) and
    export environment variables based on the source of the incoming connection.
  Added relay prevention based on the content of the local access file(s) and
    the list(s) of local domains.  Connections from remote sources that are
    granted relay permission in the access file(s) are allowed to relay.  Users
    who authenticate with SMTP AUTH are allowed to relay.  All others must send
    to local addresses only.
  Added a series of test scripts to exercise all of spamdyke's filters and
    options.  This should make it easier to regression test new versions.
  Changed search_file() and search_tcprules_file() to compare domain names in a
    case insensitive manner.
  Changed canonicalize_path() to reduce all file paths to lowercase.  This was
    causing graylisting to be inconsistant.  Reported by bcarr@purgatoire.org.
2007-05-07 19:43:43 +00:00
joerg
01186e9166 Use OpenBSD case for DragonFly. 2007-04-18 15:36:18 +00:00
schmonz
c84d21987b Update to 2.4.0. From the changelog:
Added search_ip_file() to search files for IP addresses and allow wildcards,
    network sizes (numbers of bits, e.g. 11.22.33.44/16) and netmasks (e.g.
    11.22.33.0/255.255.255.0).
  Added new options to allow graylisting exclusions by IP address and rDNS
    name.
  Added new options to activate graylisting for only certain IP addresses and
    rDNS names.
  Updated the documentation.

  Added some explicit casting to printf("%.*s") arguments to make them ints
    instead of longs.  gcc 3.3 on OpenBSD was complaining.
  Changed a datatype in log_write() from long to time_t.  gcc 3.3 on OpenBSD
    was complaining.
  Changed all uses of sprintf() to snprintf(), even though they were already
    safe from buffer overruns.  gcc 3.3 on OpenBSD was complaining.
  Added a new target to the Makefile in the spamdyke and utils folders named
    "openbsd" that compiles without the "-lresolv" flag.  gcc 3.3 on OpenBSD
    includes the resolver library automatically and throws an error when it
    is explicitly specified.
  Added some additional #include directives in dnsmx.c, dnsptr.c and dnstxt.c
    because they're not included by resolv.h on OpenBSD.

  Gained a broader understanding of the resolver library and DNS packet
    structure, then rewrote most of dns_txt() and dns_ptr_lookup() to (more)
    correctly process DNS data.
  Added dns_mx() to perform MX record lookups.
  Changed process_command_line() to use getopt_long() and added long option
    equivalents to the existing command line flags.
  Added the option "reject-missing-sender-mx" to reject email from senders
    whose domains aren't local and don't have MX records and/or A records.
    AOL does this.
  Updated the usage statement to show the new (long) command line options.
  Updated the README.txt to show the new (long) command line options.
  Moved domain2path and domainsplit into a new folder named "utils".
  Created dnsmx, dnsptr and dnstxt in the utils folder by copying the dns_mx(),
    dns_ptr() and dns_txt() functions from spamdyke.  They are simple command
    line utilities that no one will ever use except as examples of how to make
    MX, PTR and TXT DNS queries using libc.  As far as Google knows, there are
    no such examples anywhere else on the internet.
  Changed the DNS RBL code to check for A records in addition to TXT records.
    Some RBLs are using A records, I don't know why.
  Fixed the DNS RBL code not to check 127.0.0.1 for RBL entries.
2007-04-11 14:50:37 +00:00
schmonz
8a570f2200 Initial import of spamdyke 2.2.1.
spamdyke monitors incoming traffic, acting as a middleman between
qmail and the remote server. It catches the sender and recipient
addresses as they go by and logs them to syslog. If it sees something
it doesn't like (e.g. a blacklisted sender), it cuts the connection,
closes qmail and fakes the rest of the SMTP transaction with the
remote server. qmail thinks the remote server disconnected normally.
The remote server thinks qmail is rejecting the message. It's the
best of both worlds.

spamdyke can optionally reject the connection if the remote server's
reverse DNS entry does not exist, does not resolve, contains its
IP address and either contains a prohibited keyword (like "dynamic")
or ends in a country code; if the IP address, reverse DNS entry,
or envelope sender is listed in a blacklist; or if data is sent
before the SMTP greeting banner is displayed. spamdyke can also
limit recipients per connection, greylist for some or all domains,
and close connections that go idle or take too long.
2007-03-24 07:39:25 +00:00