Patch #: Add POP3 over SSL support.
diff --git a/Lib/poplib.py b/Lib/poplib.py
index 0b22b2e..c14b8b7 100644
--- a/Lib/poplib.py
+++ b/Lib/poplib.py
@@ -7,6 +7,7 @@
 #         [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 @@
 
 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 @@
 # 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 @@
             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