diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2012-11-23 19:13:48 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2012-11-23 19:13:48 (GMT) |
commit | 8618d7457b1a648a8183966d930077e5754dc0ed (patch) | |
tree | c5fba1246a6af3cb2a700ac1cdbc970bc19f6940 /Lib/poplib.py | |
parent | 25cee19beb3117f834100cf29cff625c98d0da29 (diff) | |
download | cpython-8618d7457b1a648a8183966d930077e5754dc0ed.zip cpython-8618d7457b1a648a8183966d930077e5754dc0ed.tar.gz cpython-8618d7457b1a648a8183966d930077e5754dc0ed.tar.bz2 |
Issue #4473: Add a POP3.stls() to switch a clear-text POP3 session into an encrypted POP3 session, on supported servers.
Patch by Lorenzo Catucci.
Diffstat (limited to 'Lib/poplib.py')
-rw-r--r-- | Lib/poplib.py | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/Lib/poplib.py b/Lib/poplib.py index ccb28e5..bfcde02 100644 --- a/Lib/poplib.py +++ b/Lib/poplib.py @@ -15,6 +15,12 @@ Based on the J. Myers POP3 draft, Jan. 96 import re, socket +try: + import ssl + HAVE_SSL = True +except ImportError: + HAVE_SSL = False + __all__ = ["POP3","error_proto"] # Exception raised when an error or invalid response is received: @@ -56,6 +62,7 @@ class POP3: TOP msg n top(msg, n) UIDL [msg] uidl(msg = None) CAPA capa() + STLS stls() Raises one exception: 'error_proto'. @@ -82,6 +89,7 @@ class POP3: timeout=socket._GLOBAL_DEFAULT_TIMEOUT): self.host = host self.port = port + self._tls_established = False self.sock = self._create_socket(timeout) self.file = self.sock.makefile('rb') self._debugging = 0 @@ -352,21 +360,42 @@ class POP3: raise error_proto('-ERR CAPA not supported by server') return caps -try: - import ssl -except ImportError: - pass -else: + + def stls(self, context=None): + """Start a TLS session on the active connection as specified in RFC 2595. + + context - a ssl.SSLContext + """ + if not HAVE_SSL: + raise error_proto('-ERR TLS support missing') + if self._tls_established: + raise error_proto('-ERR TLS session already established') + caps = self.capa() + if not 'STLS' in caps: + raise error_proto('-ERR STLS not supported by server') + if context is None: + context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + context.options |= ssl.OP_NO_SSLv2 + resp = self._shortcmd('STLS') + self.sock = context.wrap_socket(self.sock) + self.file = self.sock.makefile('rb') + self._tls_established = True + return resp + + +if HAVE_SSL: class POP3_SSL(POP3): """POP3 client class over SSL connection - Instantiate with: POP3_SSL(hostname, port=995, keyfile=None, certfile=None) + Instantiate with: POP3_SSL(hostname, port=995, keyfile=None, certfile=None, + context=None) hostname - the hostname of the pop3 over ssl server port - port number keyfile - PEM formatted file that countains your private key certfile - PEM formatted certificate chain file + context - a ssl.SSLContext See the methods of the parent class POP3 for more documentation. """ @@ -392,6 +421,13 @@ else: sock = ssl.wrap_socket(sock, self.keyfile, self.certfile) return sock + def stls(self, keyfile=None, certfile=None, context=None): + """The method unconditionally raises an exception since the + STLS command doesn't make any sense on an already established + SSL/TLS session. + """ + raise error_proto('-ERR TLS session already established') + __all__.append("POP3_SSL") if __name__ == "__main__": |