diff options
author | Martin v. Löwis <martin@v.loewis.de> | 2003-10-31 12:52:35 +0000 |
---|---|---|
committer | Martin v. Löwis <martin@v.loewis.de> | 2003-10-31 12:52:35 +0000 |
commit | 48440b7c2751813da110689aff07b4e7ed4ac73f (patch) | |
tree | 08f83ca07af7d2e44bedc815fcf97099ac1b9a4d /Lib/poplib.py | |
parent | 9ad853bc371e420b20dacbfe00af9da2ba5d3b6d (diff) | |
download | cpython-git-48440b7c2751813da110689aff07b4e7ed4ac73f.tar.gz |
Patch #: Add POP3 over SSL support.
Diffstat (limited to 'Lib/poplib.py')
-rw-r--r-- | Lib/poplib.py | 90 |
1 files changed, 89 insertions, 1 deletions
diff --git a/Lib/poplib.py b/Lib/poplib.py index 0b22b2e4ef..c14b8b7d66 100644 --- a/Lib/poplib.py +++ b/Lib/poplib.py @@ -7,6 +7,7 @@ Based on the J. Myers POP3 draft, Jan. 96 # [heavily stealing from nntplib.py] # Updated: Piers Lauder <piers@cs.su.oz.au> [Jul '97] # String method conversion and test jig improvements by ESR, February 2001. +# Added the POP3_SSL class. Methods loosely based on IMAP_SSL. Hector Urtubia <urtubia@mrbook.org> Aug 2003 # Example (see the test function at the end of this file) @@ -14,7 +15,7 @@ Based on the J. Myers POP3 draft, Jan. 96 import re, socket -__all__ = ["POP3","error_proto"] +__all__ = ["POP3","error_proto","POP3_SSL"] # Exception raised when an error or invalid response is received: @@ -23,6 +24,9 @@ class error_proto(Exception): pass # Standard Port POP3_PORT = 110 +# POP SSL PORT +POP3_SSL_PORT = 995 + # Line terminators (we always output CRLF, but accept any of CRLF, LFCR, LF) CR = '\r' LF = '\n' @@ -317,6 +321,90 @@ class POP3: return self._shortcmd('UIDL %s' % which) return self._longcmd('UIDL') +class POP3_SSL(POP3): + """POP3 client class over SSL connection + + Instantiate with: POP3_SSL(hostname, port=995, keyfile=None, certfile=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 + + See the methods of the parent class POP3 for more documentation. + """ + + def __init__(self, host, port = POP3_SSL_PORT, keyfile = None, certfile = None): + self.host = host + self.port = port + self.keyfile = keyfile + self.certfile = certfile + self.buffer = "" + msg = "getaddrinfo returns an empty list" + self.sock = None + for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM): + af, socktype, proto, canonname, sa = res + try: + self.sock = socket.socket(af, socktype, proto) + self.sock.connect(sa) + except socket.error, msg: + if self.sock: + self.sock.close() + self.sock = None + continue + break + if not self.sock: + raise socket.error, msg + self.file = self.sock.makefile('rb') + self.sslobj = socket.ssl(self.sock, self.keyfile, self.certfile) + self._debugging = 0 + self.welcome = self._getresp() + + def _fillBuffer(self): + localbuf = self.sslobj.read() + if len(localbuf) == 0: + raise error_proto('-ERR EOF') + self.buffer += localbuf + + def _getline(self): + line = "" + renewline = re.compile(r'.*?\n') + match = renewline.match(self.buffer) + while not match: + self._fillBuffer() + match = renewline.match(self.buffer) + line = match.group(0) + self.buffer = renewline.sub('' ,self.buffer, 1) + if self._debugging > 1: print '*get*', `line` + + octets = len(line) + if line[-2:] == CRLF: + return line[:-2], octets + if line[0] == CR: + return line[1:-1], octets + return line[:-1], octets + + def _putline(self, line): + if self._debugging > 1: print '*put*', `line` + line += CRLF + bytes = len(line) + while bytes > 0: + sent = self.sslobj.write(line) + if sent == bytes: + break # avoid copy + line = line[sent:] + bytes = bytes - sent + + def quit(self): + """Signoff: commit changes on server, unlock mailbox, close connection.""" + try: + resp = self._shortcmd('QUIT') + except error_proto, val: + resp = val + self.sock.close() + del self.sslobj, self.sock + return resp + if __name__ == "__main__": import sys |