/gdata/tlslite/integration/POP3_TLS.py
Python | 142 lines | 97 code | 5 blank | 40 comment | 2 complexity | 6eb4668324991c2047b15843afd06955 MD5 | raw file
1"""TLS Lite + poplib.""" 2 3import socket 4from poplib import POP3 5from gdata.tlslite.TLSConnection import TLSConnection 6from gdata.tlslite.integration.ClientHelper import ClientHelper 7 8# POP TLS PORT 9POP3_TLS_PORT = 995 10 11class POP3_TLS(POP3, ClientHelper): 12 """This class extends L{poplib.POP3} with TLS support.""" 13 14 def __init__(self, host, port = POP3_TLS_PORT, 15 username=None, password=None, sharedKey=None, 16 certChain=None, privateKey=None, 17 cryptoID=None, protocol=None, 18 x509Fingerprint=None, 19 x509TrustList=None, x509CommonName=None, 20 settings=None): 21 """Create a new POP3_TLS. 22 23 For client authentication, use one of these argument 24 combinations: 25 - username, password (SRP) 26 - username, sharedKey (shared-key) 27 - certChain, privateKey (certificate) 28 29 For server authentication, you can either rely on the 30 implicit mutual authentication performed by SRP or 31 shared-keys, or you can do certificate-based server 32 authentication with one of these argument combinations: 33 - cryptoID[, protocol] (requires cryptoIDlib) 34 - x509Fingerprint 35 - x509TrustList[, x509CommonName] (requires cryptlib_py) 36 37 Certificate-based server authentication is compatible with 38 SRP or certificate-based client authentication. It is 39 not compatible with shared-keys. 40 41 The caller should be prepared to handle TLS-specific 42 exceptions. See the client handshake functions in 43 L{tlslite.TLSConnection.TLSConnection} for details on which 44 exceptions might be raised. 45 46 @type host: str 47 @param host: Server to connect to. 48 49 @type port: int 50 @param port: Port to connect to. 51 52 @type username: str 53 @param username: SRP or shared-key username. Requires the 54 'password' or 'sharedKey' argument. 55 56 @type password: str 57 @param password: SRP password for mutual authentication. 58 Requires the 'username' argument. 59 60 @type sharedKey: str 61 @param sharedKey: Shared key for mutual authentication. 62 Requires the 'username' argument. 63 64 @type certChain: L{tlslite.X509CertChain.X509CertChain} or 65 L{cryptoIDlib.CertChain.CertChain} 66 @param certChain: Certificate chain for client authentication. 67 Requires the 'privateKey' argument. Excludes the SRP or 68 shared-key related arguments. 69 70 @type privateKey: L{tlslite.utils.RSAKey.RSAKey} 71 @param privateKey: Private key for client authentication. 72 Requires the 'certChain' argument. Excludes the SRP or 73 shared-key related arguments. 74 75 @type cryptoID: str 76 @param cryptoID: cryptoID for server authentication. Mutually 77 exclusive with the 'x509...' arguments. 78 79 @type protocol: str 80 @param protocol: cryptoID protocol URI for server 81 authentication. Requires the 'cryptoID' argument. 82 83 @type x509Fingerprint: str 84 @param x509Fingerprint: Hex-encoded X.509 fingerprint for 85 server authentication. Mutually exclusive with the 'cryptoID' 86 and 'x509TrustList' arguments. 87 88 @type x509TrustList: list of L{tlslite.X509.X509} 89 @param x509TrustList: A list of trusted root certificates. The 90 other party must present a certificate chain which extends to 91 one of these root certificates. The cryptlib_py module must be 92 installed to use this parameter. Mutually exclusive with the 93 'cryptoID' and 'x509Fingerprint' arguments. 94 95 @type x509CommonName: str 96 @param x509CommonName: The end-entity certificate's 'CN' field 97 must match this value. For a web server, this is typically a 98 server name such as 'www.amazon.com'. Mutually exclusive with 99 the 'cryptoID' and 'x509Fingerprint' arguments. Requires the 100 'x509TrustList' argument. 101 102 @type settings: L{tlslite.HandshakeSettings.HandshakeSettings} 103 @param settings: Various settings which can be used to control 104 the ciphersuites, certificate types, and SSL/TLS versions 105 offered by the client. 106 """ 107 108 self.host = host 109 self.port = port 110 msg = "getaddrinfo returns an empty list" 111 self.sock = None 112 for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM): 113 af, socktype, proto, canonname, sa = res 114 try: 115 self.sock = socket.socket(af, socktype, proto) 116 self.sock.connect(sa) 117 except socket.error, msg: 118 if self.sock: 119 self.sock.close() 120 self.sock = None 121 continue 122 break 123 if not self.sock: 124 raise socket.error, msg 125 126 ### New code below (all else copied from poplib) 127 ClientHelper.__init__(self, 128 username, password, sharedKey, 129 certChain, privateKey, 130 cryptoID, protocol, 131 x509Fingerprint, 132 x509TrustList, x509CommonName, 133 settings) 134 135 self.sock = TLSConnection(self.sock) 136 self.sock.closeSocket = True 137 ClientHelper._handshake(self, self.sock) 138 ### 139 140 self.file = self.sock.makefile('rb') 141 self._debugging = 0 142 self.welcome = self._getresp()