1# Authors: 2# Trevor Perrin 3# Kees Bos - Fixes for compatibility with different Python versions 4# Martin von Loewis - python 3 port 5# 6# See the LICENSE file for legal information regarding use of this file. 7 8 9"""TLS Lite + xmlrpclib.""" 10 11try: 12 import xmlrpclib 13 import httplib 14except ImportError: 15 # Python 3 16 from xmlrpc import client as xmlrpclib 17 from http import client as httplib 18from tlslite.integration.httptlsconnection import HTTPTLSConnection 19from tlslite.integration.clienthelper import ClientHelper 20import tlslite.errors 21 22 23class XMLRPCTransport(xmlrpclib.Transport, ClientHelper): 24 """Handles an HTTPS transaction to an XML-RPC server.""" 25 26 # Pre python 2.7, the make_connection returns a HTTP class 27 transport = xmlrpclib.Transport() 28 conn_class_is_http = not hasattr(transport, '_connection') 29 del(transport) 30 31 def __init__(self, use_datetime=0, 32 username=None, password=None, 33 certChain=None, privateKey=None, 34 checker=None, 35 settings=None, 36 ignoreAbruptClose=False): 37 """Create a new XMLRPCTransport. 38 39 An instance of this class can be passed to L{xmlrpclib.ServerProxy} 40 to use TLS with XML-RPC calls:: 41 42 from tlslite import XMLRPCTransport 43 from xmlrpclib import ServerProxy 44 45 transport = XMLRPCTransport(user="alice", password="abra123") 46 server = ServerProxy("https://localhost", transport) 47 48 For client authentication, use one of these argument 49 combinations: 50 - username, password (SRP) 51 - certChain, privateKey (certificate) 52 53 For server authentication, you can either rely on the 54 implicit mutual authentication performed by SRP or 55 you can do certificate-based server 56 authentication with one of these argument combinations: 57 - x509Fingerprint 58 59 Certificate-based server authentication is compatible with 60 SRP or certificate-based client authentication. 61 62 The constructor does not perform the TLS handshake itself, but 63 simply stores these arguments for later. The handshake is 64 performed only when this class needs to connect with the 65 server. Thus you should be prepared to handle TLS-specific 66 exceptions when calling methods of L{xmlrpclib.ServerProxy}. See the 67 client handshake functions in 68 L{tlslite.TLSConnection.TLSConnection} for details on which 69 exceptions might be raised. 70 71 @type username: str 72 @param username: SRP username. Requires the 73 'password' argument. 74 75 @type password: str 76 @param password: SRP password for mutual authentication. 77 Requires the 'username' argument. 78 79 @type certChain: L{tlslite.x509certchain.X509CertChain} 80 @param certChain: Certificate chain for client authentication. 81 Requires the 'privateKey' argument. Excludes the SRP arguments. 82 83 @type privateKey: L{tlslite.utils.rsakey.RSAKey} 84 @param privateKey: Private key for client authentication. 85 Requires the 'certChain' argument. Excludes the SRP arguments. 86 87 @type checker: L{tlslite.checker.Checker} 88 @param checker: Callable object called after handshaking to 89 evaluate the connection and raise an Exception if necessary. 90 91 @type settings: L{tlslite.handshakesettings.HandshakeSettings} 92 @param settings: Various settings which can be used to control 93 the ciphersuites, certificate types, and SSL/TLS versions 94 offered by the client. 95 96 @type ignoreAbruptClose: bool 97 @param ignoreAbruptClose: ignore the TLSAbruptCloseError on 98 unexpected hangup. 99 """ 100 101 # self._connection is new in python 2.7, since we're using it here, 102 # we'll add this ourselves too, just in case we're pre-2.7 103 self._connection = (None, None) 104 xmlrpclib.Transport.__init__(self, use_datetime) 105 self.ignoreAbruptClose = ignoreAbruptClose 106 ClientHelper.__init__(self, 107 username, password, 108 certChain, privateKey, 109 checker, 110 settings) 111 112 def make_connection(self, host): 113 # return an existing connection if possible. This allows 114 # HTTP/1.1 keep-alive. 115 if self._connection and host == self._connection[0]: 116 http = self._connection[1] 117 else: 118 # create a HTTPS connection object from a host descriptor 119 chost, extra_headers, x509 = self.get_host_info(host) 120 121 http = HTTPTLSConnection(chost, None, 122 username=self.username, password=self.password, 123 certChain=self.certChain, privateKey=self.privateKey, 124 checker=self.checker, 125 settings=self.settings, 126 ignoreAbruptClose=self.ignoreAbruptClose) 127 # store the host argument along with the connection object 128 self._connection = host, http 129 if not self.conn_class_is_http: 130 return http 131 http2 = httplib.HTTP() 132 http2._setup(http) 133 return http2 134