diff options
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 0b22b2e..c14b8b7 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  | 
