/* Test various SSL connections between proactors*/ static void test_ssl(test_t *t) { if (!pn_ssl_present()) { TEST_LOGF(t, "Skip SSL test, no support"); return; } test_proactor_t tps[] ={ test_proactor(t, ssl_client_handler), test_proactor(t, ssl_server_handler) }; test_proactor_t *client = &tps[0], *server = &tps[1]; pn_ssl_domain_t *cd = client->handler.ssl_domain = pn_ssl_domain(PN_SSL_MODE_CLIENT); pn_ssl_domain_t *sd = server->handler.ssl_domain = pn_ssl_domain(PN_SSL_MODE_SERVER); TEST_CHECK(t, 0 == SET_CREDENTIALS(sd, "tserver")); pn_listener_t *l = test_listen(server, ""); /* Basic SSL connection */ pn_proactor_connect2(client->proactor, NULL, NULL, listener_info(l).connect); /* Open ok at both ends */ TEST_ETYPE_EQUAL(t, PN_CONNECTION_REMOTE_OPEN, TEST_PROACTORS_RUN(tps)); TEST_COND_EMPTY(t, last_condition); TEST_ETYPE_EQUAL(t, PN_CONNECTION_REMOTE_OPEN, TEST_PROACTORS_RUN(tps)); TEST_COND_EMPTY(t, last_condition); TEST_PROACTORS_RUN_UNTIL(tps, PN_TRANSPORT_CLOSED); TEST_PROACTORS_RUN_UNTIL(tps, PN_TRANSPORT_CLOSED); /* Verify peer with good hostname */ TEST_INT_EQUAL(t, 0, pn_ssl_domain_set_trusted_ca_db(cd, CERTIFICATE("tserver"))); TEST_INT_EQUAL(t, 0, pn_ssl_domain_set_peer_authentication(cd, PN_SSL_VERIFY_PEER_NAME, NULL)); pn_connection_t *c = pn_connection(); pn_connection_set_hostname(c, "test_server"); pn_proactor_connect2(client->proactor, c, NULL, listener_info(l).connect); TEST_ETYPE_EQUAL(t, PN_CONNECTION_REMOTE_OPEN, TEST_PROACTORS_RUN(tps)); TEST_COND_EMPTY(t, last_condition); TEST_ETYPE_EQUAL(t, PN_CONNECTION_REMOTE_OPEN, TEST_PROACTORS_RUN(tps)); TEST_COND_EMPTY(t, last_condition); TEST_PROACTORS_RUN_UNTIL(tps, PN_TRANSPORT_CLOSED); TEST_PROACTORS_RUN_UNTIL(tps, PN_TRANSPORT_CLOSED); /* Verify peer with bad hostname */ c = pn_connection(); pn_connection_set_hostname(c, "wrongname"); pn_proactor_connect2(client->proactor, c, NULL, listener_info(l).connect); TEST_ETYPE_EQUAL(t, PN_TRANSPORT_CLOSED, TEST_PROACTORS_RUN(tps)); TEST_COND_NAME(t, "amqp:connection:framing-error", last_condition); TEST_COND_DESC(t, "SSL", last_condition); TEST_PROACTORS_DRAIN(tps); pn_ssl_domain_free(cd); pn_ssl_domain_free(sd); TEST_PROACTORS_DESTROY(tps); }
void qd_server_config_free(qd_server_config_t *cf) { if (!cf) return; free(cf->host); free(cf->port); free(cf->host_port); free(cf->role); if (cf->http_root) free(cf->http_root); if (cf->name) free(cf->name); if (cf->protocol_family) free(cf->protocol_family); if (cf->sasl_username) free(cf->sasl_username); if (cf->sasl_password) free(cf->sasl_password); if (cf->sasl_mechanisms) free(cf->sasl_mechanisms); if (cf->auth_service) free(cf->auth_service); if (cf->sasl_init_hostname) free(cf->sasl_init_hostname); if (cf->auth_ssl_conf) pn_ssl_domain_free(cf->auth_ssl_conf); if (cf->ssl_profile) free(cf->ssl_profile); if (cf->failover_list) qd_failover_list_free(cf->failover_list); if (cf->log_message) free(cf->log_message); if (cf->ssl_certificate_file) free(cf->ssl_certificate_file); if (cf->ssl_private_key_file) free(cf->ssl_private_key_file); if (cf->ciphers) free(cf->ciphers); if (cf->ssl_password) free(cf->ssl_password); if (cf->ssl_trusted_certificate_db) free(cf->ssl_trusted_certificate_db); if (cf->ssl_trusted_certificates) free(cf->ssl_trusted_certificates); if (cf->ssl_uid_format) free(cf->ssl_uid_format); if (cf->ssl_display_name_file) free(cf->ssl_display_name_file); memset(cf, 0, sizeof(*cf)); }
void pn_ssl_free( pn_ssl_t *ssl) { if (!ssl) return; _log( ssl, "SSL socket freed.\n" ); release_ssl_socket( ssl ); if (ssl->domain) pn_ssl_domain_free(ssl->domain); if (ssl->session_id) free((void *)ssl->session_id); if (ssl->peer_hostname) free((void *)ssl->peer_hostname); if (ssl->inbuf) free((void *)ssl->inbuf); if (ssl->outbuf) free((void *)ssl->outbuf); free(ssl); }
void pn_ssl_free(pn_transport_t *transport) { pni_ssl_t *ssl = transport->ssl; if (!ssl) return; ssl_log(transport, "SSL socket freed." ); release_ssl_socket( ssl ); if (ssl->domain) pn_ssl_domain_free(ssl->domain); if (ssl->session_id) free((void *)ssl->session_id); if (ssl->peer_hostname) free((void *)ssl->peer_hostname); if (ssl->inbuf) free((void *)ssl->inbuf); if (ssl->outbuf) free((void *)ssl->outbuf); if (ssl->subject) free(ssl->subject); free(ssl); }
pn_ssl_domain_t *pn_ssl_domain( pn_ssl_mode_t mode ) { if (!ssl_initialized) { ssl_initialized = 1; SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); ssl_ex_data_index = SSL_get_ex_new_index( 0, (void *) "org.apache.qpid.proton.ssl", NULL, NULL, NULL); } pn_ssl_domain_t *domain = (pn_ssl_domain_t *) calloc(1, sizeof(pn_ssl_domain_t)); if (!domain) return NULL; domain->ref_count = 1; domain->mode = mode; // enable all supported protocol versions, then explicitly disable the // known vulnerable ones. This should allow us to use the latest version // of the TLS standard that the installed library supports. switch(mode) { case PN_SSL_MODE_CLIENT: domain->ctx = SSL_CTX_new(SSLv23_client_method()); // and TLSv1+ if (!domain->ctx) { ssl_log_error("Unable to initialize OpenSSL context."); free(domain); return NULL; } break; case PN_SSL_MODE_SERVER: domain->ctx = SSL_CTX_new(SSLv23_server_method()); // and TLSv1+ if (!domain->ctx) { ssl_log_error("Unable to initialize OpenSSL context."); free(domain); return NULL; } break; default: pn_transport_logf(NULL, "Invalid value for pn_ssl_mode_t: %d", mode); free(domain); return NULL; } const long reject_insecure = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; SSL_CTX_set_options(domain->ctx, reject_insecure); #ifdef SSL_OP_NO_COMPRESSION // Mitigate the CRIME vulnerability SSL_CTX_set_options(domain->ctx, SSL_OP_NO_COMPRESSION); #endif // by default, allow anonymous ciphers so certificates are not required 'out of the box' if (!SSL_CTX_set_cipher_list( domain->ctx, CIPHERS_ANONYMOUS )) { ssl_log_error("Failed to set cipher list to %s", CIPHERS_ANONYMOUS); pn_ssl_domain_free(domain); return NULL; } // ditto: by default do not authenticate the peer (can be done by SASL). if (pn_ssl_domain_set_peer_authentication( domain, PN_SSL_ANONYMOUS_PEER, NULL )) { pn_ssl_domain_free(domain); return NULL; } DH *dh = get_dh2048(); if (dh) { SSL_CTX_set_tmp_dh(domain->ctx, dh); DH_free(dh); SSL_CTX_set_options(domain->ctx, SSL_OP_SINGLE_DH_USE); } return domain; }
pn_ssl_domain_t *pn_ssl_domain( pn_ssl_mode_t mode ) { if (!ssl_initialized) { ssl_initialized = 1; SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); ssl_ex_data_index = SSL_get_ex_new_index( 0, (void *) "org.apache.qpid.proton.ssl", NULL, NULL, NULL); } pn_ssl_domain_t *domain = (pn_ssl_domain_t *) calloc(1, sizeof(pn_ssl_domain_t)); if (!domain) return NULL; domain->ref_count = 1; domain->mode = mode; switch(mode) { case PN_SSL_MODE_CLIENT: domain->ctx = SSL_CTX_new(TLSv1_client_method()); if (!domain->ctx) { _log_ssl_error( "Unable to initialize OpenSSL context.\n"); free(domain); return NULL; } break; case PN_SSL_MODE_SERVER: domain->ctx = SSL_CTX_new(SSLv23_server_method()); if (!domain->ctx) { _log_ssl_error("Unable to initialize OpenSSL context.\n"); free(domain); return NULL; } SSL_CTX_set_options(domain->ctx, SSL_OP_NO_SSLv2); // v2 is insecure break; default: _log_error("Invalid valid for pn_ssl_mode_t: %d\n", mode); free(domain); return NULL; } // by default, allow anonymous ciphers so certificates are not required 'out of the box' if (!SSL_CTX_set_cipher_list( domain->ctx, CIPHERS_ANONYMOUS )) { _log_ssl_error("Failed to set cipher list to %s\n", CIPHERS_ANONYMOUS); pn_ssl_domain_free(domain); return NULL; } // ditto: by default do not authenticate the peer (can be done by SASL). if (pn_ssl_domain_set_peer_authentication( domain, PN_SSL_ANONYMOUS_PEER, NULL )) { pn_ssl_domain_free(domain); return NULL; } DH *dh = get_dh2048(); if (dh) { SSL_CTX_set_tmp_dh(domain->ctx, dh); DH_free(dh); SSL_CTX_set_options(domain->ctx, SSL_OP_SINGLE_DH_USE); } return domain; }