Repository: qpid-proton Updated Branches: refs/heads/master 3989e3f89 -> e86cd22fc
PROTON-939: allow pn_ssl_set_peer_hostname to override connection's hostname Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/e86cd22f Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/e86cd22f Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/e86cd22f Branch: refs/heads/master Commit: e86cd22fc724add9e18f6150604ecd666ff4a4c9 Parents: 3989e3f Author: Ken Giusti <[email protected]> Authored: Wed Jul 8 12:02:20 2015 -0400 Committer: Ken Giusti <[email protected]> Committed: Wed Jul 8 16:11:25 2015 -0400 ---------------------------------------------------------------------- proton-c/include/proton/ssl.h | 4 +++ proton-c/src/transport/transport.c | 20 +++++++++++---- tests/python/proton_tests/ssl.py | 45 +++++++++++++++++++++++++++++++-- 3 files changed, 62 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e86cd22f/proton-c/include/proton/ssl.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/ssl.h b/proton-c/include/proton/ssl.h index b250e6a..d8d4d1f 100644 --- a/proton-c/include/proton/ssl.h +++ b/proton-c/include/proton/ssl.h @@ -293,6 +293,10 @@ PN_EXTERN pn_ssl_resume_status_t pn_ssl_resume_status( pn_ssl_t *ssl ); /** Set the expected identity of the remote peer. * + * By default, SSL will use the hostname associated with the connection that + * the transport is bound to (see ::pn_connection_set_hostname). This method + * allows the caller to override that default. + * * The hostname is used for two purposes: 1) when set on an SSL client, it is sent to the * server during the handshake (if Server Name Indication is supported), and 2) it is used * to check against the identifying name provided in the peer's certificate. If the http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e86cd22f/proton-c/src/transport/transport.c ---------------------------------------------------------------------- diff --git a/proton-c/src/transport/transport.c b/proton-c/src/transport/transport.c index e5e8276..d2c3509 100644 --- a/proton-c/src/transport/transport.c +++ b/proton-c/src/transport/transport.c @@ -652,11 +652,21 @@ int pn_transport_bind(pn_transport_t *transport, pn_connection_t *connection) pn_sasl(transport); pni_sasl_set_user_password(transport, pn_string_get(connection->auth_user), pn_string_get(connection->auth_password)); } - if (transport->sasl) { - pni_sasl_set_remote_hostname(transport, pn_string_get(connection->hostname)); - } - if (transport->ssl) { - pn_ssl_set_peer_hostname((pn_ssl_t*) transport, pn_string_get(connection->hostname)); + + if (pn_string_size(connection->hostname)) { + if (transport->sasl) { + pni_sasl_set_remote_hostname(transport, pn_string_get(connection->hostname)); + } + + // be sure not to overwrite a hostname already set by the user via + // pn_ssl_set_peer_hostname() called before the bind + if (transport->ssl) { + size_t name_len = 0; + pn_ssl_get_peer_hostname((pn_ssl_t*) transport, NULL, &name_len); + if (name_len == 0) { + pn_ssl_set_peer_hostname((pn_ssl_t*) transport, pn_string_get(connection->hostname)); + } + } } if (transport->open_rcvd) { http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e86cd22f/tests/python/proton_tests/ssl.py ---------------------------------------------------------------------- diff --git a/tests/python/proton_tests/ssl.py b/tests/python/proton_tests/ssl.py index f3c7f1f..8432797 100644 --- a/tests/python/proton_tests/ssl.py +++ b/tests/python/proton_tests/ssl.py @@ -53,7 +53,9 @@ class SslTest(common.Test): class SslTestConnection(object): """ Represents a single SSL connection. """ - def __init__(self, domain=None, mode=Transport.CLIENT, session_details=None): + def __init__(self, domain=None, mode=Transport.CLIENT, + session_details=None, conn_hostname=None, + ssl_peername=None): if not common.isSSLPresent(): raise Skipped("No SSL libraries found.") @@ -61,9 +63,14 @@ class SslTest(common.Test): self.domain = domain self.transport = Transport(mode) self.connection = Connection() - self.transport.bind(self.connection) + if conn_hostname: + self.connection.hostname = conn_hostname if domain: self.ssl = SSL( self.transport, self.domain, session_details ) + if ssl_peername: + self.ssl.peer_hostname = ssl_peername + # bind last, after all configuration complete: + self.transport.bind(self.connection) def _pump(self, ssl_client, ssl_server, buffer_size=1024): pump(ssl_client.transport, ssl_server.transport, buffer_size) @@ -691,6 +698,40 @@ class SslTest(common.Test): assert server.connection.state & Endpoint.REMOTE_UNINIT self.teardown() + # Pass: ensure that the user can give an alternate name that overrides + # the connection's configured hostname + self.setup() + self.server_domain.set_credentials(self._testpath("server-wc-certificate.pem"), + self._testpath("server-wc-private-key.pem"), + "server-password") + self.client_domain.set_trusted_ca_db(self._testpath("ca-certificate.pem")) + self.client_domain.set_peer_authentication( SSLDomain.VERIFY_PEER_NAME ) + + server = SslTest.SslTestConnection(self.server_domain, mode=Transport.SERVER) + client = SslTest.SslTestConnection(self.client_domain, + conn_hostname="This.Name.Does.not.Match", + ssl_peername="alternate.name.one.com") + self._do_handshake(client, server) + del client + del server + self.teardown() + + # Pass: ensure that the hostname supplied by the connection is used if + # none has been specified for the SSL instanace + self.setup() + self.server_domain.set_credentials(self._testpath("server-certificate.pem"), + self._testpath("server-private-key.pem"), + "server-password") + self.client_domain.set_trusted_ca_db(self._testpath("ca-certificate.pem")) + self.client_domain.set_peer_authentication( SSLDomain.VERIFY_PEER_NAME ) + + server = SslTest.SslTestConnection(self.server_domain, mode=Transport.SERVER) + client = SslTest.SslTestConnection(self.client_domain, + conn_hostname="a1.good.server.domain.com") + self._do_handshake(client, server) + del client + del server + self.teardown() def test_defaults_messenger_app(self): """ Test an SSL connection using the Messenger apps (no certificates) --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
