Example #1
0
    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])
Example #2
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)