[Python-checkins] CVS: python/dist/src/Lib smtplib.py,1.41,1.42
Guido van Rossum
gvanrossum@users.sourceforge.net
Fri, 14 Sep 2001 09:08:17 -0700
Update of /cvsroot/python/python/dist/src/Lib
In directory usw-pr-cvs1:/tmp/cvs-serv7651
Modified Files:
smtplib.py
Log Message:
SF patch #461413 (Gerhard Häring): Add STARTTLS feature to smtplib
This patch adds the features from RFC 2487 (Secure SMTP
over TLS) to the smtplib module:
- A starttls() function
- Wrapper classes that simulate enough of sockets and
files for smtplib, but really wrap a SSLObject
- reset the list of known SMTP extensions at each call
of ehlo(). This should have been the case anyway.
Index: smtplib.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/smtplib.py,v
retrieving revision 1.41
retrieving revision 1.42
diff -C2 -d -r1.41 -r1.42
*** smtplib.py 2001/09/11 15:57:46 1.41
--- smtplib.py 2001/09/14 16:08:14 1.42
***************
*** 3,8 ****
'''SMTP/ESMTP client class.
! This should follow RFC 821 (SMTP), RFC 1869 (ESMTP) and RFC 2554 (SMTP
! Authentication).
Notes:
--- 3,8 ----
'''SMTP/ESMTP client class.
! This should follow RFC 821 (SMTP), RFC 1869 (ESMTP), RFC 2554 (SMTP
! Authentication) and RFC 2487 (Secure SMTP over TLS).
Notes:
***************
*** 125,128 ****
--- 125,163 ----
"""
+ class SSLFakeSocket:
+ """A fake socket object that really wraps a SSLObject.
+
+ It only supports what is needed in smtplib.
+ """
+ def __init__(self, realsock, sslobj):
+ self.realsock = realsock
+ self.sslobj = sslobj
+
+ def send(self, str):
+ self.sslobj.write(str)
+ return len(str)
+
+ def close(self):
+ self.realsock.close()
+
+ class SSLFakeFile:
+ """A fake file like object that really wraps a SSLObject.
+
+ It only supports what is needed in smtplib.
+ """
+ def __init__( self, sslobj):
+ self.sslobj = sslobj
+
+ def readline(self):
+ str = ""
+ chr = None
+ while chr != "\n":
+ chr = self.sslobj.read(1)
+ str += chr
+ return str
+
+ def close(self):
+ pass
+
def quoteaddr(addr):
"""Quote a subset of the email addresses defined by RFC 821.
***************
*** 334,337 ****
--- 369,373 ----
host.
"""
+ self.esmtp_features = {}
if name:
self.putcmd("ehlo", name)
***************
*** 507,510 ****
--- 543,562 ----
return (code, resp)
+ def starttls(self, keyfile = None, certfile = None):
+ """Puts the connection to the SMTP server into TLS mode.
+
+ If the server supports TLS, this will encrypt the rest of the SMTP
+ session. If you provide the keyfile and certfile parameters,
+ the identity of the SMTP server and client can be checked. This,
+ however, depends on whether the socket module really checks the
+ certificates.
+ """
+ (resp, reply) = self.docmd("STARTTLS")
+ if resp == 220:
+ sslobj = socket.ssl(self.sock, keyfile, certfile)
+ self.sock = SSLFakeSocket(self.sock, sslobj)
+ self.file = SSLFakeFile(sslobj)
+ return (resp, reply)
+
def sendmail(self, from_addr, to_addrs, msg, mail_options=[],
rcpt_options=[]):