NO-JIRA: Remove SSL autodetect protocol hack which is no longer necessary - Add API to get ssf from SSL layer - Wired up pn_ssl_domain_allow_unsecured() (to pn_transport_require_encryption() functionality)
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/a3fc3ffa Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/a3fc3ffa Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/a3fc3ffa Branch: refs/heads/cjansen-cpp-client Commit: a3fc3ffa297626daf9e672a427277cc8d5c4db91 Parents: 3bd4aba Author: Andrew Stitcher <[email protected]> Authored: Tue May 26 15:31:38 2015 -0400 Committer: Andrew Stitcher <[email protected]> Committed: Tue May 26 15:31:38 2015 -0400 ---------------------------------------------------------------------- proton-c/include/proton/ssl.h | 7 +++++++ proton-c/src/engine/engine-internal.h | 1 - proton-c/src/ssl/openssl.c | 14 ++++++++++++-- proton-c/src/ssl/ssl-internal.h | 2 -- proton-c/src/ssl/ssl_stub.c | 5 +++++ proton-c/src/transport/transport.c | 25 +++++-------------------- proton-c/src/windows/schannel.c | 20 ++++++++++++++++++-- 7 files changed, 47 insertions(+), 27 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a3fc3ffa/proton-c/include/proton/ssl.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/ssl.h b/proton-c/include/proton/ssl.h index 87e7025..b250e6a 100644 --- a/proton-c/include/proton/ssl.h +++ b/proton-c/include/proton/ssl.h @@ -257,6 +257,13 @@ PN_EXTERN int pn_ssl_init( pn_ssl_t *ssl, */ PN_EXTERN bool pn_ssl_get_cipher_name(pn_ssl_t *ssl, char *buffer, size_t size); +/** Get the SSF (security strength factor) of the Cipher that is currently in use. + * + * @param[in] ssl the ssl client/server to query. + * @return the ssf, note that 0 means no security. + */ +PN_EXTERN int pn_ssl_get_ssf(pn_ssl_t *ssl); + /** Get the name of the SSL protocol that is currently in use. * * Gets a text description of the SSL protocol that is currently active, or returns FALSE if SSL http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a3fc3ffa/proton-c/src/engine/engine-internal.h ---------------------------------------------------------------------- diff --git a/proton-c/src/engine/engine-internal.h b/proton-c/src/engine/engine-internal.h index 4b24a02..2f0cc56 100644 --- a/proton-c/src/engine/engine-internal.h +++ b/proton-c/src/engine/engine-internal.h @@ -194,7 +194,6 @@ struct pn_transport_t { bool auth_required; bool authenticated; bool encryption_required; - bool encrypted; bool referenced; }; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a3fc3ffa/proton-c/src/ssl/openssl.c ---------------------------------------------------------------------- diff --git a/proton-c/src/ssl/openssl.c b/proton-c/src/ssl/openssl.c index 02a16fc..52eac01 100644 --- a/proton-c/src/ssl/openssl.c +++ b/proton-c/src/ssl/openssl.c @@ -718,6 +718,10 @@ int pn_ssl_init(pn_ssl_t *ssl0, pn_ssl_domain_t *domain, const char *session_id) if (session_id && domain->mode == PN_SSL_MODE_CLIENT) ssl->session_id = pn_strdup(session_id); + // If SSL doesn't specifically allow skipping encryption, require SSL + // TODO: This is a probably a stop-gap until allow_unsecured is removed + if (!domain->allow_unsecured) transport->encryption_required = true; + return init_ssl_socket(transport, ssl); } @@ -733,9 +737,15 @@ int pn_ssl_domain_allow_unsecured_client(pn_ssl_domain_t *domain) return 0; } -bool pn_ssl_allow_unsecured(pn_transport_t *transport) +int pn_ssl_get_ssf(pn_ssl_t *ssl0) { - return transport && transport->ssl && transport->ssl->domain && transport->ssl->domain->allow_unsecured; + const SSL_CIPHER *c; + + pni_ssl_t *ssl = get_ssl_internal(ssl0); + if (ssl && ssl->ssl && (c = SSL_get_current_cipher( ssl->ssl ))) { + return SSL_CIPHER_get_bits(c, NULL); + } + return 0; } bool pn_ssl_get_cipher_name(pn_ssl_t *ssl0, char *buffer, size_t size ) http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a3fc3ffa/proton-c/src/ssl/ssl-internal.h ---------------------------------------------------------------------- diff --git a/proton-c/src/ssl/ssl-internal.h b/proton-c/src/ssl/ssl-internal.h index 3d9e163..d3205ea 100644 --- a/proton-c/src/ssl/ssl-internal.h +++ b/proton-c/src/ssl/ssl-internal.h @@ -33,6 +33,4 @@ // release the SSL context void pn_ssl_free(pn_transport_t *transport); -bool pn_ssl_allow_unsecured(pn_transport_t *transport); - #endif /* ssl-internal.h */ http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a3fc3ffa/proton-c/src/ssl/ssl_stub.c ---------------------------------------------------------------------- diff --git a/proton-c/src/ssl/ssl_stub.c b/proton-c/src/ssl/ssl_stub.c index 4749d0c..f504a79 100644 --- a/proton-c/src/ssl/ssl_stub.c +++ b/proton-c/src/ssl/ssl_stub.c @@ -142,3 +142,8 @@ const char* pn_ssl_get_remote_subject(pn_ssl_t *ssl) { return NULL; } + +int pn_ssl_get_ssf(pn_ssl_t *ssl) +{ + return 0; +} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a3fc3ffa/proton-c/src/transport/transport.c ---------------------------------------------------------------------- diff --git a/proton-c/src/transport/transport.c b/proton-c/src/transport/transport.c index c0269d9..e72875b 100644 --- a/proton-c/src/transport/transport.c +++ b/proton-c/src/transport/transport.c @@ -180,22 +180,13 @@ static void pn_io_layer_setup(pn_transport_t *transport, unsigned int layer) { assert(layer == 0); // Figure out if we are server or not - if (transport->server) - { - // XXX: This is currently a large hack to work around the SSL - // code not handling a connection error before being set up fully - if (transport->ssl && pn_ssl_allow_unsecured(transport)) { + if (transport->server) { transport->io_layers[layer++] = &pni_autodetect_layer; return; - } } if (transport->ssl) { transport->io_layers[layer++] = &ssl_layer; } - if (transport->server) { - transport->io_layers[layer++] = &pni_autodetect_layer; - return; - } if (transport->sasl) { transport->io_layers[layer++] = &sasl_header_layer; } @@ -261,21 +252,18 @@ ssize_t pn_io_layer_input_autodetect(pn_transport_t *transport, unsigned int lay pn_transport_logf(transport, " <- %s", "SASL"); return 8; case PNI_PROTOCOL_AMQP1: - if (!transport->authenticated && transport->auth_required) { + if (transport->auth_required && !pn_transport_is_authenticated(transport)) { pn_do_error(transport, "amqp:connection:policy-error", "Client skipped authentication - forbidden"); pn_set_error_layer(transport); return 8; } -// TODO: Encrypted connection detection not implemented yet -#if 0 - if (!transport->encrypted && transport->encryption_required) { + if (transport->encryption_required && !pn_transport_is_encrypted(transport)) { pn_do_error(transport, "amqp:connection:policy-error", "Client connection unencryted - forbidden"); pn_set_error_layer(transport); return 8; } -#endif transport->io_layers[layer] = &amqp_write_header_layer; if (transport->trace & PN_TRACE_FRM) pn_transport_logf(transport, " <- %s", "AMQP"); @@ -408,7 +396,6 @@ static void pn_transport_initialize(void *object) transport->auth_required = false; transport->authenticated = false; transport->encryption_required = false; - transport->encrypted = false; transport->referenced = true; @@ -526,8 +513,7 @@ void pn_transport_require_auth(pn_transport_t *transport, bool required) bool pn_transport_is_authenticated(pn_transport_t *transport) { - assert(transport); - return transport->authenticated; + return transport && transport->authenticated; } void pn_transport_require_encryption(pn_transport_t *transport, bool required) @@ -538,8 +524,7 @@ void pn_transport_require_encryption(pn_transport_t *transport, bool required) bool pn_transport_is_encrypted(pn_transport_t *transport) { - assert(transport); - return transport->encrypted; + return transport && transport->ssl && pn_ssl_get_ssf((pn_ssl_t*)transport)>0; } void pn_transport_free(pn_transport_t *transport) http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a3fc3ffa/proton-c/src/windows/schannel.c ---------------------------------------------------------------------- diff --git a/proton-c/src/windows/schannel.c b/proton-c/src/windows/schannel.c index 78d05bf..757a108 100644 --- a/proton-c/src/windows/schannel.c +++ b/proton-c/src/windows/schannel.c @@ -409,6 +409,8 @@ static void ssl_session_free( pn_ssl_session_t *ssn) /** Public API - visible to application code */ +// TODO: This should really return true as SSL is fully implemented, +// but the tests currently fail because the fixed certificates aren't usable on windows bool pn_ssl_present(void) { return false; @@ -612,6 +614,10 @@ int pn_ssl_init(pn_ssl_t *ssl0, pn_ssl_domain_t *domain, const char *session_id) if (session_id && domain->mode == PN_SSL_MODE_CLIENT) ssl->session_id = pn_strdup(session_id); + // If SSL doesn't specifically allow skipping encryption, require SSL + // TODO: This is a probably a stop-gap until allow_unsecured is removed + if (!domain->allow_unsecured) transport->encryption_required = true; + ssl->cred = domain->cred; pn_incref(domain->cred); @@ -641,9 +647,19 @@ int pn_ssl_domain_allow_unsecured_client(pn_ssl_domain_t *domain) } -bool pn_ssl_allow_unsecured(pn_transport_t *transport) +// TODO: This is just an untested guess +int pn_ssl_get_ssf(pn_ssl_t *ssl0) { - return transport && transport->ssl && transport->ssl->domain && transport->ssl->domain->allow_unsecured; + SecPkgContext_ConnectionInfo info; + + pni_ssl_t *ssl = get_ssl_internal(ssl0); + if (ssl && + ssl->state == RUNNING && + SecIsValidHandle(&ssl->ctxt_handle) && + QueryContextAttributes(&ssl->ctxt_handle, SECPKG_ATTR_CONNECTION_INFO, &info) == SEC_E_OK) { + return info.dwCipherStrength; + } + return 0; } bool pn_ssl_get_cipher_name(pn_ssl_t *ssl0, char *buffer, size_t size ) --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
