Patch #: Add POP3 over SSL support.
diff --git a/Doc/lib/libpoplib.tex b/Doc/lib/libpoplib.tex
index f5da970..b056693 100644
--- a/Doc/lib/libpoplib.tex
+++ b/Doc/lib/libpoplib.tex
@@ -13,9 +13,12 @@
 \indexii{POP3}{protocol}
 
 This module defines a class, \class{POP3}, which encapsulates a
-connection to an POP3 server and implements the protocol as defined in
+connection to a POP3 server and implements the protocol as defined in
 \rfc{1725}.  The \class{POP3} class supports both the minimal and
-optional command sets.
+optional command sets. Additionally, this module provides a class
+\class{POP3_SSL}, which provides support for connecting to POP3
+servers that use SSL as an underlying protocol layer.
+
 
 Note that POP3, though widely supported, is obsolescent.  The
 implementation quality of POP3 servers varies widely, and too many are
@@ -31,6 +34,16 @@
 If \var{port} is omitted, the standard POP3 port (110) is used.
 \end{classdesc}
 
+\begin{classdesc}{POP3_SSL}{host\optional{, port\optional{, keyfile\optional{, certfile}}}}
+This is a subclass of \class{POP3} that connects to the server over an
+SSL encrypted socket.  If \var{port} is not specified, 995, the
+standard POP3-over-SSL port is used.  \var{keyfile} and \var{certfile}
+are also optional - they can contain a PEM formatted private key and
+certificate chain file for the SSL connection.
+
+\versionadded{2.4}
+\end{classdesc}
+
 One exception is defined as an attribute of the \module{poplib} module:
 
 \begin{excdesc}{error_proto}
@@ -143,6 +156,9 @@
 \var{octets})}.
 \end{methoddesc}
 
+Instances of \class{POP3_SSL} have no additional methods. The
+interface of this subclass is identical to its parent.
+
 
 \subsection{POP3 Example \label{pop3-example}}
 
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
diff --git a/Misc/ACKS b/Misc/ACKS
index c836df6..a8d645a 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -562,6 +562,7 @@
 Bill Tutt
 Doobee R. Tzeck
 Lionel Ulmer
+Hector Urtubia
 Frank Vercruesse
 Jaap Vermeulen
 Al Vezza
diff --git a/Misc/NEWS b/Misc/NEWS
index 4bbbb57..970c814 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -101,6 +101,8 @@
 Library
 -------
 
+- poplib.POP3_SSL has been added.
+
 - tmpfile.mkstemp now returns an absolute path even if dir is relative.
 
 - urlparse is RFC 2396 compliant.