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 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
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
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()
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")
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()
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()
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()
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)
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)
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 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)
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)
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)
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
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
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()
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)
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
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