Ejemplo n.º 1
0
    def is_ssl_sasl_client_accepted(self, listener_port, tls_protocol):
        """
        Attempts to connect a proton client to the management address
        on the given listener_port using the specific tls_protocol provided.
        If connection was established and accepted, returns True and False otherwise.
        :param listener_port:
        :param tls_protocol:
        :return:
        """
        # Management address to connect using the given TLS protocol
        url = Url("amqps://0.0.0.0:%d/$management" % listener_port)
        # Preparing SSLDomain (client cert) and SASL authentication info
        domain = SSLDomain(SSLDomain.MODE_CLIENT)
        domain.set_credentials(self.ssl_file('client-certificate.pem'),
                               self.ssl_file('client-private-key.pem'),
                               'client-password')
        # Enforcing given TLS protocol
        cproton.pn_ssl_domain_set_protocols(domain._domain, tls_protocol)

        # Try opening the secure and authenticated connection
        try:
            connection = BlockingConnection(url,
                                            sasl_enabled=True,
                                            ssl_domain=domain,
                                            allowed_mechs='PLAIN',
                                            user='******',
                                            password='******')
        except proton.ConnectionException:
            return False

        # TLS version provided was accepted
        connection.close()
        return True
Ejemplo n.º 2
0
 def __init__(self, urls, certificate=None, private_key=None,
              trusted_certificates=None):
     self.urls = urls
     self.ssl_domain = SSLDomain(SSLDomain.MODE_CLIENT)
     self.ssl_domain.set_credentials(certificate, private_key, None)
     self.ssl_domain.set_trusted_ca_db(trusted_certificates)
     self.ssl_domain.set_peer_authentication(SSLDomain.VERIFY_PEER)
Ejemplo n.º 3
0
    def __init__(self, host="0.0.0.0", port=5672, router: Router = None):

        self._logger = logging.getLogger(self.__module__)
        self.port = port
        self.host = host
        self._router = router
        self._connection_options = {
            'sasl_enabled': False,
            'ssl_domain': None,
            'allow_insecure_mechs': True,
            'user': None,
            'password': None
        }

        if self._router:
            # Enable SASL when credentials provided
            self._connection_options[
                'sasl_enabled'] = self._router.has_ssl_keys(
                ) or self._router.has_credentials()

            # If SSL certificates provided, use them
            if self._router.has_ssl_keys():
                ssl_domain = SSLDomain(SSLDomain.MODE_CLIENT)
                ssl_domain.set_credentials(self._router.pem_file,
                                           self._router.key_file,
                                           self._router.key_password)
                self._connection_options['ssl_domain'] = ssl_domain

            # If User and Password provided
            if self._router.has_credentials():
                self._connection_options['user'] = self._router.user
                self._connection_options['password'] = self._router.password
Ejemplo n.º 4
0
    def is_ssl_sasl_client_accepted(self, listener_port, tls_protocol):
        """
        Attempts to connect a proton client to the management address
        on the given listener_port using the specific tls_protocol provided.
        If connection was established and accepted, returns True and False otherwise.
        :param listener_port:
        :param tls_protocol:
        :return:
        """
        # Management address to connect using the given TLS protocol
        url = Url("amqps://0.0.0.0:%d/$management" % listener_port)
        # Preparing SSLDomain (client cert) and SASL authentication info
        domain = SSLDomain(SSLDomain.MODE_CLIENT)
        domain.set_credentials(self.ssl_file('client-certificate.pem'),
                               self.ssl_file('client-private-key.pem'),
                               'client-password')
        # Enforcing given TLS protocol
        cproton.pn_ssl_domain_set_protocols(domain._domain, tls_protocol)

        # Try opening the secure and authenticated connection
        try:
            connection = BlockingConnection(url,
                                            sasl_enabled=True,
                                            ssl_domain=domain,
                                            allowed_mechs='PLAIN',
                                            user='******',
                                            password='******')
        except proton.ConnectionException:
            return False

        # TLS version provided was accepted
        connection.close()
        return True
Ejemplo n.º 5
0
def opts_ssl_domain(opts, mode=SSLDomain.MODE_CLIENT):
    """Return proton.SSLDomain from command line options or None if no SSL options specified.
    @param opts: Parsed optoins including connection_options()
    """

    certificate, key, trustfile, password, password_file, ssl_disable_peer_name_verify = opts.ssl_certificate,\
                                                                                         opts.ssl_key,\
                                                                                         opts.ssl_trustfile,\
                                                                                         opts.ssl_password,\
                                                                                         opts.ssl_password_file, \
                                                                                         opts.ssl_disable_peer_name_verify

    if not (certificate or trustfile):
        return None

    if password_file:
        password = get_password(password_file)

    domain = SSLDomain(mode)

    if trustfile:
        domain.set_trusted_ca_db(str(trustfile))
        if ssl_disable_peer_name_verify:
            domain.set_peer_authentication(SSLDomain.VERIFY_PEER,
                                           str(trustfile))
        else:
            domain.set_peer_authentication(SSLDomain.VERIFY_PEER_NAME,
                                           str(trustfile))

    if certificate:
        domain.set_credentials(str(certificate), str(key), str(password))
    return domain
Ejemplo n.º 6
0
def opts_ssl_domain(opts, mode=SSLDomain.MODE_CLIENT):
    """Return proton.SSLDomain from command line options or None if no SSL options specified.
    @param opts: Parsed optoins including connection_options()
    """

    certificate, key, trustfile, password, password_file, ssl_disable_peer_name_verify = opts.ssl_certificate,\
                                                                                         opts.ssl_key,\
                                                                                         opts.ssl_trustfile,\
                                                                                         opts.ssl_password,\
                                                                                         opts.ssl_password_file, \
                                                                                         opts.ssl_disable_peer_name_verify

    if not (certificate or trustfile):
        return None

    if password_file:
        password = get_password(password_file)

    domain = SSLDomain(mode)

    if trustfile:
        domain.set_trusted_ca_db(str(trustfile))
        if ssl_disable_peer_name_verify:
            domain.set_peer_authentication(SSLDomain.VERIFY_PEER, str(trustfile))
        else:
            domain.set_peer_authentication(SSLDomain.VERIFY_PEER_NAME, str(trustfile))

    if certificate:
        domain.set_credentials(str(certificate), str(key), str(password))
    return domain
Ejemplo n.º 7
0
class AuthService(MessagingHandler):
    def __init__(self, address):
        super(AuthService, self).__init__()
        self.address = address
        self.permissions = {}
        self.allow('admin', '*', ['send', 'recv'])
        self.allow('guest', 'foo', ['send', 'recv'])
        self.listener = None
        self.tmo = 0.1  # seconds
        self.stop_req = False
        self.acceptor = None
        self.ssl_domain = SSLDomain(SSLDomain.MODE_SERVER)
        self.ssl_domain.set_credentials(self.ssl_file('server-certificate.pem'),
                                        self.ssl_file('server-private-key.pem'),
                                        password="******")
        self.ssl_domain.set_trusted_ca_db(self.ssl_file('ca-certificate.pem'))

    def ssl_file(self, name):
        return os.path.join(system_test.DIR, 'ssl_certs', name)

    def allow(self, user, address, permissions):
        if not self.permissions.get(user):
            self.permissions[user] = {}
        self.permissions[user][address] = Array(UNDESCRIBED, Data.STRING, *permissions)

    def on_start(self, event):
        self.listener = event.container.listen(self.address, ssl_domain=self.ssl_domain)
        event.container.schedule(self.tmo, self)

    def stop(self):
        self.stop_req = True

    def on_connection_opening(self, event):
        if self.permissions.get(event.transport.user):
            event.connection.properties = {
                symbol('authenticated-identity'): "%s" % event.transport.user,
                symbol('address-authz'): self.permissions[event.transport.user]
            }
        else:
            event.connection.properties = {
                symbol('authenticated-identity'): "%s" % event.transport.user,
                symbol('address-authz'): {}
            }

    def on_timer_task(self, event):
        if self.stop_req:
            if self.listener:
                self.listener.close()
            else:
                sys.exit(0)
        else:
            event.reactor.schedule(self.tmo, self)
    def run(self):
        try:
            ssl = SSLDomain(SSLDomain.MODE_CLIENT)
            ssl.set_credentials(str(self.options.accountPublicKey),
                                str(self.options.accountPrivateKey), str(""))
            ssl.set_trusted_ca_db(str(self.options.brokerPublicKey))
            ssl.set_peer_authentication(SSLDomain.VERIFY_PEER_NAME,
                                        trusted_CAs=str(
                                            self.options.brokerPublicKey))

            connection = BlockingConnection(self.address,
                                            ssl_domain=ssl,
                                            heartbeat=60000)
            receiver = connection.create_receiver(self.broadcast_address,
                                                  credit=self.capacity)

            while True:
                received_message = None

                try:
                    received_message = receiver.receive(
                        timeout=self.options.timeout)
                except Timeout, e:
                    print("-I- No message received for ", self.options.timeout,
                          " seconds")
                    break

                self.message_counter += 1
                print("-I- Received broadcast message: " +
                      received_message.body)
                receiver.accept()

            print("-I- " + str(self.message_counter) + " messages received")

            connection.close()
Ejemplo n.º 9
0
    def __init__(self, router_host, router_port, cert_dir):
        self.router_host = router_host
        self.router_port = router_port
        self.cert_dir = cert_dir
        ssl_domain = None
        allowed_mechs = []
        sasl_enabled = False

        if self.cert_dir != None:
            ssl_domain = SSLDomain(SSLDomain.MODE_CLIENT)
            ssl_domain.set_trusted_ca_db(
                str(os.path.join(self.cert_dir, 'ca.crt')))
            ssl_domain.set_credentials(
                str(os.path.join(self.cert_dir, "tls.crt")),
                str(os.path.join(self.cert_dir, "tls.key")), None)
            ssl_domain.set_peer_authentication(SSLDomain.VERIFY_PEER)
            allowed_mechs = str("EXTERNAL")
            sasl_enabled = True

        self.client = SyncRequestResponse(
            BlockingConnection("amqps://" + self.router_host + ":" +
                               str(self.router_port),
                               30,
                               None,
                               ssl_domain,
                               allowed_mechs=allowed_mechs,
                               sasl_enabled=sasl_enabled), "$management")
Ejemplo n.º 10
0
 def __init__(self, address):
     super(AuthService, self).__init__()
     self.address = address
     self.permissions = {}
     self.allow('admin', '*', ['send', 'recv'])
     self.allow('guest', 'foo', ['send', 'recv'])
     self.listener = None
     self.tmo = 0.1  # seconds
     self.stop_req = False
     self.acceptor = None
     self.ssl_domain = SSLDomain(SSLDomain.MODE_SERVER)
     self.ssl_domain.set_credentials(self.ssl_file('server-certificate.pem'),
                                     self.ssl_file('server-private-key.pem'),
                                     password="******")
     self.ssl_domain.set_trusted_ca_db(self.ssl_file('ca-certificate.pem'))
Ejemplo n.º 11
0
    def is_proto_allowed(self, listener_port, tls_protocol):
        """
        Opens a simple proton client connection to the provided TCP port using
        a specific TLS protocol version and returns True in case connection
        was established and accepted or False otherwise.
        :param listener_port: TCP port number
        :param tls_protocol: TLSv1, TLSv1.1 or TLSv1.2 (string)
        :return:
        """
        # Management address to connect using the given TLS protocol
        url = Url("amqps://0.0.0.0:%d/$management" % listener_port)
        # Preparing SSLDomain (client cert) and SASL authentication info
        domain = SSLDomain(SSLDomain.MODE_CLIENT)
        # Enforcing given TLS protocol
        cproton.pn_ssl_domain_set_protocols(domain._domain, tls_protocol)

        # Try opening the secure and authenticated connection
        try:
            connection = BlockingConnection(url, sasl_enabled=False, ssl_domain=domain, timeout=self.TIMEOUT)
        except proton.Timeout:
            return False
        except proton.ConnectionException:
            return False

        # TLS version provided was accepted
        connection.close()
        return True
Ejemplo n.º 12
0
 def __init__(self, server, address, count, peer_hostname):
     super(Recv, self).__init__()
     self.server = server
     self.address = address
     self.expected = count
     self.received = 0
     self.peer_hostname = peer_hostname
     self.ssl_domain = SSLDomain(SSLDomain.MODE_CLIENT)
    def run(self):
        try:
            ssl = SSLDomain(SSLDomain.MODE_CLIENT)
            ssl.set_credentials(str(self.options.accountPublicKey), str(self.options.accountPrivateKey), str(""))
            ssl.set_trusted_ca_db(str(self.options.brokerPublicKey))
            ssl.set_peer_authentication(SSLDomain.VERIFY_PEER_NAME, trusted_CAs=str(self.options.brokerPublicKey))

            connection = BlockingConnection(self.address, ssl_domain=ssl, heartbeat=60000)
            receiver = connection.create_receiver(self.broadcast_address, credit=self.capacity)

            while True:
                received_message = None

                try:
                    received_message = receiver.receive(timeout=self.options.timeout)
                except Timeout, e:
                    print("-I- No message received for ", self.options.timeout, " seconds")
                    break

                self.message_counter += 1
                print("-I- Received broadcast message: " + received_message.body)
                receiver.accept()

            print("-I- " + str(self.message_counter) + " messages received")

            connection.close()
Ejemplo n.º 14
0
def isSSLPresent():
    """ True if a suitable SSL library is available.
    """
    try:
        xxx = SSLDomain(SSLDomain.MODE_CLIENT)
        return True
    except SSLUnavailable, e:
        # SSL libraries not installed
        return False
Ejemplo n.º 15
0
    def __init__(self, router_host, router_port, cert_dir):
        self.router_host = router_host
        self.router_port = router_port
        self.cert_dir = cert_dir
        self.ssl_domain = None
        self.allowed_mechs = []
        self.sasl_enabled = False

        if self.cert_dir != None:
            self.ssl_domain = SSLDomain(SSLDomain.MODE_CLIENT)
            self.ssl_domain.set_trusted_ca_db(
                str(os.path.join(self.cert_dir, 'ca.crt')))
            self.ssl_domain.set_credentials(
                str(os.path.join(self.cert_dir, "tls.crt")),
                str(os.path.join(self.cert_dir, "tls.key")), None)
            self.ssl_domain.set_peer_authentication(SSLDomain.VERIFY_PEER)
            self.allowed_mechs = str("EXTERNAL")
            self.sasl_enabled = True
Ejemplo n.º 16
0
 def __init__(self, server, address, messages, peer_hostname):
     super(Send, self).__init__()
     self.server = server
     self.address = address
     self.sent = 0
     self.confirmed = 0
     self.total = messages
     self.peer_hostname = peer_hostname
     self.ssl_domain = SSLDomain(SSLDomain.MODE_CLIENT)
Ejemplo n.º 17
0
class SSLConfig(object):
    def __init__(self):
        self.client = SSLDomain(SSLDomain.MODE_CLIENT)
        self.server = SSLDomain(SSLDomain.MODE_SERVER)

    def set_credentials(self, cert_file, key_file, password):
        self.client.set_credentials(cert_file, key_file, password)
        self.server.set_credentials(cert_file, key_file, password)

    def set_trusted_ca_db(self, certificate_db):
        self.client.set_trusted_ca_db(certificate_db)
        self.server.set_trusted_ca_db(certificate_db)
Ejemplo n.º 18
0
def opts_ssl_domain(opts, mode=SSLDomain.MODE_CLIENT):
    """Return proton.SSLDomain from command line options or None if no SSL options specified.
    @param opts: Parsed optoins including connection_options()
    """
    certificate, key, trustfile, password = opts.ssl_certificate, opts.ssl_key, opts.ssl_trustfile, opts.ssl_password
    if not (certificate or trustfile): return None
    domain = SSLDomain(mode)
    if trustfile:
        domain.set_trusted_ca_db(trustfile)
        domain.set_peer_authentication(SSLDomain.VERIFY_PEER, trustfile)
    if certificate:
        domain.set_credentials(certificate, key, password)
    return domain
    def on_start(self, event):
        self.container = event.container

        ssl = SSLDomain(SSLDomain.MODE_CLIENT)
        ssl.set_credentials(str(self.options.accountPublicKey), str(self.options.accountPrivateKey), str(""))
        ssl.set_trusted_ca_db(str(self.options.brokerPublicKey))
        ssl.set_peer_authentication(SSLDomain.VERIFY_PEER_NAME, trusted_CAs=str(self.options.brokerPublicKey))

        conn = event.container.connect(self.address, ssl_domain=ssl, heartbeat=60000, allowed_mechs=str("EXTERNAL"))
        event.container.create_receiver(conn, self.broadcast_address)
Ejemplo n.º 20
0
 def on_start(self, event):
     ssl_domain = SSLDomain(mode=SSLDomain.MODE_CLIENT)
     ssl_domain.set_trusted_ca_db(env.certificate_db)
     ssl_domain.set_credentials(env.cert_file, env.key_file, env.password)
     conn = event.container.connect(urls=self.urls, ssl_domain=ssl_domain) #, user=env.username, password=env.password)
     # at-least-once delivery semantics for message delivery
     event.container.create_sender(conn, self.address, options=AtLeastOnce())
     self.start = time.time()
Ejemplo n.º 21
0
    def on_start(self, event):
        self.container = event.container

        ssl = SSLDomain(SSLDomain.MODE_CLIENT)
        ssl.set_credentials(str(self.options.accountPublicKey),
                            str(self.options.accountPrivateKey), str(""))
        ssl.set_trusted_ca_db(str(self.options.brokerPublicKey))
        ssl.set_peer_authentication(SSLDomain.VERIFY_PEER_NAME,
                                    trusted_CAs=str(
                                        self.options.brokerPublicKey))

        conn = event.container.connect(self.address,
                                       ssl_domain=ssl,
                                       heartbeat=60000,
                                       allowed_mechs=str("EXTERNAL"))
        event.container.create_receiver(conn, self.broadcast_address)
Ejemplo n.º 22
0
 def on_start(self, event):
     ssl_domain = SSLDomain(mode=SSLDomain.MODE_CLIENT)
     ssl_domain.set_trusted_ca_db(env.certificate_db)
     ssl_domain.set_credentials(env.cert_file, env.key_file, env.password)
     conn = event.container.connect(
         urls=self.urls, ssl_domain=ssl_domain
     )  #, user=env.username, password=env.password)
     event.container.create_receiver(conn, self.address)
     self.start = time.time()
Ejemplo n.º 23
0
def opts_ssl_domain(opts, mode=SSLDomain.MODE_CLIENT):
    """Return proton.SSLDomain from command line options or None if no SSL options specified.
    @param opts: Parsed optoins including connection_options()
    """
    certificate, key, trustfile, password = opts.ssl_certificate, opts.ssl_key, opts.ssl_trustfile, opts.ssl_password
    if not (certificate or trustfile): return None
    domain = SSLDomain(mode)
    if trustfile:
        domain.set_trusted_ca_db(trustfile)
        domain.set_peer_authentication(SSLDomain.VERIFY_PEER, trustfile)
    if certificate:
        domain.set_credentials(certificate, key, password)
    return domain
Ejemplo n.º 24
0
 def on_start(self, event):
     # Write the UMB cert and key out to disk but immediately delete
     # them once the connection has been established. There may be a
     # better way to do this if we can be assured of a secure directory.
     temp_dir = tempfile.mkdtemp()
     mktemp = functools.partial(tempfile.NamedTemporaryFile,
                                delete=False,
                                dir=temp_dir)
     
     try:
         temp_cert = mktemp()
         temp_key = mktemp()
         temp_cert.write(self.certificate)
         temp_key.write(self.key)
         temp_cert.close()
         temp_key.close()
         
         domain = SSLDomain(SSLDomain.MODE_CLIENT)
         domain.set_credentials(temp_cert.name, temp_key.name, b'')
         conn = event.container.connect(self.server, ssl_domain=domain)
     finally:
         shutil.rmtree(temp_dir)
             
     event.container.create_sender(conn, "topic://" + self.topic)
Ejemplo n.º 25
0
 def on_start(self, event):
     self.log.debug('Container starting')
     event.container.connected = False
     if self.conf.has_option('broker', 'cert') and self.conf.has_option('broker', 'cacert'):
         ssl = SSLDomain(SSLDomain.MODE_CLIENT)
         cert = self.conf.get('broker', 'cert')
         ssl.set_credentials(cert, cert, None)
         ssl.set_trusted_ca_db(self.conf.get('broker', 'cacert'))
         ssl.set_peer_authentication(SSLDomain.VERIFY_PEER)
     else:
         ssl = None
     self.log.debug('connecting to %s', self.url)
     event.container.connect(url=self.url, reconnect=False, ssl_domain=ssl)
     connect_timeout = self.conf.getint('broker', 'connect_timeout')
     self.connect_task = event.container.schedule(connect_timeout, self)
     send_timeout = self.conf.getint('broker', 'send_timeout')
     self.timeout_task = event.container.schedule(send_timeout, self)
Ejemplo n.º 26
0
 def on_start(self, event):
     log.debug('Container starting')
     event.container.connected = False
     event.container.error_msgs = []
     if 'cert' in self.conf and 'key' in self.conf and 'cacert' in self.conf:
         ssl = SSLDomain(SSLDomain.MODE_CLIENT)
         ssl.set_credentials(self.conf['cert'], self.conf['key'], None)
         ssl.set_trusted_ca_db(self.conf['cacert'])
         ssl.set_peer_authentication(SSLDomain.VERIFY_PEER)
     else:
         ssl = None
     log.debug('connecting to %s', self.url)
     event.container.connect(url=self.url, reconnect=False, ssl_domain=ssl)
     connect_timeout = self.conf['connect_timeout']
     self.connect_task = event.container.schedule(connect_timeout, self)
     send_timeout = self.conf['send_timeout']
     self.timeout_task = event.container.schedule(send_timeout, self)
Ejemplo n.º 27
0
    def create_ssl_domain(self, ssl_options_dict, mode=SSLDomain.MODE_CLIENT):
        """Return proton.SSLDomain from command line options or None if no SSL options specified.
            @param opts: Parsed optoins including connection_options()
        """
        certificate, key, trustfile, password = ssl_options_dict.get('ssl-certificate'), \
            ssl_options_dict.get('ssl-key'), \
            ssl_options_dict.get('ssl-trustfile'), \
            ssl_options_dict.get('ssl-password')

        if not (certificate or trustfile):
            return None
        domain = SSLDomain(mode)
        if trustfile:
            domain.set_trusted_ca_db(str(trustfile))
            domain.set_peer_authentication(SSLDomain.VERIFY_PEER, str(trustfile))
        if certificate:
            domain.set_credentials(str(certificate), str(key), str(password))

        return domain
Ejemplo n.º 28
0
 def on_start(self, event):
     self.log.debug('Container starting')
     event.container.connected = False
     if self.conf.has_option('broker', 'cert') and self.conf.has_option('broker', 'cacert'):
         ssl = SSLDomain(SSLDomain.MODE_CLIENT)
         cert = self.conf.get('broker', 'cert')
         ssl.set_credentials(cert, cert, None)
         ssl.set_trusted_ca_db(self.conf.get('broker', 'cacert'))
         ssl.set_peer_authentication(SSLDomain.VERIFY_PEER)
     else:
         ssl = None
     self.log.debug('connecting to %s', self.url)
     event.container.connect(url=self.url, reconnect=False, ssl_domain=ssl)
     connect_timeout = self.conf.getint('broker', 'connect_timeout')
     self.connect_task = event.container.schedule(connect_timeout, self)
     send_timeout = self.conf.getint('broker', 'send_timeout')
     self.timeout_task = event.container.schedule(send_timeout, self)
Ejemplo n.º 29
0
    def create_ssl_domain(self, ssl_options_dict, mode=SSLDomain.MODE_CLIENT):
        """Return proton.SSLDomain from command line options or None if no SSL options specified.
            @param opts: Parsed optoins including connection_options()
        """
        certificate, key, trustfile, password = ssl_options_dict.get('ssl-certificate'), \
                                                ssl_options_dict.get('ssl-key'), \
                                                ssl_options_dict.get('ssl-trustfile'), \
                                                ssl_options_dict.get('ssl-password')

        if not (certificate or trustfile):
            return None
        domain = SSLDomain(mode)
        if trustfile:
            domain.set_trusted_ca_db(str(trustfile))
            domain.set_peer_authentication(SSLDomain.VERIFY_PEER, str(trustfile))
        if certificate:
            domain.set_credentials(str(certificate), str(key), str(password))

        return domain
    def run(self):
        try:
            ssl = SSLDomain(SSLDomain.MODE_CLIENT)
            ssl.set_credentials(str(self.options.accountPublicKey), str(self.options.accountPrivateKey), str(""))
            ssl.set_trusted_ca_db(str(self.options.brokerPublicKey))
            ssl.set_peer_authentication(SSLDomain.VERIFY_PEER_NAME, trusted_CAs=str(self.options.brokerPublicKey))

            connection = BlockingConnection(self.address, ssl_domain=ssl, heartbeat=60000)
            receiver = connection.create_receiver(self.response_address)
            sender = connection.create_sender(self.request_address)

            message = Message(body="<FIXML>...</FIXML>", reply_to=self.reply_adress)
            print("-I- Sending request message: " + message.body)
            sender.send(message);

            try:
                received_message = receiver.receive(timeout=self.options.timeout)
                print("-I- Received response message: " + received_message.body)
                self.message_counter += 1
                receiver.accept()
            except Timeout, e:
                print("-I- No message received for ", self.options.timeout, " seconds")

            connection.close()
Ejemplo n.º 31
0
 def ssl_domain(connector):
     """
     Get the ssl domain using the broker settings.
     :param connector: A broker.
     :type connector: Connector
     :return: The populated domain.
     :rtype: SSLDomain
     :raise: SSLException
     :raise: ValueError
     """
     domain = None
     if connector.use_ssl():
         connector.ssl.validate()
         domain = SSLDomain(SSLDomain.MODE_CLIENT)
         domain.set_trusted_ca_db(connector.ssl.ca_certificate)
         domain.set_credentials(
             connector.ssl.client_certificate, connector.ssl.client_key
             or connector.ssl.client_certificate, None)
         if connector.ssl.host_validation:
             mode = SSLDomain.VERIFY_PEER_NAME
         else:
             mode = SSLDomain.VERIFY_PEER
         domain.set_peer_authentication(mode)
     return domain
Ejemplo n.º 32
0
 def ssl_domain(connector):
     """
     Get the ssl domain using the broker settings.
     :param connector: A broker.
     :type connector: Connector
     :return: The populated domain.
     :rtype: SSLDomain
     :raise: SSLException
     :raise: ValueError
     """
     domain = None
     if connector.use_ssl():
         connector.ssl.validate()
         domain = SSLDomain(SSLDomain.MODE_CLIENT)
         domain.set_trusted_ca_db(connector.ssl.ca_certificate)
         domain.set_credentials(
             connector.ssl.client_certificate,
             connector.ssl.client_key or connector.ssl.client_certificate, None)
         if connector.ssl.host_validation:
             mode = SSLDomain.VERIFY_PEER_NAME
         else:
             mode = SSLDomain.VERIFY_PEER
         domain.set_peer_authentication(mode)
     return domain
Ejemplo n.º 33
0
class AMQConsumer(object):

    def __init__(self, urls, certificate=None, private_key=None,
                 trusted_certificates=None):
        self.urls = urls
        self.ssl_domain = SSLDomain(SSLDomain.MODE_CLIENT)
        self.ssl_domain.set_credentials(certificate, private_key, None)
        self.ssl_domain.set_trusted_ca_db(trusted_certificates)
        self.ssl_domain.set_peer_authentication(SSLDomain.VERIFY_PEER)

    def consume(self, address, callback,
                data=None, selector=None, auto_accept=True,
                subscription_name=None):
        """Start to consume messages

        :param str address: refer to ``ReceiverHandler.__init__``.
        :param callable callback: refer to ``ReceiverHandler.__init__``.
        :param data: refer to ``ReceiverHandler.__init__``.
        :param str selector: refer to ``ReceiverHandler.__init__``.
        :param bool auto_accept: whether to accept message automatically.
            Defaults to ``True``, that is to use default behaivor of
            ``proton.MessagingHandler``. Otherwise, received message will be
            accepted according to return value from ``callback``. For
            detailed information, refer to ``ReceiverHandler.on_message``.
        :param str subscription_name: name to use to identify the durable
            subscription. It will also be used as the client ID. If it is
            None, the subscription will be non-durable, and the client ID
            will be random.
        :return: the return value of ``callback`` once a message is handled.
            Or, the value returned when the last time ``callback`` is called.
        """
        handler = ReceiverHandler(self.urls, address,
                                  callback, data=data,
                                  selector=selector,
                                  ssl_domain=self.ssl_domain,
                                  auto_accept=auto_accept,
                                  subscription_name=subscription_name)
        Container(handler).run()
        return handler.result
Ejemplo n.º 34
0
class RouterCollector(object):
    def __init__(self, router_host, router_port, cert_dir):
        self.router_host = router_host
        self.router_port = router_port
        self.cert_dir = cert_dir
        self.ssl_domain = None
        self.allowed_mechs = []
        self.sasl_enabled = False

        if self.cert_dir != None:
            self.ssl_domain = SSLDomain(SSLDomain.MODE_CLIENT)
            self.ssl_domain.set_trusted_ca_db(
                str(os.path.join(self.cert_dir, 'ca.crt')))
            self.ssl_domain.set_credentials(
                str(os.path.join(self.cert_dir, "tls.crt")),
                str(os.path.join(self.cert_dir, "tls.key")), None)
            self.ssl_domain.set_peer_authentication(SSLDomain.VERIFY_PEER)
            self.allowed_mechs = str("EXTERNAL")
            self.sasl_enabled = True

    def create_collector_map(self):
        metrics = [
            MetricCollector('connectionCount',
                            'Number of connections to router', ['container']),
            MetricCollector('connectionCount',
                            'Total number of connections to router',
                            ['routerId'],
                            id="totalConnectionCount"),
            MetricCollector('linkCount', 'Number of links to router',
                            ['address']),
            MetricCollector('linkCount',
                            'Number of consumers to router', ['address'],
                            id="consumerCount",
                            filter={"linkDir": "out"}),
            MetricCollector('linkCount',
                            'Number of producers to router', ['address'],
                            id="producerCount",
                            filter={"linkDir": "in"}),
            MetricCollector('linkCount',
                            'Total number of links to router', ['routerId'],
                            id="totalLinkCount"),
            MetricCollector('addrCount',
                            'Number of addresses defined in router',
                            ['routerId']),
            MetricCollector('autoLinkCount',
                            'Number of auto links defined in router',
                            ['routerId']),
            MetricCollector('linkRouteCount',
                            'Number of link routers defined in router',
                            ['routerId']),
            MetricCollector('unsettledCount', 'Number of unsettled messages',
                            ['address']),
            MetricCollector('deliveryCount', 'Number of delivered messages',
                            ['address'], "COUNTER"),
            MetricCollector('releasedCount', 'Number of released messages',
                            ['address'], "COUNTER"),
            MetricCollector('rejectedCount', 'Number of rejected messages',
                            ['address'], "COUNTER"),
            MetricCollector('acceptedCount', 'Number of accepted messages',
                            ['address'], "COUNTER"),
            MetricCollector('undeliveredCount',
                            'Number of undelivered messages', ['address']),
            MetricCollector('capacity', 'Capacity of link', ['address'])
        ]
        m = {}
        for metric in metrics:
            m[metric.id] = metric
        return m

    def create_entity_map(self, collector_map):
        return {
            self.get_router: [
                collector_map['totalConnectionCount'],
                collector_map['totalLinkCount'], collector_map['addrCount'],
                collector_map['autoLinkCount'], collector_map['linkRouteCount']
            ],
            self.get_connections: [collector_map['connectionCount']],
            self.get_links: [
                collector_map['linkCount'], collector_map['unsettledCount'],
                collector_map['deliveryCount'], collector_map['releasedCount'],
                collector_map['rejectedCount'], collector_map['acceptedCount'],
                collector_map['undeliveredCount'], collector_map['capacity'],
                collector_map['consumerCount'], collector_map['producerCount']
            ]
        }

    def get_router(self, client):
        return self.collect_metric('org.apache.qpid.dispatch.router', client)

    def get_links(self, client):
        links = self.collect_metric('org.apache.qpid.dispatch.router.link',
                                    client)
        if links == None:
            return links

        connections = self.get_connections(client)
        if connections == None:
            return connections

        links.add_field_from("address", "owningAddr", clean_address)
        links.add_field("linkCount", 1)
        links.add_field_from(
            "container", "connectionId",
            lambda connection_id: get_container_from_connections(
                connection_id, connections))

        return links

    def get_connections(self, client):
        response = self.collect_metric('org.apache.qpid.dispatch.connection',
                                       client)
        if response == None:
            return response

        response.add_field("connectionCount", 1)
        return response

    def collect(self):
        collector_map = self.create_collector_map()
        fetcher_map = self.create_entity_map(collector_map)
        connection = None
        print("Collecting metrics")

        try:
            connection = BlockingConnection("amqps://" + self.router_host +
                                            ":" + str(self.router_port),
                                            30,
                                            None,
                                            self.ssl_domain,
                                            allowed_mechs=self.allowed_mechs,
                                            sasl_enabled=self.sasl_enabled,
                                            container_id="router-metrics")
            client = SyncRequestResponse(connection, "$management")
            for fetcher in fetcher_map:
                response = fetcher(client)
                if response != None:
                    for collector in fetcher_map[fetcher]:
                        for entity in response.get_results():
                            if response.contains(entity, collector.filter):
                                labels = []
                                for l in collector.labels:
                                    label_idx = response.get_index(l)
                                    if label_idx != None and entity[
                                            label_idx] != None:
                                        labels.append(entity[label_idx])
                                    else:
                                        labels.append("")
                                value = entity[response.get_index(
                                    collector.name)]
                                collector.add(labels, int(value))
        finally:
            if connection != None:
                connection.close()

        for collector in collector_map.itervalues():
            yield collector.metric()

    def collect_metric(self, entityType, client):
        result = None
        try:
            properties = {}
            properties["entityType"] = entityType
            properties["operation"] = "QUERY"
            properties["name"] = "self"
            message = Message(body=None, properties=properties)

            response = client.call(message)
            if response != None:
                result = RouterResponse(response)
        except NameError as e:
            print("Error querying router for metrics: %s" % e)
        return result
Ejemplo n.º 35
0
 def __init__(self):
     self.client = SSLDomain(SSLDomain.MODE_CLIENT)
     self.server = SSLDomain(SSLDomain.MODE_SERVER)
Ejemplo n.º 36
0
class RouterTestSslClient(RouterTestSslBase):
    """
    Starts a router with multiple listeners, all of them using an sslProfile.
    Then it runs multiple tests to validate that only the allowed protocol versions
    are being accepted through the related listener.
    """
    # Listener ports for each TLS protocol definition
    PORT_TLS1 = 0
    PORT_TLS11 = 0
    PORT_TLS12 = 0
    PORT_TLS13 = 0
    PORT_TLS1_TLS11 = 0
    PORT_TLS1_TLS12 = 0
    PORT_TLS11_TLS12 = 0
    PORT_TLS_ALL = 0
    PORT_TLS_SASL = 0
    PORT_SSL3 = 0
    TIMEOUT = 3

    # If using OpenSSL 1.1 or greater, TLSv1.2 is always being allowed
    OPENSSL_OUT_VER = None
    try:
        OPENSSL_VER_1_1_GT = ssl.OPENSSL_VERSION_INFO[:2] >= (1, 1)
    except AttributeError:
        OPENSSL_VER_1_1_GT = False

    # If still False, try getting it from "openssl version" (command output)
    # The version from ssl.OPENSSL_VERSION_INFO reflects OpenSSL version in which
    # Python was compiled with, not the one installed in the system.
    if not OPENSSL_VER_1_1_GT:
        print("Python libraries SSL Version < 1.1")
        try:
            p = Popen(['openssl', 'version'],
                      stdout=PIPE,
                      universal_newlines=True)
            openssl_out = p.communicate()[0]
            m = re.search(r'[0-9]+\.[0-9]+\.[0-9]+', openssl_out)
            OPENSSL_OUT_VER = m.group(0)
            OPENSSL_VER_1_1_GT = StrictVersion(
                OPENSSL_OUT_VER) >= StrictVersion('1.1')
            print("OpenSSL Version found = %s" % OPENSSL_OUT_VER)
        except:
            pass

    # Following variables define TLS versions allowed by openssl
    OPENSSL_MIN_VER = 0
    OPENSSL_MAX_VER = 9999
    OPENSSL_ALLOW_TLSV1 = True
    OPENSSL_ALLOW_TLSV1_1 = True
    OPENSSL_ALLOW_TLSV1_2 = True
    OPENSSL_ALLOW_TLSV1_3 = False

    # Test if OpenSSL has TLSv1_3
    OPENSSL_HAS_TLSV1_3 = False
    if OPENSSL_VER_1_1_GT:
        try:
            ssl.TLSVersion.TLSv1_3
            OPENSSL_HAS_TLSV1_3 = True
        except:
            pass

    # Test if Proton supports TLSv1_3
    try:
        dummydomain = SSLDomain(SSLDomain.MODE_CLIENT)
        PROTON_HAS_TLSV1_3 = cproton.PN_OK == cproton.pn_ssl_domain_set_protocols(
            dummydomain._domain, "TLSv1.3")
        print("TLSV1_3? Proton has: %s, OpenSSL has: %s" %
              (PROTON_HAS_TLSV1_3, OPENSSL_HAS_TLSV1_3))
    except SSLUnavailable:
        PROTON_HAS_TLSV1_3 = False

    # When using OpenSSL >= 1.1 and python >= 3.7, we can retrieve OpenSSL min and max protocols
    if OPENSSL_VER_1_1_GT:
        if sys.version_info >= (3, 7):
            if OPENSSL_HAS_TLSV1_3 and not PROTON_HAS_TLSV1_3:
                # If OpenSSL has 1.3 but proton won't let us turn it on and off then
                # this test fails because v1.3 runs unexpectedly.
                RouterTestSslBase.DISABLE_SSL_TESTING = True
                RouterTestSslBase.DISABLE_REASON = "Proton version does not support TLSv1.3 but OpenSSL does"
            else:
                OPENSSL_CTX = ssl.create_default_context()
                OPENSSL_MIN_VER = OPENSSL_CTX.minimum_version
                OPENSSL_MAX_VER = OPENSSL_CTX.maximum_version if OPENSSL_CTX.maximum_version > 0 else 9999
                OPENSSL_ALLOW_TLSV1 = OPENSSL_MIN_VER <= ssl.TLSVersion.TLSv1 <= OPENSSL_MAX_VER
                OPENSSL_ALLOW_TLSV1_1 = OPENSSL_MIN_VER <= ssl.TLSVersion.TLSv1_1 <= OPENSSL_MAX_VER
                OPENSSL_ALLOW_TLSV1_2 = OPENSSL_MIN_VER <= ssl.TLSVersion.TLSv1_2 <= OPENSSL_MAX_VER
                OPENSSL_ALLOW_TLSV1_3 = OPENSSL_HAS_TLSV1_3 and PROTON_HAS_TLSV1_3 \
                                    and OPENSSL_MIN_VER <= ssl.TLSVersion.TLSv1_3 <= OPENSSL_MAX_VER
        else:
            # At this point we are not able to precisely determine what are the minimum and maximum
            # TLS versions allowed in the system, so tests will be disabled
            RouterTestSslBase.DISABLE_SSL_TESTING = True
            RouterTestSslBase.DISABLE_REASON = "OpenSSL >= 1.1 but Python < 3.7 - Unable to determine MinProtocol"
    else:
        if OPENSSL_HAS_TLSV1_3 and not PROTON_HAS_TLSV1_3:
            # If OpenSSL has 1.3 but proton won't let us turn it on and off then
            # this test fails because v1.3 runs unexpectedly.
            RouterTestSslBase.DISABLE_SSL_TESTING = True
            RouterTestSslBase.DISABLE_REASON = "Proton version does not support TLSv1.3 but OpenSSL does"

    @classmethod
    def setUpClass(cls):
        """
        Prepares a single router with multiple listeners, each one associated with a particular
        sslProfile and each sslProfile has its own specific set of allowed protocols.
        """
        super(RouterTestSslClient, cls).setUpClass()

        cls.routers = []

        if SASL.extended():
            router = ('router', {
                'id': 'QDR.A',
                'mode': 'interior',
                'saslConfigName': 'tests-mech-PLAIN',
                'saslConfigDir': os.getcwd()
            })

            # Generate authentication DB
            super(RouterTestSslClient, cls).create_sasl_files()
        else:
            router = ('router', {'id': 'QDR.A', 'mode': 'interior'})

        # Saving listener ports for each TLS definition
        cls.PORT_TLS1 = cls.tester.get_port()
        cls.PORT_TLS11 = cls.tester.get_port()
        cls.PORT_TLS12 = cls.tester.get_port()
        cls.PORT_TLS13 = cls.tester.get_port()
        cls.PORT_TLS1_TLS11 = cls.tester.get_port()
        cls.PORT_TLS1_TLS12 = cls.tester.get_port()
        cls.PORT_TLS11_TLS12 = cls.tester.get_port()
        cls.PORT_TLS_ALL = cls.tester.get_port()
        cls.PORT_TLS_SASL = cls.tester.get_port()
        cls.PORT_SSL3 = cls.tester.get_port()

        conf = [
            router,
            # TLSv1 only
            ('listener', {
                'host': '0.0.0.0',
                'role': 'normal',
                'port': cls.PORT_TLS1,
                'authenticatePeer': 'no',
                'sslProfile': 'ssl-profile-tls1'
            }),
            # TLSv1.1 only
            ('listener', {
                'host': '0.0.0.0',
                'role': 'normal',
                'port': cls.PORT_TLS11,
                'authenticatePeer': 'no',
                'sslProfile': 'ssl-profile-tls11'
            }),
            # TLSv1.2 only
            ('listener', {
                'host': '0.0.0.0',
                'role': 'normal',
                'port': cls.PORT_TLS12,
                'authenticatePeer': 'no',
                'sslProfile': 'ssl-profile-tls12'
            }),
            # TLSv1 and TLSv1.1 only
            ('listener', {
                'host': '0.0.0.0',
                'role': 'normal',
                'port': cls.PORT_TLS1_TLS11,
                'authenticatePeer': 'no',
                'sslProfile': 'ssl-profile-tls1-tls11'
            }),
            # TLSv1 and TLSv1.2 only
            ('listener', {
                'host': '0.0.0.0',
                'role': 'normal',
                'port': cls.PORT_TLS1_TLS12,
                'authenticatePeer': 'no',
                'sslProfile': 'ssl-profile-tls1-tls12'
            }),
            # TLSv1.1 and TLSv1.2 only
            ('listener', {
                'host': '0.0.0.0',
                'role': 'normal',
                'port': cls.PORT_TLS11_TLS12,
                'authenticatePeer': 'no',
                'sslProfile': 'ssl-profile-tls11-tls12'
            }),
            # All TLS versions
            ('listener', {
                'host': '0.0.0.0',
                'role': 'normal',
                'port': cls.PORT_TLS_ALL,
                'authenticatePeer': 'no',
                'sslProfile': 'ssl-profile-tls-all'
            }),
            # Invalid protocol version
            ('listener', {
                'host': '0.0.0.0',
                'role': 'normal',
                'port': cls.PORT_SSL3,
                'authenticatePeer': 'no',
                'sslProfile': 'ssl-profile-ssl3'
            })
        ]

        # Adding SASL listener only when SASL is available
        if SASL.extended():
            conf += [
                # TLS 1 and 1.2 with SASL PLAIN authentication for proton client validation
                ('listener', {
                    'host': '0.0.0.0',
                    'role': 'normal',
                    'port': cls.PORT_TLS_SASL,
                    'authenticatePeer': 'yes',
                    'saslMechanisms': 'PLAIN',
                    'requireSsl': 'yes',
                    'requireEncryption': 'yes',
                    'sslProfile': 'ssl-profile-tls1-tls12'
                })
            ]

        # Adding SSL profiles
        conf += [
            # SSL Profile for TLSv1
            ('sslProfile', {'name': 'ssl-profile-tls1',
                            'caCertFile': cls.ssl_file('ca-certificate.pem'),
                            'certFile': cls.ssl_file('server-certificate.pem'),
                            'privateKeyFile': cls.ssl_file('server-private-key.pem'),
                            'ciphers': 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:' \
                                       'DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS',
                            'protocols': 'TLSv1',
                            'password': '******'}),
            # SSL Profile for TLSv1.1
            ('sslProfile', {'name': 'ssl-profile-tls11',
                            'caCertFile': cls.ssl_file('ca-certificate.pem'),
                            'certFile': cls.ssl_file('server-certificate.pem'),
                            'privateKeyFile': cls.ssl_file('server-private-key.pem'),
                            'ciphers': 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:' \
                                       'DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS',
                            'protocols': 'TLSv1.1',
                            'password': '******'}),
            # SSL Profile for TLSv1.2
            ('sslProfile', {'name': 'ssl-profile-tls12',
                            'caCertFile': cls.ssl_file('ca-certificate.pem'),
                            'certFile': cls.ssl_file('server-certificate.pem'),
                            'privateKeyFile': cls.ssl_file('server-private-key.pem'),
                            'ciphers': 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:' \
                                       'DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS',
                            'protocols': 'TLSv1.2',
                            'password': '******'}),
            # SSL Profile for TLSv1 and TLSv1.1
            ('sslProfile', {'name': 'ssl-profile-tls1-tls11',
                            'caCertFile': cls.ssl_file('ca-certificate.pem'),
                            'certFile': cls.ssl_file('server-certificate.pem'),
                            'privateKeyFile': cls.ssl_file('server-private-key.pem'),
                            'ciphers': 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:' \
                                       'DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS',
                            'protocols': 'TLSv1 TLSv1.1',
                            'password': '******'}),
            # SSL Profile for TLSv1 and TLSv1.2
            ('sslProfile', {'name': 'ssl-profile-tls1-tls12',
                            'caCertFile': cls.ssl_file('ca-certificate.pem'),
                            'certFile': cls.ssl_file('server-certificate.pem'),
                            'privateKeyFile': cls.ssl_file('server-private-key.pem'),
                            'ciphers': 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:' \
                                       'DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS',
                            'protocols': 'TLSv1 TLSv1.2',
                            'password': '******'}),
            # SSL Profile for TLSv1.1 and TLSv1.2
            ('sslProfile', {'name': 'ssl-profile-tls11-tls12',
                            'caCertFile': cls.ssl_file('ca-certificate.pem'),
                            'certFile': cls.ssl_file('server-certificate.pem'),
                            'privateKeyFile': cls.ssl_file('server-private-key.pem'),
                            'ciphers': 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:' \
                                       'DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS',
                            'protocols': 'TLSv1.1 TLSv1.2',
                            'password': '******'}),
            # SSL Profile for all TLS versions (protocols element not defined)
            ('sslProfile', {'name': 'ssl-profile-tls-all',
                            'caCertFile': cls.ssl_file('ca-certificate.pem'),
                            'certFile': cls.ssl_file('server-certificate.pem'),
                            'privateKeyFile': cls.ssl_file('server-private-key.pem'),
                            'ciphers': 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:' \
                                       'DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS',
                            'password': '******'}),
            # SSL Profile for invalid protocol version SSLv23
            ('sslProfile', {'name': 'ssl-profile-ssl3',
                            'caCertFile': cls.ssl_file('ca-certificate.pem'),
                            'certFile': cls.ssl_file('server-certificate.pem'),
                            'privateKeyFile': cls.ssl_file('server-private-key.pem'),
                            'ciphers': 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:' \
                                       'DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS',
                            'protocols': 'SSLv23',
                            'password': '******'})
        ]

        if cls.OPENSSL_ALLOW_TLSV1_3:
            conf += [
                # TLSv1.3 only
                ('listener', {
                    'host': '0.0.0.0',
                    'role': 'normal',
                    'port': cls.PORT_TLS13,
                    'authenticatePeer': 'no',
                    'sslProfile': 'ssl-profile-tls13'
                }),
                # SSL Profile for TLSv1.3
                ('sslProfile', {
                    'name': 'ssl-profile-tls13',
                    'caCertFile': cls.ssl_file('ca-certificate.pem'),
                    'certFile': cls.ssl_file('server-certificate.pem'),
                    'privateKeyFile': cls.ssl_file('server-private-key.pem'),
                    'protocols': 'TLSv1.3',
                    'password': '******'
                })
            ]

        config = Qdrouterd.Config(conf)

        cls.routers.append(cls.tester.qdrouterd("A", config, wait=False))
        cls.routers[0].wait_ports()

    def get_allowed_protocols(self, listener_port):
        """
        Loops through TLSv1, TLSv1.1 and TLSv1.2 and attempts to connect
        to the listener_port using each version. The result is a boolean list
        with results in respective order for TLSv1 [0], TLSv1.1 [1] and TLSv1.2 [2].
        :param listener_port:
        :return:
        """
        results = []

        for proto in ['TLSv1', 'TLSv1.1', 'TLSv1.2']:
            results.append(self.is_proto_allowed(listener_port, proto))
        if self.OPENSSL_ALLOW_TLSV1_3:
            results.append(self.is_proto_allowed(listener_port, 'TLSv1.3'))
        else:
            results.append(False)
        return results

    def is_proto_allowed(self, listener_port, tls_protocol):
        """
        Opens a simple proton client connection to the provided TCP port using
        a specific TLS protocol version and returns True in case connection
        was established and accepted or False otherwise.
        :param listener_port: TCP port number
        :param tls_protocol: TLSv1, TLSv1.1 or TLSv1.2 (string)
        :return:
        """
        # Management address to connect using the given TLS protocol
        url = Url("amqps://0.0.0.0:%d/$management" % listener_port)
        # Preparing SSLDomain (client cert) and SASL authentication info
        domain = SSLDomain(SSLDomain.MODE_CLIENT)
        # Enforcing given TLS protocol
        cproton.pn_ssl_domain_set_protocols(domain._domain, tls_protocol)

        # Try opening the secure and authenticated connection
        try:
            connection = BlockingConnection(url,
                                            sasl_enabled=False,
                                            ssl_domain=domain,
                                            timeout=self.TIMEOUT)
        except proton.Timeout:
            return False
        except proton.ConnectionException:
            return False
        except:
            return False

        # TLS version provided was accepted
        connection.close()
        return True

    def is_ssl_sasl_client_accepted(self, listener_port, tls_protocol):
        """
        Attempts to connect a proton client to the management address
        on the given listener_port using the specific tls_protocol provided.
        If connection was established and accepted, returns True and False otherwise.
        :param listener_port:
        :param tls_protocol:
        :return:
        """
        # Management address to connect using the given TLS protocol
        url = Url("amqps://0.0.0.0:%d/$management" % listener_port)
        # Preparing SSLDomain (client cert) and SASL authentication info
        domain = SSLDomain(SSLDomain.MODE_CLIENT)
        domain.set_credentials(self.ssl_file('client-certificate.pem'),
                               self.ssl_file('client-private-key.pem'),
                               'client-password')
        # Enforcing given TLS protocol
        cproton.pn_ssl_domain_set_protocols(domain._domain, tls_protocol)

        # Try opening the secure and authenticated connection
        try:
            connection = BlockingConnection(url,
                                            sasl_enabled=True,
                                            ssl_domain=domain,
                                            allowed_mechs='PLAIN',
                                            user='******',
                                            password='******')
        except proton.ConnectionException:
            return False

        # TLS version provided was accepted
        connection.close()
        return True

    def get_expected_tls_result(self, expected_results):
        """
        Expects a list with three boolean elements, representing
        TLSv1, TLSv1.1 and TLSv1.2 (in the respective order).
        When using OpenSSL >= 1.1.x, allowance of a given TLS version is
        based on MinProtocol / MaxProtocol definitions.
        It is also important
        to mention that TLSv1.2 is being allowed even when not specified in a
        listener when using OpenSSL >= 1.1.x.

        :param expected_results:
        :return:
        """
        (tlsv1, tlsv1_1, tlsv1_2, tlsv1_3) = expected_results
        return [
            self.OPENSSL_ALLOW_TLSV1 and tlsv1, self.OPENSSL_ALLOW_TLSV1_1
            and tlsv1_1, self.OPENSSL_ALLOW_TLSV1_2 and tlsv1_2,
            self.OPENSSL_ALLOW_TLSV1_3 and tlsv1_3
        ]

    @SkipIfNeeded(RouterTestSslBase.DISABLE_SSL_TESTING,
                  RouterTestSslBase.DISABLE_REASON)
    def test_tls1_only(self):
        """
        Expects TLSv1 only is allowed
        """
        self.assertEqual(
            self.get_expected_tls_result([True, False, False, False]),
            self.get_allowed_protocols(self.PORT_TLS1))

    @SkipIfNeeded(RouterTestSslBase.DISABLE_SSL_TESTING,
                  RouterTestSslBase.DISABLE_REASON)
    def test_tls11_only(self):
        """
        Expects TLSv1.1 only is allowed
        """
        self.assertEqual(
            self.get_expected_tls_result([False, True, False, False]),
            self.get_allowed_protocols(self.PORT_TLS11))

    @SkipIfNeeded(RouterTestSslBase.DISABLE_SSL_TESTING,
                  RouterTestSslBase.DISABLE_REASON)
    def test_tls12_only(self):
        """
        Expects TLSv1.2 only is allowed
        """
        self.assertEqual(
            self.get_expected_tls_result([False, False, True, False]),
            self.get_allowed_protocols(self.PORT_TLS12))

    @SkipIfNeeded(RouterTestSslBase.DISABLE_SSL_TESTING,
                  RouterTestSslBase.DISABLE_REASON)
    def test_tls13_only(self):
        """
        Expects TLSv1.3 only is allowed
        """
        self.assertEqual(
            self.get_expected_tls_result([False, False, False, True]),
            self.get_allowed_protocols(self.PORT_TLS13))

    @SkipIfNeeded(RouterTestSslBase.DISABLE_SSL_TESTING,
                  RouterTestSslBase.DISABLE_REASON)
    def test_tls1_tls11_only(self):
        """
        Expects TLSv1 and TLSv1.1 only are allowed
        """
        self.assertEqual(
            self.get_expected_tls_result([True, True, False, False]),
            self.get_allowed_protocols(self.PORT_TLS1_TLS11))

    @SkipIfNeeded(RouterTestSslBase.DISABLE_SSL_TESTING,
                  RouterTestSslBase.DISABLE_REASON)
    def test_tls1_tls12_only(self):
        """
        Expects TLSv1 and TLSv1.2 only are allowed
        """
        self.assertEqual(
            self.get_expected_tls_result([True, False, True, False]),
            self.get_allowed_protocols(self.PORT_TLS1_TLS12))

    @SkipIfNeeded(RouterTestSslBase.DISABLE_SSL_TESTING,
                  RouterTestSslBase.DISABLE_REASON)
    def test_tls11_tls12_only(self):
        """
        Expects TLSv1.1 and TLSv1.2 only are allowed
        """
        self.assertEqual(
            self.get_expected_tls_result([False, True, True, False]),
            self.get_allowed_protocols(self.PORT_TLS11_TLS12))

    @SkipIfNeeded(RouterTestSslBase.DISABLE_SSL_TESTING,
                  RouterTestSslBase.DISABLE_REASON)
    def test_tls_all(self):
        """
        Expects all supported versions: TLSv1, TLSv1.1, TLSv1.2 and TLSv1.3 to be allowed
        """
        self.assertEqual(
            self.get_expected_tls_result([True, True, True, True]),
            self.get_allowed_protocols(self.PORT_TLS_ALL))

    @SkipIfNeeded(RouterTestSslBase.DISABLE_SSL_TESTING,
                  RouterTestSslBase.DISABLE_REASON)
    def test_ssl_invalid(self):
        """
        Expects connection is rejected as SSL is no longer supported
        """
        self.assertEqual(False, self.is_proto_allowed(self.PORT_SSL3, 'SSLv3'))

    @SkipIfNeeded(RouterTestSslBase.DISABLE_SSL_TESTING or not SASL.extended(),
                  "Cyrus library not available. skipping test")
    def test_ssl_sasl_client_valid(self):
        """
        Attempts to connect a Proton client using a valid SASL authentication info
        and forcing the TLS protocol version, which should be accepted by the listener.
        :return:
        """
        if not SASL.extended():
            self.skipTest("Cyrus library not available. skipping test")

        exp_tls_results = self.get_expected_tls_result(
            [True, False, True, False])
        self.assertEqual(
            exp_tls_results[0],
            self.is_ssl_sasl_client_accepted(self.PORT_TLS_SASL, "TLSv1"))
        self.assertEqual(
            exp_tls_results[2],
            self.is_ssl_sasl_client_accepted(self.PORT_TLS_SASL, "TLSv1.2"))

    @SkipIfNeeded(RouterTestSslBase.DISABLE_SSL_TESTING or not SASL.extended(),
                  "Cyrus library not available. skipping test")
    def test_ssl_sasl_client_invalid(self):
        """
        Attempts to connect a Proton client using a valid SASL authentication info
        and forcing the TLS protocol version, which should be rejected by the listener.
        :return:
        """
        if not SASL.extended():
            self.skipTest("Cyrus library not available. skipping test")

        exp_tls_results = self.get_expected_tls_result(
            [True, False, True, False])
        self.assertEqual(
            exp_tls_results[1],
            self.is_ssl_sasl_client_accepted(self.PORT_TLS_SASL, "TLSv1.1"))
parser.add_option("-a", "--address", default="amqps://127.0.0.1:5672",
                  help="address to which messages are sent (default %default)")

parser.add_option("-m", "--messages", type="int", default=100,
                  help="number of messages to send (default %default)")

parser.add_option("-t", "--ssl-trustfile", default="/home/gmurthy/opensource/dispatch/tests/config-2/ca-certificate.pem",
                  help="The trust file")

parser.add_option("-c", "--ssl-certificate", default="/home/gmurthy/opensource/dispatch/tests/config-2/client-certificate.pem",
                  help="The cert file")

parser.add_option("-k", "--ssl-key", default="/home/gmurthy/opensource/dispatch/tests/config-2/client-private-key.pem",
                  help="The trust key")

parser.add_option("-p", "--ssl-password", default="client-password",
                  help="The trust file")

opts, args = parser.parse_args()

try:
    ssl_domain = SSLDomain(SSLDomain.MODE_CLIENT)
    ssl_domain.set_trusted_ca_db(str(opts.ssl_trustfile))
    ssl_domain.set_peer_authentication(SSLDomain.VERIFY_PEER, str(opts.ssl_trustfile))
    # for client authentication and private key password protected
    #ssl_domain.set_credentials(str(opts.ssl_certificate), str(opts.ssl_key), str(opts.ssl_password))
    # for client authentication and private key NOT password protected
    #ssl_domain.set_credentials(str(opts.ssl_certificate), str(opts.ssl_key), None)
    Container(Send(opts.address, opts.messages, ssl_domain=ssl_domain)).run()
except KeyboardInterrupt: pass
Ejemplo n.º 38
0
def _has_ssl():
    try:
        SSLDomain(SSLDomain.MODE_CLIENT)
        return True
    except SSLUnavailable:
        return False
Ejemplo n.º 39
0
                    "Can not find numeric priority in '%s'" % lines[i])
                priority = int(pri[0])
                # make sure the priority is from 0 to 9
                self.assertTrue(priority >= 0, "Priority was less than 0")
                self.assertTrue(priority <= 9, "Priority was greater than 9")

                # mark this priority as present
                priorities[priority] = True

        # make sure that all priorities are present in the list (currently 0-9)
        self.assertEqual(len(priorities.keys()), 10,
                         "Not all priorities are present")


try:
    SSLDomain(SSLDomain.MODE_CLIENT)

    class QdstatSslTest(system_test.TestCase):
        """Test qdstat tool output"""
        @staticmethod
        def ssl_file(name):
            return os.path.join(system_test.DIR, 'ssl_certs', name)

        @staticmethod
        def sasl_path():
            return os.path.join(system_test.DIR, 'sasl_configs')

        @classmethod
        def setUpClass(cls):
            super(QdstatSslTest, cls).setUpClass()
            # Write SASL configuration file: