summaryrefslogtreecommitdiff
path: root/Lib/poplib.py
diff options
context:
space:
mode:
authorMartin v. Löwis <martin@v.loewis.de>2003-10-31 12:52:35 +0000
committerMartin v. Löwis <martin@v.loewis.de>2003-10-31 12:52:35 +0000
commit48440b7c2751813da110689aff07b4e7ed4ac73f (patch)
tree08f83ca07af7d2e44bedc815fcf97099ac1b9a4d /Lib/poplib.py
parent9ad853bc371e420b20dacbfe00af9da2ba5d3b6d (diff)
downloadcpython-git-48440b7c2751813da110689aff07b4e7ed4ac73f.tar.gz
Patch #: Add POP3 over SSL support.
Diffstat (limited to 'Lib/poplib.py')
-rw-r--r--Lib/poplib.py90
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