Index: master/smail/CHANGES diff -c master/smail/CHANGES:1.113 master/smail/CHANGES:1.114 *** master/smail/CHANGES:1.113 Tue Sep 7 23:54:23 1999 --- master/smail/CHANGES Sun Sep 19 18:45:21 1999 *************** *** 1,10 **** ! #ident "@(#)smail:$Name: RELEASE-3_2_0_107 $:$Id: CHANGES,v 1.113 1999/09/08 03:54:23 woods Exp $" ---------------------------------------------------------------------------- ! SMAIL RELEASE $Name: RELEASE-3_2_0_107 $ ! This is Smail, release $Name: RELEASE-3_2_0_107 $. If you are new to Smail, Welcome!. --- 1,10 ---- ! #ident "@(#)smail:$Name: RELEASE-3_2_0_108 $:$Id: CHANGES,v 1.114 1999/09/19 22:45:21 woods Exp $" ---------------------------------------------------------------------------- ! SMAIL RELEASE $Name: RELEASE-3_2_0_108 $ ! This is Smail, release $Name: RELEASE-3_2_0_108 $. If you are new to Smail, Welcome!. *************** *** 30,36 **** related settings may also be of interest. ! CHANGES IN THIS RELEASE ($Name: RELEASE-3_2_0_107 $) The following list is an overview of the changes since 3.2. See other lists further down in this file to discover what happened before that. --- 30,36 ---- related settings may also be of interest. ! CHANGES IN THIS RELEASE ($Name: RELEASE-3_2_0_108 $) The following list is an overview of the changes since 3.2. See other lists further down in this file to discover what happened before that. *************** *** 159,171 **** routers some of these verifications will be rendered useless! EVERYONE should do anti-spoof IP filtering at their borders. ! - SMTP envelope sender addresses (i.e. MAIL FROM arguments) are ! verified. In the case of mail received by TCP/SMTP the ! sender's domain name must have a valid DNS MX RR or A RR. If ! the target domain of the sender address is a locally handled ! one, or if the lowest precedence MX host for the target domain ! is locally handled, then the sender address is also verified ! to be deliverable too. A new config variable "smtp_sender_verify_mx_only" can be set to force only MX lookups (i.e. strict SMTP conformance, no RFC --- 159,172 ---- routers some of these verifications will be rendered useless! EVERYONE should do anti-spoof IP filtering at their borders. ! - The SMTP envelope sender address (i.e. MAIL FROM argument) is ! verified unless the client address is listed in the new ! variable smtp_sender_no_verify. In the case of mail received ! by TCP/SMTP the sender's domain name must have a valid DNS MX ! RR or A RR. If the target domain of the sender address is a ! locally handled one, or if the lowest precedence MX host for ! the target domain is locally handled, then the sender address ! is also verified to be deliverable too. A new config variable "smtp_sender_verify_mx_only" can be set to force only MX lookups (i.e. strict SMTP conformance, no RFC *************** *** 173,179 **** Build configuration: ! - the HAVE_SETEUID feature is no longer supported. - the NOBODY config variable was changed to SMAIL_NOBODY to avoid further conflict with Solaris-2.x (SunOS-5.x). This may --- 174,180 ---- Build configuration: ! - the insecure HAVE_SETEUID feature is no longer supported. - the NOBODY config variable was changed to SMAIL_NOBODY to avoid further conflict with Solaris-2.x (SunOS-5.x). This may *************** *** 210,215 **** --- 211,222 ---- - messy handling of "#!" vs. the pipe transport driver's command setting has been moved to config.h where it belonged all along. + - A linux-glibc2 OS configuration has been added that uses DB + style DBM libraries. Note that glibc2 seems to have 32-bit + user-ids and may encounter problems if BOGUS_*ID values are + not explicitly overridden by a local smail_nobody setting. + + Miscellaneous: - other minor bug fixes for SysVr4, Linux, SunOS 4+5, etc. *************** *** 275,282 **** - The un-documented NO_VERIFY option has been split into the two still un-documented NO_SMTP_EXPN and NO_SMTP_VRFY options both ! to make it possible to disable EXPN without breaking VRFY, and ! to disambiguate from the old VRFY_RCPTS. - Duplicate addresses are now checked for in two stages -- first as literal duplicates without parsing right down to the --- 282,297 ---- - The un-documented NO_VERIFY option has been split into the two still un-documented NO_SMTP_EXPN and NO_SMTP_VRFY options both ! to make it possible to permanently disable EXPN without ! breaking VRFY, and to disambiguate from the old VRFY_RCPTS. ! ! - the smtp_info variable has been renamed smtp_allow_expn and ! now only affects EXPN (VRFY, as required by RFC-1123, is ! always enabled unless turned off at compile time as above). A ! compatibility entry remains for smtp_info. ! ! - the smtp_debug variable has been renamed smtp_allow_debug. A ! compatability entry remains for smtp_debug. - Duplicate addresses are now checked for in two stages -- first as literal duplicates without parsing right down to the Index: master/smail/INSTALL diff -c master/smail/INSTALL:1.25 master/smail/INSTALL:1.26 *** master/smail/INSTALL:1.25 Tue Sep 7 23:53:40 1999 --- master/smail/INSTALL Sun Sep 19 17:33:06 1999 *************** *** 1,4 **** ! #ident "@(#)smail:$Name: RELEASE-3_2_0_107 $:$Id: INSTALL,v 1.25 1999/09/08 03:53:40 woods Exp $" INITIAL UNPACKING --- 1,4 ---- ! #ident "@(#)smail:$Name: RELEASE-3_2_0_108 $:$Id: INSTALL,v 1.26 1999/09/19 21:33:06 woods Exp $" INITIAL UNPACKING *************** *** 15,21 **** installed and a default repository created) you might do something like this: ! cvs import -I ! -m 'Smail $Name: RELEASE-3_2_0_107 $ Distribution' smail SMAIL $Name: RELEASE-3_2_0_107 $ If you don't have CVS, but are familiar with RCS, or SCCS, you can also use those tools to track any local changes you might make during the --- 15,21 ---- installed and a default repository created) you might do something like this: ! cvs import -I ! -m 'Smail $Name: RELEASE-3_2_0_108 $ Distribution' smail SMAIL $Name: RELEASE-3_2_0_108 $ If you don't have CVS, but are familiar with RCS, or SCCS, you can also use those tools to track any local changes you might make during the *************** *** 316,321 **** --- 316,325 ---- You'll also have to add NEED_HSTRERROR when using the native resolver code on releases of SunOS-5 prior to 5.6. + + * It is said that some systems with 32-bit UIDs (eg. Linux with + glibc2) will suffer problems in places if the nobody ID isn't set + right. CREATING CONFIGURATION FILES Index: master/smail/ToDo diff -c master/smail/ToDo:1.49 master/smail/ToDo:1.51 *** master/smail/ToDo:1.49 Fri Aug 6 18:27:34 1999 --- master/smail/ToDo Sun Sep 19 18:14:16 1999 *************** *** 1,4 **** ! #ident "@(#)smail:$Id: ToDo,v 1.49 1999/08/06 22:27:34 woods Exp $" Things that should be done before the next minor release (patches are, of course, gratefully accepted!): --- 1,4 ---- ! #ident "@(#)smail:$Id: ToDo,v 1.51 1999/09/19 22:14:16 woods Exp $" Things that should be done before the next minor release (patches are, of course, gratefully accepted!): *************** *** 14,28 **** - do strip quotes from quoted local parts.... maybe. - - change smtp_info to smtp_allow_expn/smtp_allow_vrfy. Add warning - about RFC-1123 says "MUST implement VRFY" and "SHOULD implement EXPN" - both in the code and smailconf.5 and note VRFY is as safe as RCPT TO. - - fix bug where qualify_domain() isn't called for addresses specified on ! the command line (i.e. it only seems to be called when '-t' is used) - use ftruncate() to remove partially written messages in appendfile.c ! if ERR_135 [if possible]. - investigate extra <>'s in received for bounces (and other places): --- 14,24 ---- - do strip quotes from quoted local parts.... maybe. - fix bug where qualify_domain() isn't called for addresses specified on ! the command line (i.e. it only seems to be called when '-t' is used) - use ftruncate() to remove partially written messages in appendfile.c ! if ERR_135 [if possible]. - investigate extra <>'s in received for bounces (and other places): *************** *** 34,50 **** (Smail-3.2.0.98-Pre 1997-Aug-19 #7 built 1997-Aug-20) - deal with un-qualified local hostnames when there's no qualify file in ! some sane way.... (the qualify.c stuff is perhaps overloaded and ! shouldn't be used to qualify both local names in outgoing headers at the ! same time as being used to qualify destination hostnames). - fix "from_field" to never allow "From:" to go missing and if it's nil ! do something appropriate.... - fix db lookup parser to allow '#' in left-hand side (if quoted?) [aliasfile] ! - investigate the Apparently-To: being set, while input_addr not being set: ! (no To/Resent-To/Cc/Bcc, etc., header in data, just envelope "MAIL FROM:") Received: from [204.92.254.3] by most.weird.com via sendmail with smtp (ident woods using rfc1413) --- 30,47 ---- (Smail-3.2.0.98-Pre 1997-Aug-19 #7 built 1997-Aug-20) - deal with un-qualified local hostnames when there's no qualify file in ! some sane way.... (the qualify.c stuff is perhaps overloaded and ! shouldn't be used to qualify both local names in outgoing headers at ! the same time as being used to qualify destination hostnames). - fix "from_field" to never allow "From:" to go missing and if it's nil ! do something appropriate.... - fix db lookup parser to allow '#' in left-hand side (if quoted?) [aliasfile] ! - investigate the Apparently-To: being set, while input_addr not being ! set: (no To/Resent-To/Cc/Bcc, etc., header in data, just envelope ! "MAIL FROM:") Received: from [204.92.254.3] by most.weird.com via sendmail with smtp (ident woods using rfc1413) *************** *** 53,65 **** (Smail-3.2 1996-Jul-4 #1 built 1996-Jul-4) Apparently-To: foo@anet ! perhaps $input_addr should be set from envelope (always?). - investigate smail vs. MH via SMTP and BCC. Seems the BCC line can end ! up in the initial Received header. I'm not even sure why the first ! received line is there. This may have something to do with other ! instances where multiple addresses per message give strange log entries ! and bounce messages. Received: from woffi.planix.com([204.29.161.34]) (1436 bytes) by whome.planix.com via sendmail with P:esmtp/D:aliases/R:inet_hosts/T:smtp --- 50,62 ---- (Smail-3.2 1996-Jul-4 #1 built 1996-Jul-4) Apparently-To: foo@anet ! perhaps $input_addr should be set from envelope (always?). - investigate smail vs. MH via SMTP and BCC. Seems the BCC line can end ! up in the initial Received header. I'm not even sure why the first ! received line is there. This may have something to do with other ! instances where multiple addresses per message give strange log ! entries and bounce messages. Received: from woffi.planix.com([204.29.161.34]) (1436 bytes) by whome.planix.com via sendmail with P:esmtp/D:aliases/R:inet_hosts/T:smtp *************** *** 76,82 **** To: customers@planix.com (to /dev/null), partners@planix.com (an alias) >> Dcc: customers_hidden@planix.com (an alias to everyone) ! Note MH uses 'Dcc' instead of 'Bcc' for normal (direct) blind carbon. - do something about the premature lower-casing of user names. Users with upper case characters may not be able to receive mail (or at least --- 73,79 ---- To: customers@planix.com (to /dev/null), partners@planix.com (an alias) >> Dcc: customers_hidden@planix.com (an alias to everyone) ! Note MH uses 'Dcc' instead of 'Bcc' for normal (direct) blind carbon. - do something about the premature lower-casing of user names. Users with upper case characters may not be able to receive mail (or at least *************** *** 198,210 **** 05/07/1997 15:40:59: /local/etc/smail/config: parse error: unexpected end of attribute - - make some of the SMTP error messages more explanitory and think about - using continuation lines, such as this: - - 550-'SIZE=2088' sender address target - 550-domain 'cheddar.netmonger.net' is not a valid e-mail domain - 550 (there is no MX record in the DNS for it). - - think about adding eqic{, ltic{, gtic{ operators that unify the case of their arguments before testing. --- 195,200 ---- *************** *** 265,271 **** is useful for clearing out mail directed to a machine which has been down for awhile. ! - implement ETRN from RFC 1985 ala the above. - implement other standards-track SMTP extensions.... --- 255,262 ---- is useful for clearing out mail directed to a machine which has been down for awhile. ! - implement ETRN from RFC 1985 ala the above (patch already available, ! but needs some performance enhancements and support for '-R'). - implement other standards-track SMTP extensions.... Index: master/smail/level diff -c master/smail/level:1.85 master/smail/level:1.87 *** master/smail/level:1.85 Wed Sep 8 01:30:58 1999 --- master/smail/level Sun Sep 19 18:48:53 1999 *************** *** 1,2 **** ! #ident "@(#)smail:$Name: RELEASE-3_2_0_107 $:$Id: level,v 1.85 1999/09/08 05:30:58 woods Exp $" ! 3.2.0.107 Wed Sep 8 01:30:18 EDT 1999 --- 1,2 ---- ! #ident "@(#)smail:$Name: RELEASE-3_2_0_108 $:$Id: level,v 1.87 1999/09/19 22:48:53 woods Exp $" ! 3.2.0.108 Sun Sep 19 18:23:33 EDT 1999 Index: master/smail/conf/EDITME-dist diff -c master/smail/conf/EDITME-dist:1.95 master/smail/conf/EDITME-dist:1.96 *** master/smail/conf/EDITME-dist:1.95 Tue Sep 7 23:52:58 1999 --- master/smail/conf/EDITME-dist Thu Sep 16 18:19:14 1999 *************** *** 1,4 **** ! #ident "@(#)smail/conf:$Name: RELEASE-3_2_0_107 $:$Id: EDITME-dist,v 1.95 1999/09/08 03:52:58 woods Exp $" # # EDITME-dist - distribution standard EDITME # --- 1,4 ---- ! #ident "@(#)smail/conf:$Name: RELEASE-3_2_0_108 $:$Id: EDITME-dist,v 1.96 1999/09/16 22:19:14 woods Exp $" # # EDITME-dist - distribution standard EDITME # *************** *** 540,546 **** #MISC_DEFINES=SMAIL_LOG_STYLE=2 # Use 3.1.29 and newer logfile format #MISC_DEFINES=USE_LSEARCH_REGEXCMP # allow regexp's in lsearch db lookups #MISC_DEFINES=USE_SUNOS4_MALLOC_DEBUG:MALLOC_DEBUG_EVERY_DEBUG:MALLOC_DEBUG_LEVEL=2 ! MISC_DEFINES=NO_FORWARDTO_FILE:SMAIL_LOG_STYLE=2:USE_LSEARCH_REGEXCMP # HAVE - miscellaneous supported features --- 540,546 ---- #MISC_DEFINES=SMAIL_LOG_STYLE=2 # Use 3.1.29 and newer logfile format #MISC_DEFINES=USE_LSEARCH_REGEXCMP # allow regexp's in lsearch db lookups #MISC_DEFINES=USE_SUNOS4_MALLOC_DEBUG:MALLOC_DEBUG_EVERY_DEBUG:MALLOC_DEBUG_LEVEL=2 ! MISC_DEFINES="NO_FORWARDTO_FILE:SMAIL_LOG_STYLE=2:USE_LSEARCH_REGEXCMP" # HAVE - miscellaneous supported features *************** *** 574,580 **** # need to add the ident library to the LIBS. # LIBWHOSON - enable use of the WHOSON API library. # LIBWRAP - enable use of the TCP/IP wrapper library. ! # EHLO - have ESMTP sending support # # Many of these features are already enabled in the appropriate # OS configuration files, and do not need to be selected here... --- 574,580 ---- # need to add the ident library to the LIBS. # LIBWHOSON - enable use of the WHOSON API library. # LIBWRAP - enable use of the TCP/IP wrapper library. ! # EHLO - turn on ESMTP support # # Many of these features are already enabled in the appropriate # OS configuration files, and do not need to be selected here... *************** *** 652,670 **** #HAVE=RFC1413 # have the rfc1413 libraries #HAVE=LIBWHOSON # have the WHOSON API library #HAVE=LIBWRAP # have the tcp_wrappers library ! #HAVE=EHLO # have ESMTP sending support #HAVE=HDB_UUCP:NDBM # new DBM and HoneyDanBer UUCP #HAVE=BIND:HDB_UUCP:NDBM # Bind, new DBM, and HoneyDanBer UUCP # NO_HAVE - disable features # ! # You can use NO_HAVE to disable features set in the conf/os you # selected with OS_TYPE or to define other features *not* supported in # your configuration. # # WARNING: Any setting of this variable in the EDITME is appended to # the value given in the OSTYPE file. #NO_HAVE=DBM_PAGFNO # needed with 4.4BSD db(3) ndbm.h --- 652,675 ---- #HAVE=RFC1413 # have the rfc1413 libraries #HAVE=LIBWHOSON # have the WHOSON API library #HAVE=LIBWRAP # have the tcp_wrappers library ! #HAVE=EHLO # turn on ESMTP support #HAVE=HDB_UUCP:NDBM # new DBM and HoneyDanBer UUCP #HAVE=BIND:HDB_UUCP:NDBM # Bind, new DBM, and HoneyDanBer UUCP # NO_HAVE - disable features # ! # You can use NO_HAVE to disable features set in the conf/os file you # selected with OS_TYPE or to define other features *not* supported in # your configuration. # # WARNING: Any setting of this variable in the EDITME is appended to # the value given in the OSTYPE file. + # + # Note that these settings simply undefine the settings given by the + # HAVE variable. They do *not* define any NO_HAVE_* equivalents. To + # explicitly turn off something with a NO_ macro you need to define + # that macro in MISC_DEFINES or MISC_C_DEFINES. #NO_HAVE=DBM_PAGFNO # needed with 4.4BSD db(3) ndbm.h Index: master/smail/conf/EDITME-netbsdpkg diff -c master/smail/conf/EDITME-netbsdpkg:1.7 master/smail/conf/EDITME-netbsdpkg:1.8 *** master/smail/conf/EDITME-netbsdpkg:1.7 Fri Sep 3 17:37:42 1999 --- master/smail/conf/EDITME-netbsdpkg Sun Sep 19 16:06:11 1999 *************** *** 1,4 **** ! #ident "@(#)smail:$Name: RELEASE-3_2_0_107 $:$Id: EDITME-netbsdpkg,v 1.7 1999/09/03 21:37:42 woods Exp $" # # netbsdpkg -- a netbsd install under "$PREFIX" with lots of options # --- 1,4 ---- ! #ident "@(#)smail:$Name: RELEASE-3_2_0_108 $:$Id: EDITME-netbsdpkg,v 1.8 1999/09/19 20:06:11 woods Exp $" # # netbsdpkg -- a netbsd install under "$PREFIX" with lots of options # *************** *** 11,17 **** LDFLAGS="-g -O2 -pipe -L$PREFIX/lib" LIBS="-lident -lwrap -lwhoson" OS_TYPE=bsd4.4-lite ! MISC_DEFINES=SMAIL_LOG_STYLE=2:NO_FORWARDTO_FILE:USE_TARGET_DOMAIN:USE_LSEARCH_REGEXCMP:USE_STRICT_MX HAVE=RFC1413:EHLO:LIBWRAP:LIBWHOSON SMAIL_BIN_DIR=$PREFIX/bin # It would be nice to be able to force this to /etc/smail, but that --- 11,17 ---- LDFLAGS="-g -O2 -pipe -L$PREFIX/lib" LIBS="-lident -lwrap -lwhoson" OS_TYPE=bsd4.4-lite ! MISC_DEFINES=SMAIL_LOG_STYLE=2:NO_FORWARDTO_FILE:USE_TARGET_DOMAIN:USE_LSEARCH_REGEXCMP:USE_STRICT_MX:LOG_SMTP_NON_COMPLIANCE:LOG_SMTP_ILLEGAL_OPERAND_WARNING HAVE=RFC1413:EHLO:LIBWRAP:LIBWHOSON SMAIL_BIN_DIR=$PREFIX/bin # It would be nice to be able to force this to /etc/smail, but that Index: master/smail/conf/EDITME-newmost diff -c master/smail/conf/EDITME-newmost:1.6 master/smail/conf/EDITME-newmost:1.7 *** master/smail/conf/EDITME-newmost:1.6 Sun Jul 18 21:33:29 1999 --- master/smail/conf/EDITME-newmost Sun Sep 19 16:06:11 1999 *************** *** 1,4 **** ! #ident "@(#)smail/conf:$Name: RELEASE-3_2_0_107 $:$Id: EDITME-newmost,v 1.6 1999/07/19 01:33:29 woods Exp $" # # most (the new most) - a completely stock, native, NetBSD-1.x install, # but with some common smail options enabled --- 1,4 ---- ! #ident "@(#)smail/conf:$Name: RELEASE-3_2_0_108 $:$Id: EDITME-newmost,v 1.7 1999/09/19 20:06:11 woods Exp $" # # most (the new most) - a completely stock, native, NetBSD-1.x install, # but with some common smail options enabled *************** *** 8,14 **** LDFLAGS="-g -O2 -pipe -L/usr/local/lib" LIBS="-lident -lwrap" OS_TYPE=bsd4.4-lite ! MISC_DEFINES='SMAIL_LOG_STYLE=2:NO_FORWARDTO_FILE:USE_TARGET_DOMAIN:USE_LSEARCH_REGEXCMP:USE_STRICT_MX' HAVE=RFC1413:EHLO:LIBWRAP ALIASES_FILE=/etc/aliases ALIASES_TYPE=lsearch --- 8,14 ---- LDFLAGS="-g -O2 -pipe -L/usr/local/lib" LIBS="-lident -lwrap" OS_TYPE=bsd4.4-lite ! MISC_DEFINES='SMAIL_LOG_STYLE=2:NO_FORWARDTO_FILE:USE_TARGET_DOMAIN:USE_LSEARCH_REGEXCMP:USE_STRICT_MX:LOG_SMTP_NON_COMPLIANCE:LOG_SMTP_ILLEGAL_OPERAND_WARNING' HAVE=RFC1413:EHLO:LIBWRAP ALIASES_FILE=/etc/aliases ALIASES_TYPE=lsearch Index: master/smail/conf/driver/arpa-network diff -c master/smail/conf/driver/arpa-network:1.6 master/smail/conf/driver/arpa-network:1.7 *** master/smail/conf/driver/arpa-network:1.6 Wed May 29 16:27:17 1996 --- master/smail/conf/driver/arpa-network Thu Sep 16 20:36:35 1999 *************** *** 1,4 **** ! # @(#) $Id: arpa-network,v 1.6 1996/05/29 20:27:17 woods Exp $ # This file lists the drivers used in a UNIX environment with # BSD networking and the Berkeley Internet Name Domain server. --- 1,4 ---- ! #ident "@(#)smail/conf/driver:$Name: RELEASE-3_2_0_108 $:$Id: arpa-network,v 1.7 1999/09/17 00:36:35 woods Exp $" # This file lists the drivers used in a UNIX environment with # BSD networking and the Berkeley Internet Name Domain server. *************** *** 84,89 **** transport appendfile nocache nofinish # use this only if you have BSD networking routines - transport smtp source=tcpsmtp.c nocache nofinish transport tcpsmtp nocache nofinish transport library smtplib.c smtplib.h --- 84,88 ---- Index: master/smail/conf/os/linux-glibc2 diff -c /dev/null master/smail/conf/os/linux-glibc2:2.1 *** /dev/null Sun Sep 19 19:11:56 1999 --- master/smail/conf/os/linux-glibc2 Sun Sep 19 17:30:48 1999 *************** *** 0 **** --- 1,112 ---- + #ident "@(#)smail/conf/os:$Name: RELEASE-3_2_0_108 $:$Id: linux-glibc2,v 2.1 1999/09/19 21:30:48 woods Exp $" + # + # linux - describe characteristics of Linux-based GNU systems + # + # Original by Ian Jackson for Debian GNU/Linux + # + # GNU Libc-2 support supplied by Eugene Crosser . + + # Richard Stallman writes: + # + # Linux is a kernel; the system as a whole is a variant of the GNU + # system. + # + # When people call these GNU systems just "Linux", that isn't really + # accurate. It also undermines the spreading of the philosophy that + # encourages people to write more free software (since the name "Linux" + # has become associated with a different philosophy). So if you could + # avoid doing this, it would be useful. + + . $ROOT/conf/os/posix + + # lie through our teeth.... + OSNAMES=LINUX:UNIX:$OSNAMES + + # ARCH_TYPE - this is likely true except for the DEC Alpha port... + ARCH_TYPE=32bit + + # According to dan@gasboy.com (Dan Wilder) the libc-4.7.6 version of + # flock() needs the file opened in write mode.... If you have this + # older version of the libc, you may need to add: + # #define LOCK_REQUIRES_WRITE + # (between the #include's). + # + LOCKING_PROTOCOL="\ + #include + #include + #define lock_fd(fd) (flock((fd), LOCK_EX|LOCK_NB) < 0? FAIL: SUCCEED) + #define lock_fd_wait(fd) (flock((fd), LOCK_EX) < 0? FAIL: SUCCEED) + #define unlock_fd(fd) ((void) flock((fd), LOCK_UN)) + #define unlock_fd_wait(fd) ((void) flock((fd), LOCK_UN)) + #define lock_fd_rd_wait(fd) (flock((fd), LOCK_SH) < 0? FAIL: SUCCEED) + " + + #LOCK_BY_NAME=TRUE + #FLOCK_MAILBOX=TRUE + + MAILBOX_DIR=/var/spool/mail + + DRIVER_CONFIGURATION=arpa-network # includes BIND/DNS router + + RANLIB=ranlib # Behavior compatible with BSD + + # According to Johannes Stille + # RedHat 3.0.4 with libc 5.3.12 has all of these.... + # + # We choose NDBM in assumption 4.4BSD db(3) with ndbm.h emulation is + # available in libc.a. Most GNU/Linux systems have GDBM too, but so + # far as I know it's bigger and slower than db -- even sdbm may be + # better. If your ndbm.h doesn't include db.h, then this won't work + # and you should look at EDITME-dist for further hints. + # + # OS_HAVE - name the capabilities of this operating system + HAVE=BIND:BSD_NETWORKING:COMSAT:FSYNC:FTRUNCATE\ + :FGETPWENT:GETHOSTNAME:HASH_BANG:NDBM:RENAME:RLIMIT\ + :SETGROUPS:SYSEXITS:STRERROR:ULIMIT:MEMMOVE:HDB_UUCP:$HAVE + + # NO_HAVE - what features are not available on this operating system + #[[ this is because of the db(3) emulation of ndbm ]] + NO_HAVE=DBM_PAGFNO + + LIBS="-lresolv -ldb" + + # NOTE: GNU/Linux systems seem to have a that's compatible + # with the old SysV stuff, so the user might want to add USE_REGEXP_H + # to the MISC_DEFINES in their EDITME. Some GNU/Linux systems also + # seem to have a P1003.2 too, and this should be used if it + # works, and will be tried since none of the UNIX_SYS5* are on (nor + # should be on) by default. + # + #MISC_DEFINES=USE_REGEXP_H + + MISC_C_DEFINES=' + #define DBM_SUFFIX ".db" + ' + + : SOCKET_INCLUDES=' + #include + #include + #include + #include + #ifdef HAVE_BIND + # undef NOERROR /* remove conflict in SVR4 header files */ + # include + # include + #endif + ' + + SMAIL_NOBODY=nobody # BSD and SunOS-like systems + SECURE_PATH=/bin:/usr/bin:/sbin:/usr/sbin + + MAN1=/usr/man/man1 + MAN1_EXT=1 + MAN3=/usr/man/man3 + MAN3_EXT=3 + MAN8=/usr/man/man8 + MAN8_EXT=8 + + COMPRESS=gzip + COMP_FLAG=-9f + DOT_Z=.gz + UNCOMPRESS=gunzip + ZCAT=zcat Index: master/smail/man/man5/smailconf.an diff -c master/smail/man/man5/smailconf.an:1.27 master/smail/man/man5/smailconf.an:1.30 *** master/smail/man/man5/smailconf.an:1.27 Fri Sep 3 17:41:16 1999 --- master/smail/man/man5/smailconf.an Sun Sep 19 18:35:35 1999 *************** *** 1,4 **** ! .\"#ident "@(#)smail/man/man5:$Name: RELEASE-3_2_0_107 $:$Id: smailconf.an,v 1.27 1999/09/03 21:41:16 woods Exp $" .\" .de Vb .ft CW --- 1,4 ---- ! .\"#ident "@(#)smail/man/man5:$Name: RELEASE-3_2_0_108 $:$Id: smailconf.an,v 1.30 1999/09/19 22:35:35 woods Exp $" .\" .de Vb .ft CW *************** *** 13,19 **** .if n .na .if n .nh .\" ! .TH SMAILCONF X_MAN5_EXT_X "$Name: RELEASE-3_2_0_107 $" "Smail-3" "Local" .\" .SH "NAME" X_LIB_DIR_X/config \- smail global variables configuration --- 13,19 ---- .if n .na .if n .nh .\" ! .TH SMAILCONF X_MAN5_EXT_X "$Name: RELEASE-3_2_0_108 $" "Smail-3" "Local" .\" .SH "NAME" X_LIB_DIR_X/config \- smail global variables configuration *************** *** 1122,1128 **** \& ESMTP spoken here .Ve .TP 4 ! .B "smtp_debug" type: .I boolean .br --- 1122,1128 ---- \& ESMTP spoken here .Ve .TP 4 ! .B "smtp_allow_debug" type: .I boolean .br *************** *** 1241,1257 **** .B smtp_hello_verify for standards conformance notes. .TP 4 ! .B "smtp_info" type: .I boolean .br default value: .I on .IP ! This boolean variable enables the use of the SMTP commands ``VRFY'' and ! ``EXPN''. Some sites may wish to disable these commands to prevent ! information being gained about their systems. In general there is not ! great loss of security by leaving them enabled. .TP 4 .B "smtp_max_recipients" type: --- 1241,1256 ---- .B smtp_hello_verify for standards conformance notes. .TP 4 ! .B "smtp_allow_expn" type: .I boolean .br default value: .I on .IP ! This boolean variable enables the use of the SMTP ``EXPN'' command. ! Some sites may wish to disable this command to prevent divulging the ! contents of mailing lists and aliases. .TP 4 .B "smtp_max_recipients" type: *************** *** 1372,1377 **** --- 1371,1415 ---- internet to allow a mail host to have only an A RR. In the default configuration smail will also search for DNS A RRs that match the domain part of the sender address. + .TP 4 + .B "smtp_sender_no_verify" + type: + .I string + .br + default value: (none) + .IP + A colon-separated list of host IP patterns that are allowed to deliver + remote mail via SMTP and which do not need or want target addresses + specified in ``MAIL FROM:'' commands to be verified immediately during + message delivery. Setting this to a list of local network numbers helps + clients deliver mail immediately to the queue without needing to wait + for possible DNS lookup timeouts. Some MUAs (and even some primitive + MTAs) that use SMTP for mail delivery do not have sufficient or + adjustable timeouts and may fail to deliver mail when network or remote + nameserver problems cause delays. + .IP + Note that disabling sender address verifcation unnecessarily will make + it possible for users to use incorrect sender addresses which may + prevent them from ever receiving bounces or even replies (the latter in + the common case where the sender's MUA uses the ``From:'' address as the + sender address too). Unless you run Smail on a dial-up link and don't + want it to connect for every queued message then do not set this + variable! + .IP + The magic keyword + .I localnet + represents a run-time generated pattern constructed to represent + the classical IP network for the local interface address of the current + connection. + .IP + There is compile-time optional support for a magic keyword + .I whoson + which can be used to query a WHOSON server for additonal IP numbers + which are currently authorised to relay mail remotely via SMTP. + .IP + See + .B smtp_hello_broken_allow + for and explanation of wild-cards and caveats. .TP 4 .B "spool_dirs" type: Index: master/smail/src/Makefile diff -c master/smail/src/Makefile:1.44 master/smail/src/Makefile:1.45 *** master/smail/src/Makefile:1.44 Fri Sep 3 16:04:59 1999 --- master/smail/src/Makefile Thu Sep 16 16:03:46 1999 *************** *** 1,5 **** # ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_107 $:$Id: Makefile,v 1.44 1999/09/03 20:04:59 woods Exp $" # # Makefile for the smail program # --- 1,5 ---- # ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_108 $:$Id: Makefile,v 1.45 1999/09/16 20:03:46 woods Exp $" # # Makefile for the smail program # *************** *** 331,335 **** --- 331,339 ---- version.o: version.h smtprecv.o: iobpeek.h config.o: config.h + default.o: config.h smail.h direct.h route.h transport.h bindlib.h extern.h + default.o: directors/include.h directors/aliasfile.h directors/fwdfile.h directors/user.h directors/smartuser.h + default.o: routers/gethost.h routers/uuname.h routers/pathalias.h routers/smarthost.h routers/reroute.h + default.o: transports/pipe.h transports/appendfile.h transports/tcpsmtp.h transports/smtplib.h # DO NOT REMOVE THIS LINE, OR "make depend" WILL NOT WORK Index: master/smail/src/addr.c diff -c master/smail/src/addr.c:1.29 master/smail/src/addr.c:1.32 *** master/smail/src/addr.c:1.29 Tue Sep 7 17:56:26 1999 --- master/smail/src/addr.c Sun Sep 19 17:21:23 1999 *************** *** 1,5 **** /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_107 $:$Id: addr.c,v 1.29 1999/09/07 21:56:26 woods Exp $" */ /* --- 1,5 ---- /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_108 $:$Id: addr.c,v 1.32 1999/09/19 21:21:23 woods Exp $" */ /* *************** *** 778,789 **** int level; /* ! * remove extra white space and comments from the address */ arg = COPY_STRING(arg); strip_rfc822_comments(arg); p = arg; while ((c = *p)) { --- 778,790 ---- int level; /* ! * remove extra white space and RFC822 comments from the address */ arg = COPY_STRING(arg); strip_rfc822_comments(arg); + strip_rfc822_whitespace(arg); p = arg; while ((c = *p)) { *************** *** 860,868 **** } /* ! * strip_rfc822_comments - strip RFC822 comments and white space form a string */ - void strip_rfc822_comments(s) char *s; --- 861,868 ---- } /* ! * strip_rfc822_comments - destructively strip RFC822 comments from a string */ void strip_rfc822_comments(s) char *s; *************** *** 870,884 **** char *p, *q; int c; int level; - static char delims[] = "@:;<>.,"; - int space = 0; p = q = s; while ((c = *p++)) { - if (isspace(c)) { - space = 1; - continue; - } if (c == '(') { level = 1; --- 870,878 ---- *************** *** 901,912 **** --- 895,979 ---- } continue; } + if (c == '\\') { + *q++ = c; + if ((c = *p)) { + *q++ = c; + p++; + } + continue; + } + if (c == '"') { + *q++ = c; + while ((c = *p)) { + p++; + *q++ = c; + if (c == '"') + break; + if (c == '\\') { + if ((c = *p)) { + *q++ = c; + p++; + } + } + } + continue; + } + *q++ = c; + } + *q++ = '\0'; + } + + /* + * strip_rfc822_whitespace - destructively strip *extra* whitespace from an + * RFC822 address + */ + void + strip_rfc822_whitespace(s) + char *s; + { + char *p, *q; + int c; + int level; + static char delims[] = "@:;<>().,"; + int space = 0; + + p = q = s; + while ((c = *p++)) { + if (isspace(c)) { + space = 1; + continue; + } if (space) { space = 0; if (q > s && !strchr(delims, *(q - 1)) && !strchr(delims, c)) { *q++ = ' '; } } + if (c == '(') { + level = 1; + + while ((c = *p++)) { + *q++ = c; + if (c == '(') { + level++; + continue; + } + if (c == ')') { + --level; + if (level == 0) + break; + continue; + } + if (c == '\\') { + if (*p) { + *q++ = c; + p++; + } + } + } + continue; + } if (c == '\\') { *q++ = c; if ((c = *p)) { *************** *** 1542,1550 **** } } } else { ! char line[4096]; ! while (fgets(line, sizeof(line), stdin) != NULL) { (void)fprintf(stderr, "input: %s\n", line); /* preparse the address to get rid of mutant forms */ --- 1609,1617 ---- } } } else { ! char *line; ! while ((line = read_line(stdin))) { (void)fprintf(stderr, "input: %s\n", line); /* preparse the address to get rid of mutant forms */ Index: master/smail/src/config.c diff -c master/smail/src/config.c:1.37 master/smail/src/config.c:1.39 *** master/smail/src/config.c:1.37 Sun Aug 8 12:46:11 1999 --- master/smail/src/config.c Sun Sep 19 16:02:33 1999 *************** *** 1,5 **** /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_107 $:$Id: config.c,v 1.37 1999/08/08 16:46:11 woods Exp $" */ /* --- 1,5 ---- /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_108 $:$Id: config.c,v 1.39 1999/09/19 20:02:33 woods Exp $" */ /* *************** *** 99,112 **** int smtp_accept_max = SMTP_ACCEPT_MAX; /* max simultaneous SMTPs to accept */ int smtp_accept_queue = SMTP_ACCEPT_QUEUE; /* simultaneous SMTPs to queueonly */ char *smtp_banner = SMTP_BANNER; /* smtp startup banner message */ ! int smtp_debug = SMTP_DEBUG; /* allow DEBUG command in SMTP */ ! int smtp_info = SMTP_INFO; /* allow EXPN/VRFY commanda in SMTP */ char *smtp_recipient_no_verify = SMTP_RECIPIENT_NO_VERIFY; /* ip list for not verifying RCPT TO */ char *smtp_remote_allow = SMTP_REMOTE_ALLOW; /* ip list that can send remote smtp */ int smtp_hello_verify = SMTP_HELLO_VERIFY; /* verify HELO/EHLO host has A RR matching sockaddr */ char *smtp_hello_broken_allow = SMTP_HELLO_BROKEN_ALLOW; /* ip list that can avoid hello verification */ int smtp_hello_verify_literal = SMTP_HELLO_VERIFY_LITERAL; /* verify HELO/EHLO domain literal has PTR RR */ int smtp_hello_verify_ptr = SMTP_HELLO_VERIFY_PTR; /* verify HELO/EHLO matches PTR RR for sockaddr */ int smtp_sender_verify_mx_only = SMTP_SENDER_VERIFY_MX_ONLY; /* require MX RRs for MAIL FROM: hosts */ int smtp_max_recipients = SMTP_MAX_RECIPIENTS; /* maximum recipients per SMTP connect */ int debug_pause_for_smtp_connections = 0; /* seconds to pause after child fork for debugger connect */ --- 99,113 ---- int smtp_accept_max = SMTP_ACCEPT_MAX; /* max simultaneous SMTPs to accept */ int smtp_accept_queue = SMTP_ACCEPT_QUEUE; /* simultaneous SMTPs to queueonly */ char *smtp_banner = SMTP_BANNER; /* smtp startup banner message */ ! int smtp_allow_debug = SMTP_ALLOW_DEBUG; /* allow DEBUG command in SMTP */ ! int smtp_allow_expn = SMTP_ALLOW_EXPN; /* allow EXPN commanda in SMTP */ char *smtp_recipient_no_verify = SMTP_RECIPIENT_NO_VERIFY; /* ip list for not verifying RCPT TO */ char *smtp_remote_allow = SMTP_REMOTE_ALLOW; /* ip list that can send remote smtp */ int smtp_hello_verify = SMTP_HELLO_VERIFY; /* verify HELO/EHLO host has A RR matching sockaddr */ char *smtp_hello_broken_allow = SMTP_HELLO_BROKEN_ALLOW; /* ip list that can avoid hello verification */ int smtp_hello_verify_literal = SMTP_HELLO_VERIFY_LITERAL; /* verify HELO/EHLO domain literal has PTR RR */ int smtp_hello_verify_ptr = SMTP_HELLO_VERIFY_PTR; /* verify HELO/EHLO matches PTR RR for sockaddr */ + char *smtp_sender_no_verify = SMTP_SENDER_NO_VERIFY; /* ip list for not verifying MAIL FROM */ int smtp_sender_verify_mx_only = SMTP_SENDER_VERIFY_MX_ONLY; /* require MX RRs for MAIL FROM: hosts */ int smtp_max_recipients = SMTP_MAX_RECIPIENTS; /* maximum recipients per SMTP connect */ int debug_pause_for_smtp_connections = 0; /* seconds to pause after child fork for debugger connect */ Index: master/smail/src/config.h diff -c master/smail/src/config.h:1.64 master/smail/src/config.h:1.66 *** master/smail/src/config.h:1.64 Wed Feb 3 00:25:29 1999 --- master/smail/src/config.h Sun Sep 19 16:02:33 1999 *************** *** 1,5 **** /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_107 $:$Id: config.h,v 1.64 1999/02/03 05:25:29 woods Exp $" */ /* --- 1,5 ---- /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_108 $:$Id: config.h,v 1.66 1999/09/19 20:02:33 woods Exp $" */ /* *************** *** 592,615 **** #endif /* ! * Allow debugging to be used in SMTP dialogs. This allows the ! * remote end to see the debugging output from smail, but does not ! * have any other affects. If this is TRUE, the DEBUG command in ! * SMTP turns on debugging and sets its level. If this is FALSE, ! * the DEBUG command only produces a cute message. This is only ! * useful if NODEBUG is not defined. */ ! #ifndef SMTP_DEBUG ! # define SMTP_DEBUG TRUE /* probably reasonable */ #endif /* ! * Allow the information commands EXPN & VRFY to be used in SMTP dialogs. * This allows the remote end to get information about your site * so the paranoid may wish to disable this. */ ! #ifndef SMTP_INFO ! # define SMTP_INFO TRUE /* probably reasonable */ #endif /* --- 592,614 ---- #endif /* ! * Allow debugging to be used in SMTP dialogs. This allows the remote end to ! * see the debugging output from smail, but does not have any other affects. ! * If this is TRUE, the DEBUG command in SMTP turns on debugging and sets its ! * level. If this is FALSE, the DEBUG command only produces a cute message. ! * This is only really useful if NODEBUG is not defined. */ ! #ifndef SMTP_ALLOW_DEBUG ! # define SMTP_ALLOW_DEBUG TRUE /* probably reasonable */ #endif /* ! * Allow the information commands EXPN to be used in SMTP dialogs. * This allows the remote end to get information about your site * so the paranoid may wish to disable this. */ ! #ifndef SMTP_ALLOW_EXPN ! # define SMTP_ALLOW_EXPN TRUE /* probably reasonable */ #endif /* *************** *** 670,675 **** --- 669,675 ---- else {for }}\ ; $spool_date\n\t\ ($version_string built $compile_date)" + /* XXX stupid hack for emacs " */ #endif /* *************** *** 828,833 **** --- 828,842 ---- #ifndef SMTP_HELLO_VERIFY_PTR # define SMTP_HELLO_VERIFY_PTR 0 /* XXX not many will yet... */ + #endif + + /* + * The default list of networks from which do not need/want the MAIL FROM: + * address to be verified. + */ + + #ifndef SMTP_SENDER_NO_VERIFY + # define SMTP_SENDER_NO_VERIFY NULL #endif /* Index: master/smail/src/debug.h diff -c master/smail/src/debug.h:1.11 master/smail/src/debug.h:1.12 *** master/smail/src/debug.h:1.11 Sun Dec 7 19:45:18 1997 --- master/smail/src/debug.h Thu Sep 16 16:03:18 1999 *************** *** 1,5 **** /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_107 $:$Id: debug.h,v 1.11 1997/12/08 00:45:18 woods Exp $" */ /* --- 1,5 ---- /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_108 $:$Id: debug.h,v 1.12 1999/09/16 20:03:18 woods Exp $" */ /* *************** *** 139,144 **** --- 139,168 ---- (void)fflush(errfile); \ } \ } + # define DEBUG7(d,m,a,b,c,e,f,g,h) \ + { \ + if ((d) <= debug && errfile) { \ + MALLOC_DEBUG_HOOK(MALLOC_VERIFY_LEVEL); \ + (void)dprintf(errfile,(m),(a),(b),(c),(e),(f),(g),(h));\ + (void)fflush(errfile); \ + } \ + } + # define DEBUG8(d,m,a,b,c,e,f,g,h,i) \ + { \ + if ((d) <= debug && errfile) { \ + MALLOC_DEBUG_HOOK(MALLOC_VERIFY_LEVEL); \ + (void)dprintf(errfile,(m),(a),(b),(c),(e),(f),(g),(h),(i));\ + (void)fflush(errfile); \ + } \ + } + # define DEBUG9(d,m,a,b,c,e,f,g,h,i,j) \ + { \ + if ((d) <= debug && errfile) { \ + MALLOC_DEBUG_HOOK(MALLOC_VERIFY_LEVEL); \ + (void)dprintf(errfile,(m),(a),(b),(c),(e),(f),(g),(h),(i),(j));\ + (void)fflush(errfile); \ + } \ + } #else /* NODEBUG */ # define DEBUG(d,m) # define DEBUG1(d,m,a) *************** *** 147,152 **** --- 171,179 ---- # define DEBUG4(d,m,a,b,c,e) # define DEBUG5(d,m,a,b,c,e,f) # define DEBUG6(d,m,a,b,c,e,f,g) + # define DEBUG7(d,m,a,b,c,e,f,g) + # define DEBUG8(d,m,a,b,c,e,f,g) + # define DEBUG9(d,m,a,b,c,e,f,g) #endif /* NODEBUG */ /* Index: master/smail/src/extern.h diff -c master/smail/src/extern.h:1.69 master/smail/src/extern.h:1.73 *** master/smail/src/extern.h:1.69 Sun Aug 8 12:46:12 1999 --- master/smail/src/extern.h Sun Sep 19 17:40:15 1999 *************** *** 1,5 **** /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_107 $:$Id: extern.h,v 1.69 1999/08/08 16:46:12 woods Exp $" */ /* --- 1,5 ---- /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_108 $:$Id: extern.h,v 1.73 1999/09/19 21:40:15 woods Exp $" */ /* *************** *** 93,100 **** extern char *smtp_banner; /* smtp startup banner message */ extern int smtp_accept_max; /* max simultaneous SMTPs to accept */ extern int smtp_accept_queue; /* simultaneous SMTPs until queueonly */ ! extern int smtp_debug; /* allow DEBUG command in SMTP */ ! extern int smtp_info; /* allow EXPN/VRFY commands in SMTP */ extern char *smtp_recipient_no_verify; /* ip list for not verifying RCPT TO */ extern char *smtp_remote_allow; /* ip list that can send remote smtp */ extern char *smtp_local_net; /* the local network calculated from src. addr */ --- 93,100 ---- extern char *smtp_banner; /* smtp startup banner message */ extern int smtp_accept_max; /* max simultaneous SMTPs to accept */ extern int smtp_accept_queue; /* simultaneous SMTPs until queueonly */ ! extern int smtp_allow_debug; /* allow DEBUG command in SMTP */ ! extern int smtp_allow_expn; /* allow EXPN command in SMTP */ extern char *smtp_recipient_no_verify; /* ip list for not verifying RCPT TO */ extern char *smtp_remote_allow; /* ip list that can send remote smtp */ extern char *smtp_local_net; /* the local network calculated from src. addr */ *************** *** 102,107 **** --- 102,108 ---- extern char *smtp_hello_broken_allow; /* ip list that can avoid hello verification */ extern int smtp_hello_verify_literal; /* verify HELO/EHLO domain literal has PTR RR */ extern int smtp_hello_verify_ptr; /* verify HELO/EHLO matches PTR RR for sockaddr */ + extern char *smtp_sender_no_verify; /* ip list for not verifying MAIL FROM */ extern int smtp_sender_verify_mx_only; /* require MX RRs for MAIL FROM: hosts */ extern int smtp_max_recipients; /* maximum recipients per SMTP connect */ extern int debug_pause_for_smtp_connections; /* seconds to pause after child fork for debugger connect */ *************** *** 260,265 **** --- 261,267 ---- extern char *build_partial_uucp_route(); extern void split_addr_list(); extern void strip_rfc822_comments(); + extern void strip_rfc822_whitespace(); extern struct addr *alloc_addr(); extern void insert_addr_list(); extern struct addr *addr_sort(); *************** *** 355,361 **** extern void compute_nobody(); extern void input_signals(); extern void processing_signals(); ! extern void deliver_signals(); extern void test_addresses(); extern void perform_deliver_mail(); extern void deliver_mail(); --- 357,363 ---- extern void compute_nobody(); extern void input_signals(); extern void processing_signals(); ! extern void delivery_signals(); extern void test_addresses(); extern void perform_deliver_mail(); extern void deliver_mail(); Index: master/smail/src/field.c diff -c master/smail/src/field.c:1.11 master/smail/src/field.c:1.12 *** master/smail/src/field.c:1.11 Thu Mar 6 22:35:58 1997 --- master/smail/src/field.c Sun Sep 19 17:21:23 1999 *************** *** 1,5 **** /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_107 $:$Id: field.c,v 1.11 1997/03/07 03:35:58 woods Exp $" */ /* --- 1,5 ---- /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_108 $:$Id: field.c,v 1.12 1999/09/19 21:21:23 woods Exp $" */ /* *************** *** 1590,1598 **** argv++; } } else { ! char line[4096]; ! while (fgets(line, sizeof(line), stdin) != NULL) { (void)fprintf(stderr, "input: %s\n", line); s = index(line, ':'); if (s) { --- 1590,1598 ---- argv++; } } else { ! char *line; ! while ((line = read_line(stdin))) { (void)fprintf(stderr, "input: %s\n", line); s = index(line, ':'); if (s) { Index: master/smail/src/hash.c diff -c master/smail/src/hash.c:1.10 master/smail/src/hash.c:1.11 *** master/smail/src/hash.c:1.10 Fri Nov 6 15:15:10 1998 --- master/smail/src/hash.c Sun Sep 19 17:21:23 1999 *************** *** 1,5 **** /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_107 $:$Id: hash.c,v 1.10 1998/11/06 20:15:10 woods Exp $" */ /* --- 1,5 ---- /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_108 $:$Id: hash.c,v 1.11 1999/09/19 21:21:23 woods Exp $" */ /* *************** *** 1087,1097 **** #ifdef STANDALONE #include #include #define TABLE_LEN 3 /* use only a few slots to stress the chain code */ - #define INPUT_SIZE (70*1024) /* max input line */ char *tempname = "/tmp/hashtestXXXXXX"; /* tempory hash file name */ --- 1087,1097 ---- #ifdef STANDALONE + #include "dys.h" #include #include #define TABLE_LEN 3 /* use only a few slots to stress the chain code */ char *tempname = "/tmp/hashtestXXXXXX"; /* tempory hash file name */ *************** *** 1101,1107 **** char *argv[]; /* args */ { int i; /* index */ ! char buf[INPUT_SIZE+1]; /* the input buffer for stdin args */ struct hash *cur; /* pointer to walk the table */ struct hash_table *table; /* our allocated table */ struct hash_table *tableic; /* allocated table without regard to case */ --- 1101,1107 ---- char *argv[]; /* args */ { int i; /* index */ ! char *buf; /* the input buffer for stdin args */ struct hash *cur; /* pointer to walk the table */ struct hash_table *table; /* our allocated table */ struct hash_table *tableic; /* allocated table without regard to case */ *************** *** 1137,1143 **** * special case: no args means read one arg per line */ if (argc == 1) { ! while(fgets(buf, INPUT_SIZE, stdin) != NULL) { i = strlen(buf); buf[i-1] = '\0'; DEBUG1(DBG_HASH_LO, --- 1137,1143 ---- * special case: no args means read one arg per line */ if (argc == 1) { ! while ((buf = read_line(stdin))) { i = strlen(buf); buf[i-1] = '\0'; DEBUG1(DBG_HASH_LO, Index: master/smail/src/log.c diff -c master/smail/src/log.c:1.24 master/smail/src/log.c:1.25 *** master/smail/src/log.c:1.24 Thu Jul 22 01:03:15 1999 --- master/smail/src/log.c Sun Sep 19 17:21:24 1999 *************** *** 1,5 **** /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_107 $:$Id: log.c,v 1.24 1999/07/22 05:03:15 woods Exp $" */ /* --- 1,5 ---- /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_108 $:$Id: log.c,v 1.25 1999/09/19 21:21:24 woods Exp $" */ /* *************** *** 797,803 **** main() { register int c; /* hold key for current operation */ ! char line[4096]; /* buffer to hold a line of input */ char *p; while ((c = getchar()) != EOF) { --- 797,803 ---- main() { register int c; /* hold key for current operation */ ! char *line; /* a line of input */ char *p; while ((c = getchar()) != EOF) { *************** *** 826,845 **** } break; case 'p': ! fgets(line, sizeof(line), stdin); ! panic(EX_OSERR, line); break; case 'l': ! fgets(line, sizeof(line), stdin); ! write_log(WRITE_LOG_SYS, line); break; case 'm': ! fgets(line, sizeof(line), stdin); ! write_log(WRITE_LOG_MLOG, line); break; case 'L': ! fgets(line, sizeof(line), stdin); ! write_log(WRITE_LOG_MLOG|WRITE_LOG_SYS|WRITE_LOG_PANIC); break; case ' ': case '\t': --- 826,845 ---- } break; case 'p': ! if ((line = read_line(stdin))) ! panic(EX_OSERR, line); break; case 'l': ! if ((line = read_line(stdin))) ! write_log(WRITE_LOG_SYS, line); break; case 'm': ! if ((line = read_line(stdin))) ! write_log(WRITE_LOG_MLOG, line); break; case 'L': ! if ((line = read_line(stdin))) ! write_log(WRITE_LOG_MLOG|WRITE_LOG_SYS|WRITE_LOG_PANIC); break; case ' ': case '\t': Index: master/smail/src/modes.c diff -c master/smail/src/modes.c:1.84 master/smail/src/modes.c:1.88 *** master/smail/src/modes.c:1.84 Thu Jul 22 01:10:22 1999 --- master/smail/src/modes.c Sun Sep 19 17:40:16 1999 *************** *** 1,5 **** /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_107 $:$Id: modes.c,v 1.84 1999/07/22 05:10:22 woods Exp $" */ /* --- 1,5 ---- /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_108 $:$Id: modes.c,v 1.88 1999/09/19 21:40:16 woods Exp $" */ /* *************** *** 17,23 **** * * external functions: build_host_strings, compute_nobody, * input_signals, processing_signals, ! * deliver_signals, test_addresses, * perform_deliver_mail, deliver_mail, * daemon_mode, noop_mode, verify_addresses, * print_version, print_copying_file, --- 17,23 ---- * * external functions: build_host_strings, compute_nobody, * input_signals, processing_signals, ! * delivery_signals, test_addresses, * perform_deliver_mail, deliver_mail, * daemon_mode, noop_mode, verify_addresses, * print_version, print_copying_file, *************** *** 417,423 **** void test_addresses() { - char line[4096]; /* plenty of space for input lines */ int stdin_is_a_tty = isatty(0); X_PANIC_OKAY(); --- 417,422 ---- *************** *** 434,446 **** struct addr *fail; char *error; int form = FAIL; ! char *lp = line; ! if (!fgets(line, sizeof(line), stdin)) { break; } strip_rfc822_comments(lp); ! if (*lp == '\0') { continue; } --- 433,446 ---- struct addr *fail; char *error; int form = FAIL; ! char *lp; ! if (!(lp = read_line(stdin))) { break; } strip_rfc822_comments(lp); ! strip_rfc822_whitespace(lp); ! if (!*lp) { continue; } *************** *** 504,512 **** break; default: ! (void) fprintf(stderr, ! "%s ... internal error in resolve_addr_list\n", ! line); break; } } --- 504,511 ---- break; default: ! (void) fprintf(stderr, "%s ... internal error in resolve_addr_list\n", ! lp); break; } } *************** *** 894,900 **** { int ls; /* listen socket */ int as; /* accept socket */ ! struct sockaddr_in sin, from; /* from is currently */ struct servent *smtp_service; /* smtp service file entry */ struct hostent *hostentp; /* host file entry */ int port; --- 893,899 ---- { int ls; /* listen socket */ int as; /* accept socket */ ! struct sockaddr_in sockin, from; /* from is currently */ struct servent *smtp_service; /* smtp service file entry */ struct hostent *hostentp; /* host file entry */ int port; *************** *** 939,945 **** } port = smtp_service->s_port; } ! (void) bzero((char *)&sin, sizeof(sin)); ls = socket(AF_INET, SOCK_STREAM, 0); if (ls < 0) { write_log(WRITE_LOG_SYS, "socket(AF_INET, SOCKSTREAM, 0) failed: %s", --- 938,944 ---- } port = smtp_service->s_port; } ! (void) bzero((char *)&sockin, sizeof(sockin)); ls = socket(AF_INET, SOCK_STREAM, 0); if (ls < 0) { write_log(WRITE_LOG_SYS, "socket(AF_INET, SOCKSTREAM, 0) failed: %s", *************** *** 947,953 **** exitvalue = EX_OSERR; return; } ! sin.sin_family = AF_INET; if (listen_name) { hostentp = gethostbyname(listen_name); if (!hostentp) { --- 946,952 ---- exitvalue = EX_OSERR; return; } ! sockin.sin_family = AF_INET; if (listen_name) { hostentp = gethostbyname(listen_name); if (!hostentp) { *************** *** 957,968 **** strerror(errno)); /* NOTREACHED */ } ! memcpy(&sin.sin_addr, hostentp->h_addr_list[0], sizeof(struct in_addr)); ! DEBUG1(DBG_MAIN_LO, "listen on ip addr [%s]\n", inet_ntoa(sin.sin_addr)); } else { ! sin.sin_addr.s_addr = INADDR_ANY; } ! sin.sin_port = port; /* * set SO_REUSEADDR so that the daemon can be restarted while --- 956,967 ---- strerror(errno)); /* NOTREACHED */ } ! memcpy(&sockin.sin_addr, hostentp->h_addr_list[0], sizeof(struct in_addr)); ! DEBUG1(DBG_MAIN_LO, "listen on ip addr [%s]\n", inet_ntoa(sockin.sin_addr)); } else { ! sockin.sin_addr.s_addr = INADDR_ANY; } ! sockin.sin_port = port; /* * set SO_REUSEADDR so that the daemon can be restarted while *************** *** 978,984 **** return; } ! if (bind(ls, (struct sockaddr *)&sin, sizeof(sin)) < 0) { write_log(WRITE_LOG_SYS, "bind() failed: %s.", strerror(errno)); exitvalue = EX_OSERR; return; --- 977,983 ---- return; } ! if (bind(ls, (struct sockaddr *)&sockin, sizeof(sockin)) < 0) { write_log(WRITE_LOG_SYS, "bind() failed: %s.", strerror(errno)); exitvalue = EX_OSERR; return; *************** *** 1869,1874 **** --- 1868,1874 ---- struct addr *new, *next; build_host_strings(); + compute_nobody(); /* first reverse the list */ new = NULL; for (cur = recipients; cur; cur = next) { Index: master/smail/src/pathto.c diff -c master/smail/src/pathto.c:1.11 master/smail/src/pathto.c:1.12 *** master/smail/src/pathto.c:1.11 Tue Dec 16 17:11:57 1997 --- master/smail/src/pathto.c Sun Sep 19 14:48:01 1999 *************** *** 1,5 **** /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_107 $:$Id: pathto.c,v 1.11 1997/12/16 22:11:57 woods Exp $" */ /* --- 1,5 ---- /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_108 $:$Id: pathto.c,v 1.12 1999/09/19 18:48:01 woods Exp $" */ /* *************** *** 347,353 **** } for (argp = &argv[optind]; *argp; argp++) { ! strip_rfc822_comments(*argp); } /* setup all of the hostname information */ --- 347,354 ---- } for (argp = &argv[optind]; *argp; argp++) { ! strip_rfc822_comments(*argp); /* XXX should we really do this!?!?! */ ! strip_rfc822_whitespace(*argp); } /* setup all of the hostname information */ Index: master/smail/src/resolve.c diff -c master/smail/src/resolve.c:1.15 master/smail/src/resolve.c:1.16 *** master/smail/src/resolve.c:1.15 Thu Jul 22 01:12:50 1999 --- master/smail/src/resolve.c Sun Sep 19 14:34:31 1999 *************** *** 1,5 **** /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_107 $:$Id: resolve.c,v 1.15 1999/07/22 05:12:50 woods Exp $" */ /* --- 1,5 ---- /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_108 $:$Id: resolve.c,v 1.16 1999/09/19 18:34:31 woods Exp $" */ /* *************** *** 18,23 **** --- 18,24 ---- */ #include #include + #define NEED_SOCKETS /* grumble */ #include "defs.h" #include "smail.h" #include "dys.h" *************** *** 33,38 **** --- 34,46 ---- # include "error.h" #endif + #ifndef INADDR_NONE + # define INADDR_NONE ((unsigned long) (-1)) /* XXX 64bit too??? */ + #endif + #ifndef INADDR_LOOPBACK + # define INADDR_LOOPBACK ((unsigned long) 0x7F000001) + #endif + /* exported variables */ struct hash_table *hit_table; /* table to recognize address hits */ *************** *** 227,246 **** /* * islocalhost - determine if the given target is the local host * ! * given the currently known names for the localhost, determine ! * if the given name matches one of these known names. * * return TRUE or FALSE. */ int islocalhost(target) register char *target; /* name to match */ { if ((uucp_name && EQIC(target, uucp_name)) || (hostnames && is_string_in_list(target, hostnames)) || (more_hostnames && is_string_in_list(target, more_hostnames))) { return TRUE; } return FALSE; } --- 235,322 ---- /* * islocalhost - determine if the given target is the local host * ! * Given the currently known names for the localhost, determine if the given ! * name or any name resolved from an IP literal matches one of these known ! * names. * * return TRUE or FALSE. + * + * WARNING: an address which looks like an IP literal (i.e. is surrounded in + * "[]"), but which the inet library claims is not valid will be treated as a + * non-local host. This should be OK because we test IP literals last. */ int islocalhost(target) register char *target; /* name to match */ { + #ifdef HAVE_BSD_NETWORKING + int len; + char *hostip; + struct in_addr inet_s; + struct hostent *hostentp; + # ifndef INET_ADDR_USE_STRUCT + unsigned long inet; /* internet address */ + # endif + #endif /* HAVE_BSD_NETWORKING */ + if ((uucp_name && EQIC(target, uucp_name)) || (hostnames && is_string_in_list(target, hostnames)) || (more_hostnames && is_string_in_list(target, more_hostnames))) { return TRUE; } + #ifdef HAVE_BSD_NETWORKING + /* + * Do a (recursive) check if this looks like a [xxx.xxx.xxx.xxx] address + * and if so whether or not it appears to be on a local interface. + */ + len = strlen(target); + if (target[0] == '[' && target[len-1] == ']') { + hostip = COPY_STRING(target+1); /* make a copy so we don't have to modify target. */ + len = strlen(hostip); + hostip[len-1] = '\0'; + # ifdef HAVE_INET_ATON + if (!inet_aton(hostip, &inet_s)) { + xfree(hostip); + return FALSE; /* not a valid IP number.... */ + } + # else + # ifdef INET_ADDR_USE_STRUCT + inet_s = inet_addr(hostip); + # else + inet = inet_addr(hostip); + inet_s.s_addr = inet; + # endif + # endif + xfree(hostip); + if (inet_s.s_addr == INADDR_NONE) { + return FALSE; /* not a valid IP number.... */ + } + if (inet_s.s_addr == htonl(INADDR_LOOPBACK)) { + return TRUE; /* obviously us.... */ + } + /* + * Do a reverse query to get the hostname. This is a bit bogus as it + * requires that the lookup work for the check to function properly. + * Better would be to look at the interfaces directly but doing that in + * a host-independent manner is nearly impossible. + */ + if ((hostentp = gethostbyaddr((char *) &(inet_s.s_addr), sizeof(inet_s.s_addr), AF_INET))) { + if (islocalhost(hostentp->h_name)) { + return TRUE; + } else { + char *p; + int i; + + for (i = 0; (p = (hostentp->h_aliases)[i]); i++) { + if (islocalhost(p)) { + return TRUE; + } + } + } + } + } + #endif /* HAVE_BSD_NETWORKING */ + return FALSE; } Index: master/smail/src/smailconf.c diff -c master/smail/src/smailconf.c:1.43 master/smail/src/smailconf.c:1.45 *** master/smail/src/smailconf.c:1.43 Fri Sep 3 17:41:17 1999 --- master/smail/src/smailconf.c Sun Sep 19 16:02:33 1999 *************** *** 1,5 **** /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_107 $:$Id: smailconf.c,v 1.43 1999/09/03 21:41:17 woods Exp $" */ /* --- 1,5 ---- /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_108 $:$Id: smailconf.c,v 1.45 1999/09/19 20:02:33 woods Exp $" */ /* *************** *** 135,142 **** { "smtp_accept_max", t_int, NULL, (tup *)&smtp_accept_max, 0 }, { "smtp_accept_queue", t_int, NULL, (tup *)&smtp_accept_queue, 0 }, { "smtp_banner", t_string, NULL, (tup *)&smtp_banner, 0 }, ! { "smtp_debug", t_boolean, NULL, (tup *)&smtp_debug, 0 }, ! { "smtp_info", t_boolean, NULL, (tup *)&smtp_info, 0 }, { "smtp_receive_command_timeout", t_interval, NULL, (tup *)&smtp_receive_command_timeout, 0 }, { "smtp_receive_message_timeout", t_interval, NULL, --- 135,144 ---- { "smtp_accept_max", t_int, NULL, (tup *)&smtp_accept_max, 0 }, { "smtp_accept_queue", t_int, NULL, (tup *)&smtp_accept_queue, 0 }, { "smtp_banner", t_string, NULL, (tup *)&smtp_banner, 0 }, ! { "smtp_allow_debug", t_boolean, NULL, (tup *)&smtp_allow_debug, 0 }, ! { "smtp_debug", t_boolean, NULL, (tup *)&smtp_allow_debug, 0 }, ! { "smtp_allow_expn", t_boolean, NULL, (tup *)&smtp_allow_expn, 0 }, ! { "smtp_info", t_boolean, NULL, (tup *)&smtp_allow_expn, 0 }, { "smtp_receive_command_timeout", t_interval, NULL, (tup *)&smtp_receive_command_timeout, 0 }, { "smtp_receive_message_timeout", t_interval, NULL, *************** *** 147,152 **** --- 149,155 ---- { "smtp_hello_broken_allow", t_string, NULL, (tup *)&smtp_hello_broken_allow, 0 }, { "smtp_hello_verify_literal", t_boolean, NULL, (tup *)&smtp_hello_verify_literal, 0 }, { "smtp_hello_verify_ptr", t_boolean, NULL, (tup *)&smtp_hello_verify_ptr, 0 }, + { "smtp_sender_no_verify", t_string, NULL, (tup *)&smtp_sender_no_verify, 0 }, { "smtp_sender_verify_mx_only", t_boolean, NULL, (tup *)&smtp_sender_verify_mx_only, 0 }, { "smtp_max_recipients", t_int, NULL, (tup *)&smtp_max_recipients, 0 }, { "debug_pause_for_smtp_connections", t_int, NULL, (tup *)&debug_pause_for_smtp_connections, 0}, Index: master/smail/src/smtprecv.c diff -c master/smail/src/smtprecv.c:1.90 master/smail/src/smtprecv.c:1.95 *** master/smail/src/smtprecv.c:1.90 Fri Sep 3 17:35:56 1999 --- master/smail/src/smtprecv.c Sun Sep 19 16:51:48 1999 *************** *** 1,5 **** /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_107 $:$Id: smtprecv.c,v 1.90 1999/09/03 21:35:56 woods Exp $" */ /* --- 1,5 ---- /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_108 $:$Id: smtprecv.c,v 1.95 1999/09/19 20:51:48 woods Exp $" */ /* *************** *** 115,120 **** --- 115,121 ---- static void send_session_denied_reply(FILE *, char *, char *); # endif static void non_compliant_reply(FILE *, int, char *); + static void illegal_operand_warning(char *, char *operand); static void reset_state(void); static enum e_smtp_commands read_smtp_command(FILE *, FILE *); static int decode_mail_options(char *, FILE *); *************** *** 137,142 **** --- 138,144 ---- static void send_session_denied_reply(); # endif static void non_compliant_reply(); + static void illegal_operand_warning(); static void reset_state(); static enum e_smtp_commands read_smtp_command(); static int decode_mail_options(); *************** *** 464,473 **** --- 466,477 ---- alarm(smtp_receive_command_timeout); } switch (read_smtp_command(in, out)) { + #ifdef HAVE_EHLO case EHLO_CMD: ehlo_p = 1; sender_proto = (out ? "esmtp" : "ebsmtp"); /* reset as appropriate */ /* FALLTHRU */ + #endif case HELO_CMD: #ifdef HAVE_LIBWRAP if (smtp_session_denied) { *************** *** 501,506 **** --- 505,514 ---- #endif orig_data = COPY_STRING(data); strip_rfc822_comments(data); /* XXX not required by RFC 821 */ + if (strcmp(data, orig_data) != 0) { + illegal_operand_warning(ehlo_p ? "EHLO" : "HELO", orig_data); + } + strip_rfc822_whitespace(data); if (!data[0]) { non_compliant_reply(out, 501, "SMTP greeting requires a hostname (or IP address literal) as operand"); break; *************** *** 614,623 **** } else { fprintf(out, "250-SIZE\r\n"); } - #ifdef HAVE_ESMTP_8BITMIME fprintf(out, "250-8BITMIME\r\n"); ! #endif ! #ifdef HAVE_ESMTP_PIPELINING fprintf(out, "250-PIPELINING\r\n"); #endif #ifndef NO_SMTP_EXPN --- 622,629 ---- } else { fprintf(out, "250-SIZE\r\n"); } fprintf(out, "250-8BITMIME\r\n"); ! #ifdef HAVE_ESMTP_PIPELINING /* defined in iobpeek.h if support is possible */ fprintf(out, "250-PIPELINING\r\n"); #endif #ifndef NO_SMTP_EXPN *************** *** 639,647 **** break; } #endif strip_rfc822_comments(data); if (data[0] == '\0') { ! non_compliant_reply(out, 501, "'MAIL FROM:' requires return address as operand."); break; } if (!sender_host) { --- 645,663 ---- break; } #endif + if (*data != '<' || !(p = strchr(data, '>'))) { + illegal_operand_warning("MAIL FROM", data); + } else if (p && *(p+1) && !isspace(*(p+1))) { + illegal_operand_warning("MAIL FROM", data); + } + orig_data = COPY_STRING(data); strip_rfc822_comments(data); + if (strcmp(data, orig_data) != 0) { + illegal_operand_warning("MAIL FROM", orig_data); + } + strip_rfc822_whitespace(data); if (data[0] == '\0') { ! non_compliant_reply(out, 501, "'MAIL FROM:' requires return return-path address as operand."); break; } if (!sender_host) { *************** *** 692,703 **** break; } #endif orig_data = COPY_STRING(data); strip_rfc822_comments(data); if (data[0] == '\0') { ! non_compliant_reply(out, 501, "'RCPT TO:' requires address as operand."); break; } if (!sender) { non_compliant_reply(out, 503, "'RCPT TO:' must be preceded by MAIL FROM: command."); break; --- 708,729 ---- break; } #endif + if (*data != '<' || !(p = strchr(data, '>'))) { + illegal_operand_warning("RCPT TO", data); + } else if (p && *(p+1) && !isspace(*(p+1))) { + illegal_operand_warning("RCPT TO", data); + } orig_data = COPY_STRING(data); strip_rfc822_comments(data); + if (strcmp(data, orig_data) != 0) { + illegal_operand_warning("RCPT TO", orig_data); + } + strip_rfc822_whitespace(data); if (data[0] == '\0') { ! non_compliant_reply(out, 501, "'RCPT TO:' requires forward-path address as operand."); break; } + /* do this after the above checks just to catch gross errors earlier */ if (!sender) { non_compliant_reply(out, 503, "'RCPT TO:' must be preceded by MAIL FROM: command."); break; *************** *** 850,867 **** break; case VRFY_CMD: - #define SMTP_RPLY_252 "252-Cannot VRFY mailbox\r\n252 but will take message for this address and attempt delivery.\r\n" if (out) { ! #ifdef NO_SMTP_VRFY ! fprintf(out, SMTP_RPLY_252); ! #else ! if (smtp_info) { /* XXX should be a separate variable: smtp_allow_vrfy */ ! strip_rfc822_comments(data); ! verify_addr(data, out, 0); ! } else { ! fprintf(out, SMTP_RPLY_252); ! } ! #endif fflush(out); } break; --- 876,885 ---- break; case VRFY_CMD: if (out) { ! strip_rfc822_comments(data); ! strip_rfc822_whitespace(data); ! verify_addr(data, out, 0); fflush(out); } break; *************** *** 879,886 **** #ifdef NO_SMTP_EXPN fprintf(out, "502 Command not implemented\r\n"); #else ! if (smtp_info) { /* XXX should be a separate variable: smtp_allow_expn */ strip_rfc822_comments(data); expand_addr(data, out); } else { fprintf(out, "502 Command disabled\r\n"); --- 897,905 ---- #ifdef NO_SMTP_EXPN fprintf(out, "502 Command not implemented\r\n"); #else ! if (smtp_allow_expn) { strip_rfc822_comments(data); + strip_rfc822_whitespace(data); expand_addr(data, out); } else { fprintf(out, "502 Command disabled\r\n"); *************** *** 939,947 **** } #endif if (out) { ! #ifndef NODEBUG ! if (smtp_debug) { /* XXX should be called: smtp_allow_debug */ strip_rfc822_comments(data); if (*data) { char *errbuf = NULL; --- 958,966 ---- } #endif if (out) { ! if (smtp_allow_debug) { strip_rfc822_comments(data); + strip_rfc822_whitespace(data); if (*data) { char *errbuf = NULL; *************** *** 965,971 **** errfile = out; break; } - #endif /* !NODEBUG */ fprintf(out, "500 I hear you knocking, but you can't come in\r\n"); fflush(out); } --- 984,989 ---- *************** *** 1129,1147 **** int ecode; char *errtxt; { if (!out) { return; } fprintf(out, "%d-%s\r\n%d-\r\n", ecode, errtxt, ecode); fprintf(out, "%d-If you are seeing this message in a bounce, or in an alert box\r\n", ecode); fprintf(out, "%d-from your mailer client, etc., then your mailer software is\r\n", ecode); ! fprintf(out, "%d-hopelessly non-compliant and incompatible with SMTP (RFC 821).\r\n", ecode); fprintf(out, "%d Please report this bug to those responsible for your mailer software.\r\n", ecode); fflush(out); return; } static void reset_state() { struct addr *cur; --- 1147,1203 ---- int ecode; char *errtxt; { + #ifdef LOG_SMTP_NON_COMPLIANCE + write_log(WRITE_LOG_SYS, "[%d] sent %d: '%s' to %s%s%s%s%s%s%s%s%s.", + getpid(), + ecode, + errtxt, + ident_sender ? ident_sender : "", + ident_sender ? "@" : "", + sender_host ? sender_host : "", + sender_host_really ? "(" : "", + sender_host_really ? sender_host_really : "", + sender_host_really ? ")" : "", + sender_host_addr ? " source [" : "", + sender_host_addr ? sender_host_addr : "", + sender_host_addr ? "]" : ""); + #endif if (!out) { return; } fprintf(out, "%d-%s\r\n%d-\r\n", ecode, errtxt, ecode); fprintf(out, "%d-If you are seeing this message in a bounce, or in an alert box\r\n", ecode); fprintf(out, "%d-from your mailer client, etc., then your mailer software is\r\n", ecode); ! fprintf(out, "%d-hopelessly non-compliant and incompatible with SMTP (RFC 821 et al).\r\n", ecode); fprintf(out, "%d Please report this bug to those responsible for your mailer software.\r\n", ecode); fflush(out); return; } static void + illegal_operand_warning(operator, operand) + char *operator; + char *operand; + { + #ifdef LOG_SMTP_ILLEGAL_OPERAND_WARNING + write_log(WRITE_LOG_SYS, "[%d] remote %s: '%s' operand not strictly legal from %s%s%s%s%s%s%s%s%s.", + getpid(), + operator, + operand, + ident_sender ? ident_sender : "", + ident_sender ? "@" : "", + sender_host ? sender_host : "", + sender_host_really ? "(" : "", + sender_host_really ? sender_host_really : "", + sender_host_really ? ")" : "", + sender_host_addr ? " source [" : "", + sender_host_addr ? sender_host_addr : "", + sender_host_addr ? "]" : ""); + #endif + return; + } + + static void reset_state() { struct addr *cur; *************** *** 1262,1280 **** while (rest && *rest) { int restlen; /* maybe we have an extended MAIL command */ ! while (*rest && isspace(*rest)) { ++rest; } restlen = 0; /* find end of option name */ ! while (*(rest+restlen) && !isspace (*(rest+restlen)) && *(rest+restlen) != '=') { ++restlen; } if (strncmpic(rest, "SIZE", restlen) == 0) { char *errbuf = NULL; /* pointer to returned error msg */ - int c; /* NUL place-holder */ rest += restlen; if (*rest != '=') { --- 1318,1336 ---- while (rest && *rest) { int restlen; + char ch; /* NUL place-holder */ /* maybe we have an extended MAIL command */ ! while (isspace(*rest)) { ++rest; } restlen = 0; /* find end of option name */ ! while (*(rest+restlen) && !isspace(*(rest+restlen)) && *(rest+restlen) != '=') { ++restlen; } if (strncmpic(rest, "SIZE", restlen) == 0) { char *errbuf = NULL; /* pointer to returned error msg */ rest += restlen; if (*rest != '=') { *************** *** 1284,1303 **** ++rest; restlen = 0; body_size = 0; ! while (*(rest+restlen) && isdigit(*(rest+restlen))) { ++restlen; } ! c = *(rest+restlen); *(rest+restlen) = '\0'; /* NUL terminate # */ body_size = c_atol(rest, &errbuf); ! *(rest+restlen) = c; /* restore */ if (errbuf) { if (out) { fprintf(out, "501-bad number: %s\r\n", errbuf); ! non_compliant_reply(out, 501, "Malformed 'MAIL FROM:' SIZE clause."); } return -1; } if (accepted_msg_size > 0 && body_size > accepted_msg_size) { if (out) { #ifdef HAVE_DF_SPOOL --- 1340,1365 ---- ++rest; restlen = 0; body_size = 0; ! /* find the end of the SIZE parameter */ ! while (isdigit(*(rest+restlen))) { ++restlen; } ! ch = *(rest+restlen); *(rest+restlen) = '\0'; /* NUL terminate # */ body_size = c_atol(rest, &errbuf); ! *(rest+restlen) = ch; /* restore */ if (errbuf) { if (out) { fprintf(out, "501-bad number: %s\r\n", errbuf); ! non_compliant_reply(out, 501, "Malformed 'MAIL FROM:' SIZE=number clause."); } return -1; } + /* is there a space, tab, or newline after the last digit? */ + if (*(rest+restlen) && !isspace(*(rest+restlen))) { + non_compliant_reply(out, 501, "'MAIL FROM:' malformed SIZE parameter."); + return -1; + } if (accepted_msg_size > 0 && body_size > accepted_msg_size) { if (out) { #ifdef HAVE_DF_SPOOL *************** *** 1312,1323 **** fflush(out); } return -1; ! } else if (*(rest+restlen) && !isspace(*(rest+restlen))) { ! non_compliant_reply(out, 501, "'MAIL FROM:' malformed SIZE clause.\r\n"); return -1; } } else { ! non_compliant_reply(out, 504, "Unknown MAIL FROM: ESMTP option.\r\n"); return -1; } rest += restlen; --- 1374,1404 ---- fflush(out); } return -1; ! } ! } else if (strncmpic(rest, "BODY", restlen) == 0) { ! rest += restlen; ! if (*rest != '=') { ! non_compliant_reply(out, 501, "'MAIL FROM:<...> BODY=?' missing parameter."); return -1; } + rest++; + restlen = 0; + /* find the end of the BODY parameter */ + while (*(rest+restlen) && !isspace(*(rest+restlen))) { + ++restlen; + } + ch = *(rest+restlen); + *(rest+restlen) = '\0'; /* NUL terminate # */ + if (strcmpic(rest, "7BIT") == 0) { + /* What more could you want in America? ;-) */ + } else if (strcmpic(rest, "8BITMIME") == 0) { + /* We'll be lazy and leave this up to the MUA to decode... */ + } else { + DEBUG1(DBG_REMOTE_LO, "Unknown ESMTP BODY=%s parameter value!", rest); + } + *(rest+restlen) = ch; /* restore */ } else { ! non_compliant_reply(out, 555, "Unknown MAIL FROM: ESMTP option."); return -1; } rest += restlen; *************** *** 1503,1509 **** sender_host_addr ? "]" : ""); } #ifdef HAVE_BIND ! if (*vaddr->work_addr && !EQ(vaddr->work_addr, "+")) { int mxresult; long bindflgs = BIND_DOMAIN_REQUIRED | BIND_DEFER_NO_CONN | BIND_LOCAL_MX_OKAY | BIND_DONT_FILTER; struct rt_info rt_info; --- 1584,1592 ---- sender_host_addr ? "]" : ""); } #ifdef HAVE_BIND ! if (*vaddr->work_addr && !EQ(vaddr->work_addr, "+") && ! !(sender_host_addr && smtp_sender_no_verify && ! match_ip(sender_host_addr, smtp_sender_no_verify))) { int mxresult; long bindflgs = BIND_DOMAIN_REQUIRED | BIND_DEFER_NO_CONN | BIND_LOCAL_MX_OKAY | BIND_DONT_FILTER; struct rt_info rt_info; Index: master/smail/src/string.c diff -c master/smail/src/string.c:1.26 master/smail/src/string.c:1.27 *** master/smail/src/string.c:1.26 Sun Jul 18 21:45:18 1999 --- master/smail/src/string.c Sun Sep 19 13:23:12 1999 *************** *** 1,5 **** /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_107 $:$Id: string.c,v 1.26 1999/07/19 01:45:18 woods Exp $" */ /* --- 1,5 ---- /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_108 $:$Id: string.c,v 1.27 1999/09/19 17:23:12 woods Exp $" */ /* *************** *** 435,441 **** va_end(ap); STR_NEXT(&str, '\0'); STR_DONE(&str); ! return str.p; } /* --- 435,442 ---- va_end(ap); STR_NEXT(&str, '\0'); STR_DONE(&str); ! ! return STR(&str); } /* *************** *** 460,473 **** inited = TRUE; STR_INIT(&str); } else { ! str.i = 0; } va_start(ap); str_printf_va(&str, fmt, ap); va_end(ap); STR_NEXT(&str, '\0'); ! return fputs(str.p, file); } /* --- 461,474 ---- inited = TRUE; STR_INIT(&str); } else { ! STR_CLEAR(&str); } va_start(ap); str_printf_va(&str, fmt, ap); va_end(ap); STR_NEXT(&str, '\0'); ! return fputs(STR(&str), file); } /* Index: master/smail/src/routers/gethost.c diff -c master/smail/src/routers/gethost.c:1.18 master/smail/src/routers/gethost.c:1.19 *** master/smail/src/routers/gethost.c:1.18 Tue Sep 7 23:52:26 1999 --- master/smail/src/routers/gethost.c Sun Sep 19 14:34:31 1999 *************** *** 1,5 **** /* ! #ident "@(#)smail/src/routers:$Name: RELEASE-3_2_0_107 $:$Id: gethost.c,v 1.18 1999/09/08 03:52:26 woods Exp $" */ /* --- 1,5 ---- /* ! #ident "@(#)smail/src/routers:$Name: RELEASE-3_2_0_108 $:$Id: gethost.c,v 1.19 1999/09/19 18:34:31 woods Exp $" */ /* *************** *** 356,401 **** { register char *p; /* temp */ struct in_addr inet_s; /* internet address */ ! #ifndef INET_ADDR_USE_STRUCT unsigned long inet; /* internet address */ #endif - static char sbuf[sizeof("[255.255.255.255]+some_slop")]; p = addr->target; DEBUG2(DBG_DRIVER_HI, "router %s: gethostbyaddr_lookup called for %s.\n", rp->name, addr->target); /* check for a domain literal form */ ! if (index(p, '[') == NULL && index(p, ']') == NULL) { /* definitely not a domain literal */ DEBUG2(DBG_DRIVER_MID, "router %s: gethostbyaddr_lookup not a domain literal %s.\n", rp->name, addr->target); return DB_NOMATCH; } ! if (*p != '[') { return bad_form(rp, addr->target, error_p); } p = index(p, ']'); ! if (p == NULL || *(p + 1) != '\0') { return bad_form(rp, addr->target, error_p); } ! /* see if the library likes the form */ ! *p = '\0'; /* chop off ending `]', for now */ ! #ifdef INET_ADDR_USE_STRUCT ! inet_s = inet_addr(addr->target + 1); #else inet = inet_addr(addr->target + 1); inet_s.s_addr = inet; #endif if (inet_s.s_addr == INADDR_NONE) { return bad_form(rp, addr->target, error_p); } ! *p = ']'; /* put it back */ ! (void) sprintf(sbuf, "[%s]", inet_ntoa(inet_s)); ! rt_info->next_host = sbuf; if (fl & RT_VERIFY) { /* Only verifying, this is far enough */ --- 356,414 ---- { register char *p; /* temp */ struct in_addr inet_s; /* internet address */ ! #if !defined(HAVE_INET_ATON) && !defined(INET_ADDR_USE_STRUCT) unsigned long inet; /* internet address */ #endif p = addr->target; DEBUG2(DBG_DRIVER_HI, "router %s: gethostbyaddr_lookup called for %s.\n", rp->name, addr->target); /* check for a domain literal form */ ! if (!strchr(p, '[') && !strchr(p, ']')) { /* definitely not a domain literal */ DEBUG2(DBG_DRIVER_MID, "router %s: gethostbyaddr_lookup not a domain literal %s.\n", rp->name, addr->target); return DB_NOMATCH; } ! /* ! * We go to some extra trouble to check if what we've been handed is a true ! * and proper literal IP address in the expected form because that's what ! * we expect, and only what we expect. ! */ if (*p != '[') { return bad_form(rp, addr->target, error_p); } p = index(p, ']'); ! if (!p || *(p+1) != '\0') { return bad_form(rp, addr->target, error_p); } ! /* see if the inet library likes the address */ ! *p = '\0'; /* chop off ending `]', for now */ ! #ifdef HAVE_INET_ATON ! if (!inet_aton(addr->target + 1, &inet_s)) { ! *p = ']'; /* put it back */ ! return bad_form(rp, addr->target, error_p); ! } #else + # ifdef INET_ADDR_USE_STRUCT + inet_s = inet_addr(addr->target + 1); + # else inet = inet_addr(addr->target + 1); inet_s.s_addr = inet; + # endif #endif if (inet_s.s_addr == INADDR_NONE) { + *p = ']'; /* put it back */ return bad_form(rp, addr->target, error_p); } ! *p = ']'; /* put it back */ ! /* ! * provide a canonical representation in "dotted quad form".... ! */ ! rt_info->next_host = xprintf("[%s]", inet_ntoa(inet_s)); if (fl & RT_VERIFY) { /* Only verifying, this is far enough */ *************** *** 403,442 **** } if (rp->flags & GETHOST_CHECK_LOCAL) { ! struct hostent *hostentp = NULL; ! int foundlocalhost; ! ! /* first check to make sure we know we're not talking to ourselves */ ! foundlocalhost = (inet_s.s_addr == htonl(INADDR_LOOPBACK)); ! /* ! * Do a reverse query to get the hostname. This is a bit bogus as it ! * requires that the lookup work for the check to function properly. ! * Better would be to look at the interfaces directly but doing that in ! * a host-independent manner is nearly impossible. ! */ ! if (!foundlocalhost) { ! if ((hostentp = gethostbyaddr((char *) &(inet_s.s_addr), sizeof(inet_s.s_addr), AF_INET))) { ! if (islocalhost(hostentp->h_name)) { ! foundlocalhost = 1; ! } else { ! char *p; ! int i; ! ! for (i = 0; (p = (hostentp->h_aliases)[i]); i++) { ! if (islocalhost(p)) { ! foundlocalhost = 1; ! break; /* that's all we need to know */ ! } ! } ! } ! } else { ! DEBUG2(DBG_DRIVER_LO, "cannot check localhost -- gethostbyaddr(%s) failed: %s.\n", sbuf, hstrerror(h_errno)); ! } ! } ! if (foundlocalhost) { struct addr *new; ! DEBUG3(DBG_DRIVER_LO, "router %s: gethostbyaddr_lookup %s%s is a local host, will force reparse.\n", rp->name, (hostentp) ? hostentp->h_name : "localhost", sbuf); /* * It seems like a good idea to record the fact that the old * address is the parent of the new address (mostly so that the --- 416,425 ---- } if (rp->flags & GETHOST_CHECK_LOCAL) { ! if (islocalhost(rt_info->next_host)) { struct addr *new; ! DEBUG2(DBG_DRIVER_LO, "router %s: '%s' is a local host, will force reparse.\n", rp->name, rt_info->next_host); /* * It seems like a good idea to record the fact that the old * address is the parent of the new address (mostly so that the *************** *** 493,499 **** * The user should supply a correctly formed INET domain * literal. */ ! error_text = xprintf("router %s: Malformed domain literal: %s", rp->name, target); DEBUG1(DBG_DRIVER_LO, "%s\n", error_text); --- 476,482 ---- * The user should supply a correctly formed INET domain * literal. */ ! error_text = xprintf("router %s: Malformed literal IP address: %s", rp->name, target); DEBUG1(DBG_DRIVER_LO, "%s\n", error_text); *************** *** 503,509 **** return DB_FAIL; } ! DEBUG2(DBG_DRIVER_LO, "router %s: gethostbyaddr not failing malformed literal: %s.\n", rp->name, target); return DB_NOMATCH; } --- 486,492 ---- return DB_FAIL; } ! DEBUG2(DBG_DRIVER_LO, "router %s: gethostbyaddr not failing malformed literal IP: %s.\n", rp->name, target); return DB_NOMATCH; } Index: master/smail/src/transports/smtplib.c diff -c master/smail/src/transports/smtplib.c:1.32 master/smail/src/transports/smtplib.c:1.38 *** master/smail/src/transports/smtplib.c:1.32 Sat Aug 14 01:32:53 1999 --- master/smail/src/transports/smtplib.c Sun Sep 19 18:22:48 1999 *************** *** 1,5 **** /* ! #ident "@(#)smail/src/transports:$Name: RELEASE-3_2_0_107 $:$Id: smtplib.c,v 1.32 1999/08/14 05:32:53 woods Exp $" */ /* --- 1,5 ---- /* ! #ident "@(#)smail/src/transports:$Name: RELEASE-3_2_0_108 $:$Id: smtplib.c,v 1.38 1999/09/19 22:22:48 woods Exp $" */ /* *************** *** 105,110 **** --- 105,111 ---- #define REPLY_OVER_QUOTA 0x552 /* remote says mailbox exceeded storage quota */ #define REPLY_ILLEGAL_USER 0x553 /* remote says mailbox name not allowed */ #define REPLY_TRANS_FAILURE 0x554 /* transaction failed (no SMTP service avail) */ + #define REPLY_ESMTP_PARAM_ERR 0x555 /* unsupported or invalid ESMTP RCPT_TO or MAIL_FROM parameter */ /* pseudo-reply codes */ #define REPLY_PROTO_ERROR 0x498 /* protocol error on read */ #define REPLY_TIMEOUT 0x499 /* timeout on read, or EOF on read */ *************** *** 118,123 **** --- 119,126 ---- /* functions local to this file */ #ifdef __STDC__ extern int smtp_startup(struct smtp *, struct error **, int); + static char *skip_to_eol(char *); + static void log_malformed_ehlo_reply(char *, char *); extern int smtp_send(struct smtp *, struct addr *, struct addr **, struct addr **, struct addr **, struct error **); extern void smtp_shutdown(struct smtp *); static void do_smtp_shutdown(struct smtp *, int); *************** *** 142,147 **** --- 145,152 ---- static struct error * read_failed(struct transport *); #else /* not __STDC__ */ extern int smtp_startup(); + static char *skip_to_eol(); + static void log_malformed_ehlo_reply(); extern int smtp_send(); extern void smtp_shutdown(); static void do_smtp_shutdown(); *************** *** 166,171 **** --- 171,177 ---- static struct error * read_failed(); #endif /* not __STDC__ */ + /* * smtp_startup - initiate contact on an SMTP connection * *************** *** 254,344 **** } if (reply == REPLY_OK) { char * cp = reply_text; ! int on_greet_line = 1; ! smtpb->smtp_flags = ESMTP_basic; ! /* Parse the EHLO reply to find out ! what the remote server supports */ ! while (*cp != 0) { ! int skip; ! int keywordlength; ! ! for (skip = 4; *cp != 0 && skip; --skip, ++cp) { ! if (skip == 1 ! ? (*cp != ' ' && *cp != '-') ! : (! isdigit (*cp))) { ! goto malformed_ehlo_reply; ! } } ! if (skip != 0) { ! goto malformed_ehlo_reply; } if (on_greet_line) { /* * Ignore greeting on first line */ on_greet_line = 0; ! goto skip_rest_of_line; } ! keywordlength = 0; ! while (*(cp+keywordlength) != 0 && !isspace(*(cp+keywordlength))) { ! ++keywordlength; } ! if (strncmpic(cp, "SIZE", keywordlength) == 0) { ! unsigned long max_size = 0; ! ! cp += keywordlength; ! while (*cp == ' ' || *cp == '\t') ! ++cp; ! if (*cp && !isdigit(*cp) && *cp != '\n') ! goto malformed_ehlo_reply; ! while (*cp && isdigit(*cp)) { ! max_size *= 10; ! max_size += *cp - '0'; ! ++cp; } ! smtpb->smtp_flags |= ESMTP_size; ! smtpb->max_size = max_size; ! } else if (strncmpic(cp, "8BITMIME", keywordlength) == 0) { ! smtpb->smtp_flags |= ESMTP_8bitmime; ! } else if (strncmpic(cp, "PIPELINING", keywordlength) == 0) { ! smtpb->smtp_flags |= ESMTP_pipelining; ! } else if (strncmpic(cp, "XVRB", keywordlength) == 0) { ! smtpb->smtp_flags |= ESMTP_verbose; ! } else if (strncmpic(cp, "XONE", keywordlength) == 0) { ! smtpb->smtp_flags |= ESMTP_one; ! } else if (strncmpic(cp, "XQUE", keywordlength) == 0) { ! smtpb->smtp_flags |= ESMTP_queue; ! } else if (strncmpic(cp, "EXPN", keywordlength) == 0) { ! ; /* NOP XXX smail offers this but we can ignore it in here */ ! } else if (strncmpic(cp, "HELP", keywordlength) == 0) { ! ; /* NOP XXX smail offers this but we can ignore it in here */ } else { ! char sc = *(cp + keywordlength); ! *(cp + keywordlength) = '\0'; ! DEBUG1(DBG_DRIVER_MID, "destination offers unsupported ESMTP option '%s'.\n", cp); ! *(cp + keywordlength) = sc; } ! skip_rest_of_line: ! while (*cp != 0 && *cp != '\n') ! ++cp; ! if (*cp == '\n') ! ++cp; } ! DEBUG6(DBG_DRIVER_MID, "destination supports ESMTP%s%s%s%s%s%s.\n", ! smtpb->smtp_flags & ESMTP_8bitmime ? " 8BITMIME" : "", ! smtpb->smtp_flags & ESMTP_size ? " SIZE" : "", ! smtpb->smtp_flags & ESMTP_pipelining ? " PIPELINING" : "", ! smtpb->smtp_flags & ESMTP_verbose ? " XVRB" : "", ! smtpb->smtp_flags & ESMTP_one ? " XONE" : "", ! smtpb->smtp_flags & ESMTP_queue ? " XQUE" : ""); ! if (smtpb->smtp_flags & ESMTP_verbose && debug >= DBG_DRIVER_MID) { STR_CLEAR(&smtp_out); (void) str_printf(&smtp_out, VERB); reply = wait_write_command(smtpb, smtpb->short_timeout, ! STR(&smtp_out), (int) STR_LEN(&smtp_out), ! &reply_text); if (REPLY_GROUP (reply) == NEGATIVE_TRY_AGAIN) { /* remote SMTP closed, try again later */ *error_p = try_again(smtpb->tp, reply_text); --- 260,417 ---- } if (reply == REPLY_OK) { char * cp = reply_text; ! int on_greet_line = 1; /* we start on the greeting line */ ! smtpb->esmtp_flags.ESMTP_basic = 1; ! /* ! * Parse the EHLO reply to find out what ESMTP options the remote ! * server supports.... ! */ ! while (*cp) { ! char *pp; ! ! /* ! * every line must begin with the three digits "250", followed ! * by a '-' for continued lines, and a ' ' for the final line ! */ ! if (strncmp(cp, "250", 3) != 0) { ! log_malformed_ehlo_reply("Not a 250 reply!", reply_text); ! return SMTP_SUCCEED; } ! cp += 3; ! if (*cp != ' ' && *cp != '-') { ! log_malformed_ehlo_reply("250 not followed by space or dash", reply_text); ! return SMTP_SUCCEED; } + cp++; /* skip the ' ' or '-' */ if (on_greet_line) { /* * Ignore greeting on first line */ on_greet_line = 0; ! cp = skip_to_eol(cp); ! continue; } ! /* ! * search for whitespace (or newline) after the keyword ! */ ! for (pp = cp; *(pp) && !isspace(*pp); ++pp) { ! ; } ! /* ! * in the ESMTP greeting the parameter values are separated ! * by whitespace, not an equal sign! We'll generously skip ! * any whitespace before a newline too... ! */ ! while (isspace(*pp)) { ! ++pp; ! } ! /* ! * decipher which keyword it is... ! */ ! if (strncmpic(cp, "8BITMIME", sizeof("8BITMIME")-1) == 0) { ! smtpb->esmtp_flags.ESMTP_8bitmime = 1; ! } else if (strncmpic(cp, "ATRN", sizeof("ATRN")-1) == 0) { ! smtpb->esmtp_flags.ESMTP_atrn = 1; ! } else if (strncmpic(cp, "AUTH", sizeof("AUTH")-1) == 0) { ! /* XXX followed by a space separated list of the names of supported SASL mechanisms */ ! smtpb->esmtp_flags.ESMTP_auth = 1; ! } else if (strncmpic(cp, "CHUNKING", sizeof("CHUNKING")-1) == 0) { ! smtpb->esmtp_flags.ESMTP_chunking = 1; ! } else if (strncmpic(cp, "DSN", sizeof("DSN")-1) == 0) { ! smtpb->esmtp_flags.ESMTP_dsn = 1; ! } else if (strncmpic(cp, "ENHANCEDSTATUSCODES", sizeof("ENHANCEDSTATUSCODES")-1) == 0) { ! smtpb->esmtp_flags.ESMTP_enhancedstatuscodes = 1; ! } else if (strncmpic(cp, "ETRN", sizeof("ETRN")-1) == 0) { ! smtpb->esmtp_flags.ESMTP_etrn = 1; ! } else if (strncmpic(cp, "EXPN", sizeof("EXPN")-1) == 0) { ! ; /* NOP XXX Smail never requests EXPN so we can ignore it in here */ ! } else if (strncmpic(cp, "HELP", sizeof("HELP")-1) == 0) { ! ; /* NOP XXX smail never requests HELP so we can ignore it in here */ ! } else if (strncmpic(cp, "ONEX", sizeof("ONEX")-1) == 0) { ! smtpb->esmtp_flags.ESMTP_onex = 1; ! } else if (strncmpic(cp, "PIPELINING", sizeof("PIPELINING")-1) == 0) { ! smtpb->esmtp_flags.ESMTP_pipelining = 1; ! } else if (strncmpic(cp, "SAML", sizeof("SAML")-1) == 0) { ! smtpb->esmtp_flags.ESMTP_saml = 1; ! } else if (strncmpic(cp, "SEND", sizeof("SEND")-1) == 0) { ! smtpb->esmtp_flags.ESMTP_send = 1; ! } else if (strncmpic(cp, "SIZE", sizeof("SIZE")-1) == 0) { ! char *errbuf = NULL; ! char *ep = strchr(cp, '\n'); ! ! if (ep+1 == pp) { /* pp points at next line if no parameter */ ! cp = skip_to_eol(cp); ! continue; ! } ! if (ep) { ! *ep = '\0'; ! } ! smtpb->esmtp_flags.ESMTP_size = 1; ! smtpb->max_size = c_atol(pp, &errbuf); /* XXX this is very generous! */ ! if (ep) { ! *ep = '\n'; ! } ! if (errbuf) { ! log_malformed_ehlo_reply(errbuf, reply_text); ! cp = skip_to_eol(cp); ! continue; } ! } else if (strncmpic(cp, "SOML", sizeof("SOML")-1) == 0) { ! smtpb->esmtp_flags.ESMTP_soml = 1; ! } else if (strncmpic(cp, "STARTTLS", sizeof("STARTTLS")-1) == 0) { ! smtpb->esmtp_flags.ESMTP_starttls = 1; ! } else if (strncmpic(cp, "TURN", sizeof("TURN")-1) == 0) { ! smtpb->esmtp_flags.ESMTP_turn = 1; ! } else if (strncmpic(cp, "VERB", sizeof("VERB")-1) == 0) { ! smtpb->esmtp_flags.ESMTP_verb = 1; ! } else if (*cp == 'X' || *cp == 'x') { ! smtpb->esmtp_flags.ESMTP_x = 1; } else { ! char *ep = strchr(cp, '\n'); ! if (ep) { ! *ep = '\0'; ! } ! # ifdef NO_LOG_EHLO ! DEBUG1(DBG_DRIVER_LO, "destination offers unsupported ESMTP option '%s'.\n", cp); ! # else ! write_log(WRITE_LOG_SYS, "destination offers unsupported ESMTP option '%s'.", cp); ! # endif ! if (ep) { ! *ep = '\n'; ! } } ! cp = skip_to_eol(cp); } ! DEBUG9(DBG_DRIVER_MID, "destination supports ESMTP%s%s%s%s%s%s%s%s%s", ! smtpb->esmtp_flags.ESMTP_8bitmime ? " 8BITMIME" : "", ! smtpb->esmtp_flags.ESMTP_atrn ? " ATRN" : "", ! smtpb->esmtp_flags.ESMTP_auth ? " AUTH" : "", ! smtpb->esmtp_flags.ESMTP_chunking ? " CHUNKING" : "", ! smtpb->esmtp_flags.ESMTP_dsn ? " DSN" : "", ! smtpb->esmtp_flags.ESMTP_enhancedstatuscodes ? " ENHANCEDSTATUSCODES" : "", ! smtpb->esmtp_flags.ESMTP_etrn ? " ETRN" : "", ! smtpb->esmtp_flags.ESMTP_expn ? " EXPN" : "", ! smtpb->esmtp_flags.ESMTP_help ? " HELP" : ""); ! DEBUG9(DBG_DRIVER_MID, "%s%s%s%s%s%s%s%s%s", ! smtpb->esmtp_flags.ESMTP_onex ? " ONEX" : "", ! smtpb->esmtp_flags.ESMTP_pipelining ? " PIPELINING" : "", ! smtpb->esmtp_flags.ESMTP_saml ? " SAML" : "", ! smtpb->esmtp_flags.ESMTP_send ? " SEND" : "", ! smtpb->esmtp_flags.ESMTP_size ? " SIZE" : "", ! smtpb->esmtp_flags.ESMTP_soml ? " SOML" : "", ! smtpb->esmtp_flags.ESMTP_starttls ? " STARTTLS" : "", ! smtpb->esmtp_flags.ESMTP_turn ? " TURN" : "", ! smtpb->esmtp_flags.ESMTP_verb ? " VERB" : ""); ! DEBUG1(DBG_DRIVER_MID, "%s.\n", ! smtpb->esmtp_flags.ESMTP_x ? " X*" : ""); ! if (smtpb->esmtp_flags.ESMTP_verb && debug >= DBG_DRIVER_MID) { STR_CLEAR(&smtp_out); (void) str_printf(&smtp_out, VERB); reply = wait_write_command(smtpb, smtpb->short_timeout, ! STR(&smtp_out), (int) STR_LEN(&smtp_out), ! &reply_text); if (REPLY_GROUP (reply) == NEGATIVE_TRY_AGAIN) { /* remote SMTP closed, try again later */ *error_p = try_again(smtpb->tp, reply_text); *************** *** 346,360 **** } } return SMTP_SUCCEED; - malformed_ehlo_reply: - /* This seems to be a reasonable way - to handle malformed EHLO replies: */ - # ifndef NO_LOG_EHLO - /* XXX this is really ugly as it leaves the newlines in place... */ - write_log(WRITE_LOG_SYS, "destination supports esmtp, but is buggy:\n%s", - reply_text); - # endif /* not NO_LOG_EHLO */ - return SMTP_SUCCEED; } } #endif /* HAVE_EHLO */ --- 419,424 ---- *************** *** 372,379 **** (void) str_printf(&smtp_out, HELO(primary_name)); reply = wait_write_command(smtpb, smtpb->short_timeout, ! STR(&smtp_out), (int) STR_LEN(&smtp_out), ! &reply_text); if (REPLY_GROUP(reply) == NEGATIVE_TRY_AGAIN) { /* remote SMTP closed, try again later */ --- 436,443 ---- (void) str_printf(&smtp_out, HELO(primary_name)); reply = wait_write_command(smtpb, smtpb->short_timeout, ! STR(&smtp_out), (int) STR_LEN(&smtp_out), ! &reply_text); if (REPLY_GROUP(reply) == NEGATIVE_TRY_AGAIN) { /* remote SMTP closed, try again later */ *************** *** 388,400 **** #ifdef HAVE_EHLO if (! tried_rset) { /* The following */ ! /* fatal error, probably doesn't understand EHLO */ STR_CLEAR(&smtp_out); (void) str_printf(&smtp_out, "RSET"); reply = wait_write_command(smtpb, smtpb->short_timeout, ! STR(&smtp_out), (int) STR_LEN(&smtp_out), ! &reply_text); if (REPLY_GROUP(reply) == NEGATIVE_TRY_AGAIN) { /* remote SMTP closed, try again later */ --- 452,464 ---- #ifdef HAVE_EHLO if (! tried_rset) { /* The following */ ! /* fatal error, maybe it doesn't understand EHLO */ STR_CLEAR(&smtp_out); (void) str_printf(&smtp_out, "RSET"); reply = wait_write_command(smtpb, smtpb->short_timeout, ! STR(&smtp_out), (int) STR_LEN(&smtp_out), ! &reply_text); if (REPLY_GROUP(reply) == NEGATIVE_TRY_AGAIN) { /* remote SMTP closed, try again later */ *************** *** 415,420 **** --- 479,485 ---- { /* fatal error, return message to sender */ *error_p = fatal_error(smtpb->tp, reply_text); + smtp_shutdown(smtpb); /* be nice and say goodby! */ return SMTP_FAIL; } } *************** *** 423,428 **** --- 488,532 ---- return SMTP_SUCCEED; } + /* + * custom code to safely skip to the end of a line. + */ + static char * + skip_to_eol(cp) + char *cp; + { + while (*cp && *cp != '\n') { + ++cp; + } + if (*cp == '\n') { + ++cp; + } + return cp; + } + + /* + * This seems to be a reasonable way to handle malformed EHLO replies.... + */ + static void + log_malformed_ehlo_reply(error_msg, reply_text) + char *error_msg; + char *reply_text; + { + #ifdef NO_LOG_EHLO + DEBUG2(DBG_DRIVER_LO, "destination supports esmtp, but is buggy: %s;\n%s\n", + error_msg, reply_text); + #else + /* XXX this is really ugly though as it leaves the newlines in place, + * though it should always be with normal SMTP continuation lines so + * shouldn't be too hard to parse.... + */ + write_log(WRITE_LOG_SYS, "destination supports esmtp, but is buggy: %s;\n%s", + error_msg, reply_text); + #endif /* not NO_LOG_EHLO */ + return; + } + + /* * smtp_send - mail a message to a remote SMTP process *************** *** 500,518 **** * if it is slightly incorrect. We simply add 2% in order to account for * \n -> \r\n conversion. */ ! if (smtpb->smtp_flags & ESMTP_size) { str_printf(&smtp_out, " SIZE=%lu", (unsigned long) ((msg_size * 102L) / 100L)); } #if 0 /* ! * This is commented out because we are not supposed to send a ! * non-MIME message on 8BITMIME mode. But sending a non-7bit ! * clean message in 7BIT mode isn't a good idea either. Sigh. ! * Something more sophisticated is definitely needed here. ! */ ! if (smtpb->smtp_flags & ESMTP_8bitmime) { ! str_printf(&smtp_out, " BODY 8BITMIME"); } #endif --- 604,626 ---- * if it is slightly incorrect. We simply add 2% in order to account for * \n -> \r\n conversion. */ ! if (smtpb->esmtp_flags.ESMTP_size) { str_printf(&smtp_out, " SIZE=%lu", (unsigned long) ((msg_size * 102L) / 100L)); } #if 0 /* ! * This is commented out because we are not supposed to send a non-MIME ! * message on 8BITMIME mode and we don't have any way to either detect if ! * the message is already in MIME format or to force a MIME conversion if ! * necessary. Sending a non-7bit clean message in 7BIT mode isn't a good ! * idea either, but is a common practice. Sigh. We'll just avoid saying ! * what we're sending.... ! */ ! if (smtpb->esmtp_flags.ESMTP_8bitmime) { ! str_printf(&smtp_out, " BODY=8BITMIME"); ! } else { ! str_printf(&smtp_out, " BODY=7BIT"); } #endif *************** *** 626,638 **** do_smtp_shutdown(smtpb, reply); return FAIL; } ! } else { ! /* successful thus far, or pipelining.... */ cur->succ = okay; okay = cur; } } ! if (! okay) { do_smtp_shutdown(smtpb, REPLY_TRANS_FAILURE); return FAIL; } --- 734,746 ---- do_smtp_shutdown(smtpb, reply); return FAIL; } ! } else if (!smtpb->esmtp_flags.ESMTP_pipelining) { ! /* successful thus far.... */ cur->succ = okay; okay = cur; } } ! if (!smtpb->esmtp_flags.ESMTP_pipelining && !okay) { do_smtp_shutdown(smtpb, REPLY_TRANS_FAILURE); return FAIL; } *************** *** 651,660 **** /* * we only "pipeline" the commands up to the DATA_BEGIN.... */ ! if (smtpb->smtp_flags & ESMTP_pipelining) { ! addr = okay; /* get back to where we started */ ! okay = NULL; ! if (flush_command_stream(smtpb, &reply_text) != REPLY_OK) { *error_p = try_again(tp, reply_text); insert_addr_list(addr, defer, *error_p); --- 759,765 ---- /* * we only "pipeline" the commands up to the DATA_BEGIN.... */ ! if (smtpb->esmtp_flags.ESMTP_pipelining) { if (flush_command_stream(smtpb, &reply_text) != REPLY_OK) { *error_p = try_again(tp, reply_text); insert_addr_list(addr, defer, *error_p); *************** *** 875,881 **** register int len; /* length of command */ char **reply_text; /* text of response from remote */ { ! if (smtpb->smtp_flags & ESMTP_pipelining) { return write_command_nowait (smtpb, text, len); } else { return wait_write_command (smtpb, timeout, text, len, reply_text); --- 980,986 ---- register int len; /* length of command */ char **reply_text; /* text of response from remote */ { ! if (smtpb->esmtp_flags.ESMTP_pipelining) { return write_command_nowait (smtpb, text, len); } else { return wait_write_command (smtpb, timeout, text, len, reply_text); Index: master/smail/src/transports/smtplib.h diff -c master/smail/src/transports/smtplib.h:1.6 master/smail/src/transports/smtplib.h:1.10 *** master/smail/src/transports/smtplib.h:1.6 Wed Feb 28 09:27:46 1996 --- master/smail/src/transports/smtplib.h Thu Sep 16 16:02:24 1999 *************** *** 1,5 **** /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_107 $:$Id: smtplib.h,v 1.6 1996/02/28 14:27:46 woods Exp $" */ /* --- 1,5 ---- /* ! #ident "@(#)smail/src:$Name: RELEASE-3_2_0_108 $:$Id: smtplib.h,v 1.10 1999/09/16 20:02:24 woods Exp $" */ /* *************** *** 21,34 **** #define SMTP_AGAIN (-2) #define SMTP_EHLO_FAIL (-3) ! #define ESMTP_none 0x0000 ! #define ESMTP_basic 0x0001 ! #define ESMTP_8bitmime 0x0002 ! #define ESMTP_size 0x0004 ! #define ESMTP_pipelining 0x0008 ! #define ESMTP_verbose 0x0010 ! #define ESMTP_one 0x0020 ! #define ESMTP_queue 0x0040 /* * the following structure is passed around between SMTP functions and --- 21,54 ---- #define SMTP_AGAIN (-2) #define SMTP_EHLO_FAIL (-3) ! /* ! * NOTE: #define sucks for bit-flags, enum is only slightly better and still ! * requires that we be able to count in binary and understand binary logic ! * idioms. Bit-fields are the best way to represent flags (except for when you ! * want to mass-assign them all to one value! :-). ! */ ! typedef struct esmtpflags { ! unsigned int ESMTP_basic : 1; /* got EHLO 250 reply */ ! unsigned int ESMTP_8bitmime : 1; /* rfc1652 */ ! unsigned int ESMTP_atrn : 1; /* rfc2645 */ ! unsigned int ESMTP_auth : 1; /* rfc2645 */ ! unsigned int ESMTP_chunking : 1; /* rfc1830 */ ! unsigned int ESMTP_dsn : 1; /* rfc1891 */ ! unsigned int ESMTP_enhancedstatuscodes : 1; /* rfc2034 */ ! unsigned int ESMTP_etrn : 1; /* rfc1985 */ ! unsigned int ESMTP_expn : 1; /* rfc821+rfc1869 */ ! unsigned int ESMTP_help : 1; /* rfc821+rfc1869 */ ! unsigned int ESMTP_onex : 1; /* One message transaction only [Eric Allman] */ ! unsigned int ESMTP_pipelining : 1; /* rfc2197 */ ! unsigned int ESMTP_saml : 1; /* rfc821+rfc1869 */ ! unsigned int ESMTP_send : 1; /* rfc821+rfc1869 */ ! unsigned int ESMTP_size : 1; /* rfc1870 */ ! unsigned int ESMTP_soml : 1; /* rfc821+rfc1869 */ ! unsigned int ESMTP_starttls : 1; /* rfc2487 */ ! unsigned int ESMTP_turn : 1; /* rfc821+rfc1869 */ ! unsigned int ESMTP_verb : 1; /* Verbose [Eric Allman] */ ! unsigned int ESMTP_x : 1; /* unspported, non-standard, unregistered */ ! } esmtpf_t; /* * the following structure is passed around between SMTP functions and *************** *** 44,50 **** unsigned long_timeout; /* normal SMTP read timeout period */ char *nl; /* line terminator string */ struct transport *tp; /* associated transport */ ! int smtp_flags; /* ESMTP extensions supported by remote */ unsigned long max_size; /* message size limit of remote */ }; --- 64,70 ---- unsigned long_timeout; /* normal SMTP read timeout period */ char *nl; /* line terminator string */ struct transport *tp; /* associated transport */ ! esmtpf_t esmtp_flags; /* ESMTP extensions supported by remote */ unsigned long max_size; /* message size limit of remote */ }; Index: master/smail/src/transports/tcpsmtp.c diff -c master/smail/src/transports/tcpsmtp.c:1.38 master/smail/src/transports/tcpsmtp.c:1.43 *** master/smail/src/transports/tcpsmtp.c:1.38 Sun Aug 8 12:46:12 1999 --- master/smail/src/transports/tcpsmtp.c Thu Sep 16 20:36:36 1999 *************** *** 1,5 **** /* ! #ident "@(#)smail/src/transports:$Name: RELEASE-3_2_0_107 $:$Id: tcpsmtp.c,v 1.38 1999/08/08 16:46:12 woods Exp $" */ /* --- 1,5 ---- /* ! #ident "@(#)smail/src/transports:$Name: RELEASE-3_2_0_108 $:$Id: tcpsmtp.c,v 1.43 1999/09/17 00:36:36 woods Exp $" */ /* *************** *** 381,387 **** smtpbuf.nl = "\r\n"; tp->flags |= PUT_CRLF; smtpbuf.tp = tp; ! smtpbuf.smtp_flags = ESMTP_none; smtpbuf.max_size = 0; DEBUG(DBG_DRIVER_LO, "connected\n"); --- 381,406 ---- smtpbuf.nl = "\r\n"; tp->flags |= PUT_CRLF; smtpbuf.tp = tp; ! smtpbuf.esmtp_flags.ESMTP_basic = 0; ! smtpbuf.esmtp_flags.ESMTP_8bitmime = 0; ! smtpbuf.esmtp_flags.ESMTP_atrn = 0; ! smtpbuf.esmtp_flags.ESMTP_auth = 0; ! smtpbuf.esmtp_flags.ESMTP_chunking = 0; ! smtpbuf.esmtp_flags.ESMTP_dsn = 0; ! smtpbuf.esmtp_flags.ESMTP_enhancedstatuscodes = 0; ! smtpbuf.esmtp_flags.ESMTP_etrn = 0; ! smtpbuf.esmtp_flags.ESMTP_expn = 0; ! smtpbuf.esmtp_flags.ESMTP_help = 0; ! smtpbuf.esmtp_flags.ESMTP_onex = 0; ! smtpbuf.esmtp_flags.ESMTP_pipelining = 0; ! smtpbuf.esmtp_flags.ESMTP_saml = 0; ! smtpbuf.esmtp_flags.ESMTP_send = 0; ! smtpbuf.esmtp_flags.ESMTP_size = 0; ! smtpbuf.esmtp_flags.ESMTP_soml = 0; ! smtpbuf.esmtp_flags.ESMTP_starttls = 0; ! smtpbuf.esmtp_flags.ESMTP_turn = 0; ! smtpbuf.esmtp_flags.ESMTP_verb = 0; ! smtpbuf.esmtp_flags.ESMTP_x = 0; smtpbuf.max_size = 0; DEBUG(DBG_DRIVER_LO, "connected\n"); *************** *** 424,446 **** (void) fclose(smtpbuf.out); return SUCCEED; } - - /* - * tpd_smtp - obsolescent name for tpd_tcpsmtp driver - * - * This routine exists for backward compatibility with Smail alpha - * releases prior to version 3.1.12. - */ - void - tpd_smtp(addr, succeed, defer, fail) - struct addr *addr; /* recipient addresses for transport */ - struct addr **succeed; /* successful deliveries */ - struct addr **defer; /* defer until a later queue run */ - struct addr **fail; /* failed deliveries */ - { - tpd_tcpsmtp(addr, succeed, defer, fail); - } - /* * tpb_tcpsmtp - read the configuration file attributes --- 443,448 ---- *************** *** 503,538 **** fprintf(f, "\tlong_timeout=%s,\n", ltoival((long) priv->long_timeout)); } - - - /* - * tpb_smtp - obsolescent name for tcpsmtp driver - * - * This routine exists for backward compatibility with Smail alpha - * releases prior to version 3.1.12. - */ - char * - tpb_smtp(tp, attrs) - struct transport *tp; /* transport entry being defined */ - struct attribute *attrs; /* list of per-driver attributes */ - { - return tpb_tcpsmtp(tp, attrs); - } - - - /* - * tpp_smtp - dump the configuration attributes - * - * This routine exists for backward compatibility with Smail alpha - * releases prior to version 3.1.12. - */ - void - tpp_smtp(f, tp) - FILE * f; - struct transport *tp; - { - tpp_tcpsmtp(f, tp); - } static char * --- 505,510 ----