CVS: tmda/TMDA ChangeLog, 1.289, 1.290 Defaults.py, 1.186, 1.187 Util.py, 1.107, 1.108

"Jason R. Mastaler" <[email protected]>
Newsgroups gmane.mail.spam.tmda.cvs
Message-ID <[email protected]>
Update of /cvsroot/tmda/tmda/TMDA
In directory sc8-pr-cvs1:/tmp/cvs-serv15319/TMDA

Modified Files:
	ChangeLog Defaults.py Util.py 
Log Message:
Bugfix/security.

It looks like this week's TMDA flame-war on the qmail list did have
one positive outcome, and that is a new method of invoking
/usr/sbin/sendmail that doesn't use the shell.  Thus we avoid the
possible security implications as well as argument quoting and
escaping issues.

You can avoid the shell by passing a tuple of arguments to
Util.pipecmd() as the command instead of a string.  This will cause
the popen2.Popen3() code to execvp() "/usr/bin/sendmail" with these
arguments exactly, with no trip through any shell.

We already knew this, as ancient TMDA did exactly this.  The problem
was that we kept getting burned by silent failures in the case of a
non-zero exit from the child process (e.g, if /usr/sbin/sendmail was a
truncated file, the message would silently be dropped on the floor).
What I didn't realize is that I needed to call wait(), capturing the
return value, and then use os.WIFEXITED(), os.WEXITSTATUS(), and
friends to get the exit status of the invoked command.

Our Util.pipecmd() function already does the above, so we just
had to pass the arguments in as a tuple, and now we get the best
of both worlds.  The scary security warning has been removed
from the Defaults.OUTGOINGMAIL comments.

Thanks to Chuck Cazabon (private e-mail xchange) for helping me iron
this out.


Index: ChangeLog
===================================================================
RCS file: /cvsroot/tmda/tmda/TMDA/ChangeLog,v
retrieving revision 1.289
retrieving revision 1.290
diff -u -r1.289 -r1.290
--- ChangeLog	9 Oct 2003 23:51:32 -0000	1.289
+++ ChangeLog	10 Oct 2003 03:29:39 -0000	1.290
@@ -1,5 +1,9 @@
 2003-10-09  Jason R. Mastaler  <[email protected]>
 
+	* Util.py (sendmail): If using /usr/sbin/sendmail, pass a tuple of
+	arguments into pipecmd() instead of a string to avoid the shell
+	completely.  Also, add '-i' to the list of args.
+	
 	* Version.py (PLATFORM): Use the more descriptive 'platform'
 	module if it's available.
 

Index: Defaults.py
===================================================================
RCS file: /cvsroot/tmda/tmda/TMDA/Defaults.py,v
retrieving revision 1.186
retrieving revision 1.187
diff -u -r1.186 -r1.187
--- Defaults.py	23 Jul 2003 20:01:05 -0000	1.186
+++ Defaults.py	10 Oct 2003 03:29:39 -0000	1.187
@@ -189,15 +189,7 @@
 #
 # "sendmail"
 #    Deliver messages via the command line interface to the sendmail
-#    program (/usr/sbin/sendmail).  Use at your own risk.  "smtp" is
-#    highly recommended.
-#
-#    SECURITY WARNING: The 'sendmail' method is not secure.  Because
-#    this method uses popen(), it goes through the shell.  It does not
-#    scan the arguments for potential exploits and so it should be
-#    considered unsafe.  For performance reasons, it's not recommended
-#    either -- use the 'smtp' method instead, even if
-#    MAIL_TRANSFER_AGENT is "sendmail".
+#    program (/usr/sbin/sendmail).
 #
 # Default is "smtp"
 if not vars().has_key('OUTGOINGMAIL'):

Index: Util.py
===================================================================
RCS file: /cvsroot/tmda/tmda/TMDA/Util.py,v
retrieving revision 1.107
retrieving revision 1.108
diff -u -r1.107 -r1.108
--- Util.py	1 Oct 2003 22:46:42 -0000	1.107
+++ Util.py	10 Oct 2003 03:29:39 -0000	1.108
@@ -564,8 +564,12 @@
         server.sendmail(envsender, envrecip, msgstr)
         server.quit()
     elif Defaults.OUTGOINGMAIL == 'sendmail':
-        cmd = "%s -f '%s' -- '%s'" % (Defaults.SENDMAIL_PROGRAM,
-                                      envsender, envrecip)
+        # You can avoid the shell by passing a tuple of arguments as
+        # the command instead of a string.  This will cause the
+        # popen2.Popen3() code to execvp() "/usr/bin/sendmail" with
+        # these arguments exactly, with no trip through any shell.
+        cmd = (Defaults.SENDMAIL_PROGRAM, '-i',
+               '-f', envsender, '--', envrecip)
         pipecmd(cmd, msgstr)
     else:
         raise Errors.ConfigError, \
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.