PROTON-1888: allow configuration of connection details from file
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/e2d1ffe5 Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/e2d1ffe5 Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/e2d1ffe5 Branch: refs/heads/go1 Commit: e2d1ffe52ad1f5688b5363ec9ceda54ae93a9d65 Parents: 3e227e1 Author: Gordon Sim <g...@redhat.com> Authored: Tue Sep 25 21:04:11 2018 +0100 Committer: Gordon Sim <g...@redhat.com> Committed: Wed Sep 26 01:19:15 2018 +0100 ---------------------------------------------------------------------- python/examples/helloworld.py | 7 +- python/proton/_reactor.py | 55 ++++++ python/tests/proton_tests/__init__.py | 1 + python/tests/proton_tests/connect.py | 171 +++++++++++++++++++ python/tests/proton_tests/ssl_db/README.txt | 7 + .../ssl_db/client-private-key-no-password.pem | 13 ++ .../ssl_db/server-certificate-lh.pem | 26 +++ .../tests/proton_tests/ssl_db/server-lh.pkcs12 | Bin 0 -> 2199 bytes .../ssl_db/server-private-key-lh.pem | 21 +++ .../proton_tests/ssl_db/server-request-lh.pem | 23 +++ 10 files changed, 320 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2d1ffe5/python/examples/helloworld.py ---------------------------------------------------------------------- diff --git a/python/examples/helloworld.py b/python/examples/helloworld.py index 7a91aa4..5b88462 100755 --- a/python/examples/helloworld.py +++ b/python/examples/helloworld.py @@ -24,13 +24,12 @@ from proton.handlers import MessagingHandler from proton.reactor import Container class HelloWorld(MessagingHandler): - def __init__(self, server, address): + def __init__(self, address): super(HelloWorld, self).__init__() - self.server = server self.address = address def on_start(self, event): - conn = event.container.connect(self.server) + conn = event.container.connect() event.container.create_receiver(conn, self.address) event.container.create_sender(conn, self.address) @@ -42,4 +41,4 @@ class HelloWorld(MessagingHandler): print(event.message.body) event.connection.close() -Container(HelloWorld("localhost:5672", "examples")).run() +Container(HelloWorld("examples")).run() http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2d1ffe5/python/proton/_reactor.py ---------------------------------------------------------------------- diff --git a/python/proton/_reactor.py b/python/proton/_reactor.py index 63e89c8..a47625f 100644 --- a/python/proton/_reactor.py +++ b/python/proton/_reactor.py @@ -19,6 +19,7 @@ from __future__ import absolute_import +import json import os import logging import traceback @@ -726,6 +727,28 @@ class SSLConfig(object): self.client.set_trusted_ca_db(certificate_db) self.server.set_trusted_ca_db(certificate_db) +def find_config_file(): + confname = 'connect.json' + confpath = ['.', '~/.config/messaging','/etc/messaging'] + for d in confpath: + f = os.path.join(d, confname) + if os.path.isfile(f): + return f + return None + +def get_default_config(): + conf = os.environ.get('MESSAGING_CONNECT_FILE') or find_config_file() + if conf and os.path.isfile(conf): + with open(conf, 'r') as f: + return json.load(f) + else: + return {} + +def get_default_port_for_scheme(scheme): + if scheme == 'amqps': + return 5671 + else: + return 5672 class Container(Reactor): """A representation of the AMQP concept of a 'container', which @@ -801,6 +824,38 @@ class Container(Reactor): the authentication secret. """ + if not url and not urls and not address: + config = get_default_config() + scheme = config.get('scheme', 'amqp') + _url = "%s://%s:%s" % (scheme, config.get('host', 'localhost'), config.get('port', get_default_port_for_scheme(scheme))) + _ssl_domain = None + _kwargs = kwargs + if config.get('user'): + _kwargs['user'] = config.get('user') + if config.get('password'): + _kwargs['password'] = config.get('password') + sasl_config = config.get('sasl', {}) + _kwargs['sasl_enabled'] = sasl_config.get('enabled', True) + if sasl_config.get('mechanisms'): + _kwargs['allowed_mechs'] = sasl_config.get('mechanisms') + tls_config = config.get('tls', {}) + if scheme == 'amqps': + _ssl_domain = SSLDomain(SSLDomain.MODE_CLIENT) + ca = tls_config.get('ca') + cert = tls_config.get('cert') + key = tls_config.get('key') + if ca: + _ssl_domain.set_trusted_ca_db(str(ca)) + if tls_config.get('verify', True): + _ssl_domain.set_peer_authentication(SSLDomain.VERIFY_PEER_NAME, str(ca)) + if cert and key: + _ssl_domain.set_credentials(str(cert), str(key), None) + + return self._connect(_url, handler=handler, reconnect=reconnect, heartbeat=heartbeat, ssl_domain=_ssl_domain, **_kwargs) + else: + return self._connect(url=url, urls=urls, handler=handler, reconnect=reconnect, heartbeat=heartbeat, ssl_domain=ssl_domain, **kwargs) + + def _connect(self, url=None, urls=None, address=None, handler=None, reconnect=None, heartbeat=None, ssl_domain=None, **kwargs): conn = self.connection(handler) conn.container = self.container_id or str(_generate_uuid()) conn.offered_capabilities = kwargs.get('offered_capabilities') http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2d1ffe5/python/tests/proton_tests/__init__.py ---------------------------------------------------------------------- diff --git a/python/tests/proton_tests/__init__.py b/python/tests/proton_tests/__init__.py index 672a43c..eca82fe 100644 --- a/python/tests/proton_tests/__init__.py +++ b/python/tests/proton_tests/__init__.py @@ -31,3 +31,4 @@ from . import interop from . import soak from . import url from . import utils +from . import connect http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2d1ffe5/python/tests/proton_tests/connect.py ---------------------------------------------------------------------- diff --git a/python/tests/proton_tests/connect.py b/python/tests/proton_tests/connect.py new file mode 100644 index 0000000..f8d21b9 --- /dev/null +++ b/python/tests/proton_tests/connect.py @@ -0,0 +1,171 @@ +from __future__ import absolute_import +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +import time +import sys +import json +from .common import Test, SkipTest, TestServer, free_tcp_port, ensureCanTestExtendedSASL +from proton import SSLDomain +from proton.reactor import Container +from proton.handlers import MessagingHandler +from .ssl import _testpath + +def write_connect_conf(obj): + with open('connect.json', 'w') as outfile: + json.dump(obj, outfile) + +class Server(MessagingHandler): + def __init__(self, expected_user=None, scheme='amqp'): + super(Server, self).__init__() + self.port = free_tcp_port() + self.scheme = scheme + self.url = '%s://localhost:%i' % (self.scheme, self.port) + self.expected_user = expected_user + self.verified_user = False + + def on_start(self, event): + self.listener = event.container.listen(self.url) + + def on_connection_opening(self, event): + if self.expected_user: + assert event.connection.transport.user == self.expected_user + self.verified_user = True + + def on_connection_closing(self, event): + event.connection.close() + self.listener.close() + +class Client(MessagingHandler): + def __init__(self): + super(Client, self).__init__() + self.opened = False + + def on_connection_opened(self, event): + self.opened = True + event.connection.close() + +class ConnectConfigTest(Test): + def test_port(self): + ensureCanTestExtendedSASL() + server = Server() + container = Container(server) + client = Client() + write_connect_conf({'port':server.port}) + container.connect(handler=client, reconnect=False) + container.run() + assert client.opened == True + + def test_user(self): + ensureCanTestExtendedSASL() + user = 'user@proton' + password = 'password' + server = Server(user) + container = Container(server) + client = Client() + write_connect_conf({'port':server.port, 'user':user, 'password':password}) + container.connect(handler=client, reconnect=False) + container.run() + assert client.opened == True + assert server.verified_user == True + + def test_ssl(self): + ensureCanTestExtendedSASL() + server = Server(scheme='amqps') + container = Container(server) + container.ssl.server.set_credentials(_testpath('server-certificate.pem'), + _testpath('server-private-key.pem'), + 'server-password') + client = Client() + config = { + 'scheme':'amqps', + 'port':server.port, + 'tls': { + 'verify': False + } + } + write_connect_conf(config) + container.connect(handler=client, reconnect=False) + container.run() + assert client.opened == True + + def test_ssl_external(self): + ensureCanTestExtendedSASL() + server = Server(scheme='amqps') + container = Container(server) + container.ssl.server.set_credentials(_testpath('server-certificate-lh.pem'), + _testpath('server-private-key-lh.pem'), + 'server-password') + container.ssl.server.set_trusted_ca_db(_testpath('ca-certificate.pem')) + container.ssl.server.set_peer_authentication( SSLDomain.VERIFY_PEER, + _testpath('ca-certificate.pem') ) + + client = Client() + config = { + 'scheme':'amqps', + 'port':server.port, + 'sasl': { + 'mechanisms': 'EXTERNAL' + }, + 'tls': { + 'cert': _testpath('client-certificate.pem'), + 'key': _testpath('client-private-key-no-password.pem'), + 'ca': _testpath('ca-certificate.pem'), + 'verify': True + } + } + write_connect_conf(config) + container.connect(handler=client, reconnect=False) + container.run() + assert client.opened == True + + def test_ssl_plain(self): + ensureCanTestExtendedSASL() + user = 'user@proton' + password = 'password' + server = Server(expected_user=user, scheme='amqps') + container = Container(server) + container.ssl.server.set_credentials(_testpath('server-certificate-lh.pem'), + _testpath('server-private-key-lh.pem'), + 'server-password') + container.ssl.server.set_trusted_ca_db(_testpath('ca-certificate.pem')) + container.ssl.server.set_peer_authentication( SSLDomain.VERIFY_PEER, + _testpath('ca-certificate.pem') ) + + client = Client() + config = { + 'scheme':'amqps', + 'port':server.port, + 'user':user, + 'password':password, + 'sasl': { + 'mechanisms': 'PLAIN' + }, + 'tls': { + 'cert': _testpath('client-certificate.pem'), + 'key': _testpath('client-private-key-no-password.pem'), + 'ca': _testpath('ca-certificate.pem'), + 'verify': True + } + } + write_connect_conf(config) + container.connect(handler=client, reconnect=False) + container.run() + assert client.opened == True + http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2d1ffe5/python/tests/proton_tests/ssl_db/README.txt ---------------------------------------------------------------------- diff --git a/python/tests/proton_tests/ssl_db/README.txt b/python/tests/proton_tests/ssl_db/README.txt index 20c92b2..8a6bd6a 100644 --- a/python/tests/proton_tests/ssl_db/README.txt +++ b/python/tests/proton_tests/ssl_db/README.txt @@ -42,11 +42,18 @@ keytool -storetype pkcs12 -keystore server.pkcs12 -storepass server-password -al keytool -storetype pkcs12 -keystore ca.pkcs12 -storepass ca-password -alias ca -keypass ca-password -gencert -rfc -validity 99999 -infile server-request.pem -outfile server-certificate.pem openssl pkcs12 -nocerts -passin pass:server-password -in server.pkcs12 -passout pass:server-password -out server-private-key.pem +# Create a certificate request for a server certificate using localhost. Use the CA's certificate to sign it: +keytool -storetype pkcs12 -keystore server-lh.pkcs12 -storepass server-password -alias server-certificate -keypass server-password -genkey -dname "CN=localhost" -validity 99999 +keytool -storetype pkcs12 -keystore server-lh.pkcs12 -storepass server-password -alias server-certificate -keypass server-password -certreq -file server-request-lh.pem +keytool -storetype pkcs12 -keystore ca.pkcs12 -storepass ca-password -alias ca -keypass ca-password -gencert -rfc -validity 99999 -infile server-request-lh.pem -outfile server-certificate-lh.pem +openssl pkcs12 -nocerts -passin pass:server-password -in server-lh.pkcs12 -passout pass:server-password -out server-private-key-lh.pem + # Create a certificate request for the client certificate. Use the CA's certificate to sign it: keytool -storetype pkcs12 -keystore client.pkcs12 -storepass client-password -alias client-certificate -keypass client-password -genkey -dname "O=Client,CN=127.0.0.1" -validity 99999 keytool -storetype pkcs12 -keystore client.pkcs12 -storepass client-password -alias client-certificate -keypass client-password -certreq -file client-request.pem keytool -storetype pkcs12 -keystore ca.pkcs12 -storepass ca-password -alias ca -keypass ca-password -gencert -rfc -validity 99999 -infile client-request.pem -outfile client-certificate.pem openssl pkcs12 -nocerts -passin pass:client-password -in client.pkcs12 -passout pass:client-password -out client-private-key.pem +openssl pkcs12 -nocerts -passin pass:client-password -in client.pkcs12 -nodes -out client-private-key-no-password.pem # Create another client certificate with a different subject line keytool -storetype pkcs12 -keystore client1.pkcs12 -storepass client-password -alias client-certificate1 -keypass client-password -genkey -dname "O=Client,CN=127.0.0.1,C=US,ST=ST,L=City,OU=Dev" -validity 99999 http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2d1ffe5/python/tests/proton_tests/ssl_db/client-private-key-no-password.pem ---------------------------------------------------------------------- diff --git a/python/tests/proton_tests/ssl_db/client-private-key-no-password.pem b/python/tests/proton_tests/ssl_db/client-private-key-no-password.pem new file mode 100644 index 0000000..4609e17 --- /dev/null +++ b/python/tests/proton_tests/ssl_db/client-private-key-no-password.pem @@ -0,0 +1,13 @@ +Bag Attributes + friendlyName: client-certificate + localKeyID: 54 69 6D 65 20 31 35 30 31 37 31 30 38 31 37 32 33 39 +Key Attributes: <No Attributes> +-----BEGIN PRIVATE KEY----- +MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdS +PO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVCl +pJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith +1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7L +vKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3 +zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImo +g9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFgIUagxvW3D50G8WfG2jBtMMVQRYXnY= +-----END PRIVATE KEY----- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2d1ffe5/python/tests/proton_tests/ssl_db/server-certificate-lh.pem ---------------------------------------------------------------------- diff --git a/python/tests/proton_tests/ssl_db/server-certificate-lh.pem b/python/tests/proton_tests/ssl_db/server-certificate-lh.pem new file mode 100644 index 0000000..6c9c7ff --- /dev/null +++ b/python/tests/proton_tests/ssl_db/server-certificate-lh.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEUzCCBA+gAwIBAgIEHgDMyTANBglghkgBZQMEAwIFADAxMRcwFQYDVQQDEw5U +cnVzdGVkLkNBLmNvbTEWMBQGA1UEChMNVHJ1c3QgTWUgSW5jLjAgFw0xODA5MjUy +MDM4MzFaGA8yMjkyMDcwOTIwMzgzMVowFDESMBAGA1UEAxMJbG9jYWxob3N0MIID +QjCCAjUGByqGSM44BAEwggIoAoIBAQCPeTXZuarpv6vtiHrPSVG28y7FnjuvNxjo +6sSWHz79NgbnQ1GpxBgzObgJ58KuHFObp0dbhdARrbi0eYd1SYRpXKwOjxSzNggo +oi/6JxEKPWKpk0U0CaD+aWxGWPhL3SCBnDcJoBBXsZWtzQAjPbpUhLYpH51kjviD +RIZ3l5zsBLQ0pqwudemYXeI9sCkvwRGMn/qdgYHnM423krcw17njSVkvaAmYchU5 +Feo9a4tGU8YzRY+AOzKkwuDycpAlbk4/ijsIOKHEUOThjBopo33fXqFD3ktm/wSQ +PtXPFiPhWNSHxgjpfyEc2B3KI8tuOAdl+CLjQr5ITAV2OTlgHNZnAh0AuvaWpoV4 +99/e5/pnyXfHhe8ysjO65YDAvNVpXQKCAQAWplxYIEhQcE51AqOXVwQNNNo6NHjB +VNTkpcAtJC7gT5bmHkvQkEq9rI837rHgnzGC0jyQQ8tkL4gAQWDt+coJsyB2p5wy +pifyRz6Rh5uixOdEvSCBVEy1W4AsNo0fqD7UielOD6BojjJCilx4xHjGjQUntxya +OrsLC+EsRGiWOefTznTbEBplqiuH9kxoJts+xy9LVZmDS7TtsC98kOmkltOlXVNb +6/xF1PYZ9j897buHOSXC8iTgdzEpbaiH7B5HSPh++1/et1SEMWsiMt7lU92vAhEr +DR8C2jCXMiT+J67ai51LKSLZuovjntnhA6Y8UoELxoi34u1DFuHvF9veA4IBBQAC +ggEAdVroB0ANoeIKYkkbTwxY8B1eIHDUX1Xa1tFCzfTBIzeP4K+5a2Km5UqkIDje +a9p3MtJgSZMAW9iJ1EDLBFH+75JirTtiYmt78vx9gIhSZkE2l/oKoVKrG3W1AJpX +b95RnfivKIETioLGSJWNuGk2X2T1u1w0xePMGRi+dmcsCa/2ci3bMNnkkHzqNtv9 +zqWJPtjcJaGjRn0ttzXdulpdRgNndSddjBhBbFGJc8wQzqnL0aHby8tgXYcAlKiG +tgcwZGTTrpg27bHyt6sMuANJZmd8hdgQ1MrFzw07EOoLa+I+7VNAsyF32gzTH1vy +wGXmCLHGOZLOGI3rBHVE55+2IaNCMEAwHwYDVR0jBBgwFoAUsjZ7PCKVgcZLkxE8 +xaWJ8cf5jmowHQYDVR0OBBYEFO4pNMdb7FfaJo8k5NZGlEGO0PnDMA0GCWCGSAFl +AwQDAgUAAy8AMCwCFB9MMOywXxzgX/OYImNrAJvR2sWLAhRMlioucHg/hFw456Y/ +fgaL4qbZfA== +-----END CERTIFICATE----- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2d1ffe5/python/tests/proton_tests/ssl_db/server-lh.pkcs12 ---------------------------------------------------------------------- diff --git a/python/tests/proton_tests/ssl_db/server-lh.pkcs12 b/python/tests/proton_tests/ssl_db/server-lh.pkcs12 new file mode 100644 index 0000000..6d4c34f Binary files /dev/null and b/python/tests/proton_tests/ssl_db/server-lh.pkcs12 differ http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2d1ffe5/python/tests/proton_tests/ssl_db/server-private-key-lh.pem ---------------------------------------------------------------------- diff --git a/python/tests/proton_tests/ssl_db/server-private-key-lh.pem b/python/tests/proton_tests/ssl_db/server-private-key-lh.pem new file mode 100644 index 0000000..44279a6 --- /dev/null +++ b/python/tests/proton_tests/ssl_db/server-private-key-lh.pem @@ -0,0 +1,21 @@ +Bag Attributes + friendlyName: server-certificate + localKeyID: 54 69 6D 65 20 31 35 33 37 39 30 37 39 31 30 32 39 39 +Key Attributes: <No Attributes> +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIICvDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQInDWm8BaYfdQCAggA +MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECM0p5kC5QUKFBIICaJUTK4ZRiUBt +g0YgRnrH1HE5f1h0tOHvnCND0wJmOmcwStqVtjIqVa5bkU4ZEEOOwWwO8n682Idd +xc7c3Tfu86nGOFSNH3PpM5Urp8eb5yg3c+rrxdjbRfWKmFtup5CnmyIUHRwvpwKo +4iBSyMTLuwB149OA10i7soB2xPH+5ZoutKIEG7HmSKBxAIYnt7awty3uQide+CKw +PPcm+P4fGeNAKoZ0QLQFuTF8ZDOzWFv6+LJuIIlHNiRwCKGLVglFpysd22PFJ7GX +nVjJ1wfdXyqixoFGSCa25e2VIwVL3OnMyzAsNKMzAoDc0kzs1wbnAAeGSO8mJsMp +ea4KHu08YFuhI99FAOHvOh1UGDBdtQ5VLBoLD+K26FCIIb45IYxbpBNXvy8N+tdW +1YrqlpjGrV0mr7mG7QTSlewowJF9KKj+YKDYjENJTjDf64S3xacNmRUbBrewGD4B +6YJyyREhj8o/kl5IuLQtLoDx6t6zr80y45LG1zarzEn3ncwAMnOApQiYLO4R/K8Y +T3jgQmZ2vqArr2dWyYN+fqoouEHr6MRbKiOhruimFC3+zVtKfNI0flHPxX4T74Xr +gETirpfZandMcqsZb6DDvXmY230IUR17NiruyLX2269LfmyT4Q5nlbURgqBYQ7zI +niM1EbTSzXVspE3x/HijJuR2nPX3k8VOmY/l87bHi9hOVen3SPt5lOYHnIhQ26jx +c+/0c7vOONxnYnl9ucB9Kgk5ku+wqPbR/olsiB36Rsf7VjZtQlwibaY2Dtb/zt7C +VvW+geNsIkbM/qlBh5isl8diuwx75e+tyLsnXRcQ8z8= +-----END ENCRYPTED PRIVATE KEY----- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e2d1ffe5/python/tests/proton_tests/ssl_db/server-request-lh.pem ---------------------------------------------------------------------- diff --git a/python/tests/proton_tests/ssl_db/server-request-lh.pem b/python/tests/proton_tests/ssl_db/server-request-lh.pem new file mode 100644 index 0000000..14072f8 --- /dev/null +++ b/python/tests/proton_tests/ssl_db/server-request-lh.pem @@ -0,0 +1,23 @@ +-----BEGIN NEW CERTIFICATE REQUEST----- +MIID5zCCA5ECAQAwFDESMBAGA1UEAxMJbG9jYWxob3N0MIIDQjCCAjUGByqGSM44 +BAEwggIoAoIBAQCPeTXZuarpv6vtiHrPSVG28y7FnjuvNxjo6sSWHz79NgbnQ1Gp +xBgzObgJ58KuHFObp0dbhdARrbi0eYd1SYRpXKwOjxSzNggooi/6JxEKPWKpk0U0 +CaD+aWxGWPhL3SCBnDcJoBBXsZWtzQAjPbpUhLYpH51kjviDRIZ3l5zsBLQ0pqwu +demYXeI9sCkvwRGMn/qdgYHnM423krcw17njSVkvaAmYchU5Feo9a4tGU8YzRY+A +OzKkwuDycpAlbk4/ijsIOKHEUOThjBopo33fXqFD3ktm/wSQPtXPFiPhWNSHxgjp +fyEc2B3KI8tuOAdl+CLjQr5ITAV2OTlgHNZnAh0AuvaWpoV499/e5/pnyXfHhe8y +sjO65YDAvNVpXQKCAQAWplxYIEhQcE51AqOXVwQNNNo6NHjBVNTkpcAtJC7gT5bm +HkvQkEq9rI837rHgnzGC0jyQQ8tkL4gAQWDt+coJsyB2p5wypifyRz6Rh5uixOdE +vSCBVEy1W4AsNo0fqD7UielOD6BojjJCilx4xHjGjQUntxyaOrsLC+EsRGiWOefT +znTbEBplqiuH9kxoJts+xy9LVZmDS7TtsC98kOmkltOlXVNb6/xF1PYZ9j897buH +OSXC8iTgdzEpbaiH7B5HSPh++1/et1SEMWsiMt7lU92vAhErDR8C2jCXMiT+J67a +i51LKSLZuovjntnhA6Y8UoELxoi34u1DFuHvF9veA4IBBQACggEAdVroB0ANoeIK +YkkbTwxY8B1eIHDUX1Xa1tFCzfTBIzeP4K+5a2Km5UqkIDjea9p3MtJgSZMAW9iJ +1EDLBFH+75JirTtiYmt78vx9gIhSZkE2l/oKoVKrG3W1AJpXb95RnfivKIETioLG +SJWNuGk2X2T1u1w0xePMGRi+dmcsCa/2ci3bMNnkkHzqNtv9zqWJPtjcJaGjRn0t +tzXdulpdRgNndSddjBhBbFGJc8wQzqnL0aHby8tgXYcAlKiGtgcwZGTTrpg27bHy +t6sMuANJZmd8hdgQ1MrFzw07EOoLa+I+7VNAsyF32gzTH1vywGXmCLHGOZLOGI3r +BHVE55+2IaAwMC4GCSqGSIb3DQEJDjEhMB8wHQYDVR0OBBYEFO4pNMdb7FfaJo8k +5NZGlEGO0PnDMA0GCWCGSAFlAwQDAgUAA0EAMD4CHQCdi9BZ+4bJSteebZbHHIdV +rsazxRXT3Jdq+JCZAh0AmqErYresnNvzucEWlQ2WcSHUvMc66e2DfIWplg== +-----END NEW CERTIFICATE REQUEST----- --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org