def atest_handle_ssl_validation_error(self): """ Tests handling untrusted SSL certificate issues. """ e = exceptions.CertificateVerificationException(CERT_FILENAME) code = self.exception_handler.handle_expired_client_cert(e) self.assertEqual(code, handler.CODE_APACHE_SERVER_EXCEPTION) self.assertEqual([TAG_FAILURE, TAG_PARAGRAPH], self.prompt.get_write_tags()) self.assertTrue("The server's SSL certificate is untrusted" in self.recorder.lines[0])
def request(self, method, url, body): """ Make the request against the Pulp server, returning a tuple of (status_code, respose_body). This method creates a new connection each time since HTTPSConnection has problems reusing a connection for multiple calls (as claimed by a prior comment in this module). :param method: The HTTP method to be used for the request (GET, POST, etc.) :type method: str :param url: The Pulp URL to make the request against :type url: str :param body: The body to pass with the request :type body: str :return: A 2-tuple of the status_code and response_body. status_code is the HTTP status code (200, 404, etc.). If the server's response is valid json, it will be parsed and response_body will be a dictionary. If not, it will be returned as a string. :rtype: tuple """ headers = dict(self.pulp_connection.headers ) # copy so we don't affect the calling method # Despite the confusing name, 'sslv23' configures m2crypto to use any available protocol in # the underlying openssl implementation. ssl_context = SSL.Context('sslv23') # This restricts the protocols we are willing to do by configuring m2 not to do SSLv2.0 or # SSLv3.0. EL 5 does not have support for TLS > v1.0, so we have to leave support for # TLSv1.0 enabled. ssl_context.set_options(m2.SSL_OP_NO_SSLv2 | m2.SSL_OP_NO_SSLv3) if self.pulp_connection.verify_ssl: ssl_context.set_verify(SSL.verify_peer, depth=100) # We need to stat the ca_path to see if it exists (error if it doesn't), and if so # whether it is a file or a directory. m2crypto has different directives depending on # which type it is. if os.path.isfile(self.pulp_connection.ca_path): ssl_context.load_verify_locations( cafile=self.pulp_connection.ca_path) elif os.path.isdir(self.pulp_connection.ca_path): ssl_context.load_verify_locations( capath=self.pulp_connection.ca_path) else: # If it's not a file and it's not a directory, it's not a valid setting raise exceptions.MissingCAPathException( self.pulp_connection.ca_path) ssl_context.set_session_timeout(self.pulp_connection.timeout) if self.pulp_connection.username and self.pulp_connection.password: raw = ':'.join( (self.pulp_connection.username, self.pulp_connection.password)) encoded = base64.encodestring(raw)[:-1] headers['Authorization'] = 'Basic ' + encoded elif self.pulp_connection.cert_filename: ssl_context.load_cert(self.pulp_connection.cert_filename) # oauth configuration. This block is only True if oauth is not None, so it won't run on RHEL # 5. if self.pulp_connection.oauth_key and self.pulp_connection.oauth_secret and oauth: oauth_consumer = oauth.Consumer(self.pulp_connection.oauth_key, self.pulp_connection.oauth_secret) oauth_request = oauth.Request.from_consumer_and_token( oauth_consumer, http_method=method, http_url='https://%s:%d%s' % (self.pulp_connection.host, self.pulp_connection.port, url)) oauth_request.sign_request(oauth.SignatureMethod_HMAC_SHA1(), oauth_consumer, None) oauth_header = oauth_request.to_header() # unicode header values causes m2crypto to do odd things. for k, v in oauth_header.items(): oauth_header[k] = encode_unicode(v) headers.update(oauth_header) headers['pulp-user'] = self.pulp_connection.oauth_user connection = httpslib.HTTPSConnection(self.pulp_connection.host, self.pulp_connection.port, ssl_context=ssl_context) try: # Request against the server connection.request(method, url, body=body, headers=headers) response = connection.getresponse() except SSL.SSLError, err: # Translate stale login certificate to an auth exception if 'sslv3 alert certificate expired' == str(err): raise exceptions.ClientCertificateExpiredException( self.pulp_connection.cert_filename) elif 'certificate verify failed' in str(err): raise exceptions.CertificateVerificationException() else: raise exceptions.ConnectionException(None, str(err), None)