allow sasl implementation to be selected per connection
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/75fc8419 Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/75fc8419 Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/75fc8419 Branch: refs/heads/PROTON-1488 Commit: 75fc8419be184b2c8f1a136270a369339b658443 Parents: 52e75d9 Author: Gordon Sim <g...@redhat.com> Authored: Thu May 25 12:18:10 2017 +0100 Committer: Gordon Sim <g...@redhat.com> Committed: Thu May 25 14:44:45 2017 +0100 ---------------------------------------------------------------------- proton-c/include/proton/proactor.h | 3 +- proton-c/src/sasl/remote_sasl.c | 51 +++++++++++++--------- proton-c/src/sasl/sasl-internal.h | 8 ++-- proton-c/src/sasl/sasl.c | 76 ++++++++++++--------------------- 4 files changed, 66 insertions(+), 72 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/75fc8419/proton-c/include/proton/proactor.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/proactor.h b/proton-c/include/proton/proactor.h index 761fb86..978453b 100644 --- a/proton-c/include/proton/proactor.h +++ b/proton-c/include/proton/proactor.h @@ -285,8 +285,9 @@ PNP_EXTERN pn_proactor_t *pn_event_proactor(pn_event_t *event); */ PNP_EXTERN pn_millis_t pn_proactor_now(void); -PNP_EXTERN void pn_use_remote_authentication_service(const char* address); +PNP_EXTERN void pn_use_remote_authentication_service(pn_transport_t* transport, const char* address); PNP_EXTERN bool pn_is_authentication_service_connection(pn_connection_t* conn); +PNP_EXTERN void pn_handle_authentication_service_connection_event(pn_event_t *e); /** * @defgroup proactor_events Events http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/75fc8419/proton-c/src/sasl/remote_sasl.c ---------------------------------------------------------------------- diff --git a/proton-c/src/sasl/remote_sasl.c b/proton-c/src/sasl/remote_sasl.c index 54a96e5..d799a93 100644 --- a/proton-c/src/sasl/remote_sasl.c +++ b/proton-c/src/sasl/remote_sasl.c @@ -37,10 +37,10 @@ const int8_t DOWNSTREAM_MECHANISMS_RECEIVED = 3; const int8_t DOWNSTREAM_CHALLENGE_RECEIVED = 4; const int8_t DOWNSTREAM_OUTCOME_RECEIVED = 5; -const char* authentication_service_address = NULL; - typedef struct { + char* authentication_service_address; + pn_connection_t* downstream; char* selected_mechanism; pni_owned_bytes_t response; @@ -65,9 +65,10 @@ void pni_copy_bytes(const pn_bytes_t* from, pni_owned_bytes_t* to) memcpy(to->start, from->start, from->size); } -pni_sasl_relay_t* new_pni_sasl_relay_t(void) +pni_sasl_relay_t* new_pni_sasl_relay_t(const char* address) { pni_sasl_relay_t* instance = (pni_sasl_relay_t*) malloc(sizeof(pni_sasl_relay_t)); + instance->authentication_service_address = pn_strdup(address); instance->selected_mechanism = 0; instance->response.start = 0; instance->response.size = 0; @@ -82,6 +83,7 @@ pni_sasl_relay_t* new_pni_sasl_relay_t(void) void delete_pni_sasl_relay_t(pni_sasl_relay_t* instance) { + if (instance->authentication_service_address) free(instance->authentication_service_address); if (instance->mechlist) free(instance->mechlist); if (instance->selected_mechanism) free(instance->selected_mechanism); if (instance->response.start) free(instance->response.start); @@ -132,13 +134,9 @@ void set_sasl_relay_context(pn_connection_t* conn, pni_sasl_relay_t* context) bool remote_init_server(pn_transport_t* transport) { pn_connection_t* upstream = pn_transport_connection(transport); - if (upstream) { - if (transport->sasl->impl_context) { - return true; - } - pn_connection_open(upstream); - pni_sasl_relay_t* impl = new_pni_sasl_relay_t(); - transport->sasl->impl_context = impl; + if (upstream && transport->sasl->impl_context) { + pni_sasl_relay_t* impl = (pni_sasl_relay_t*) transport->sasl->impl_context; + if (impl->upstream) return true; impl->upstream = upstream; pn_proactor_t* proactor = pn_connection_proactor(upstream); if (!proactor) return false; @@ -147,7 +145,7 @@ bool remote_init_server(pn_transport_t* transport) pn_connection_set_user(impl->downstream, "dummy");//force sasl set_sasl_relay_context(impl->downstream, impl); - pn_proactor_connect(proactor, impl->downstream, authentication_service_address); + pn_proactor_connect(proactor, impl->downstream, impl->authentication_service_address); return true; } else { return false; @@ -171,13 +169,10 @@ bool remote_init_client(pn_transport_t* transport) } } -bool remote_free(pn_transport_t *transport) +void remote_free(pn_transport_t *transport) { if (transport->sasl->impl_context) { release_pni_sasl_relay_t((pni_sasl_relay_t*) transport->sasl->impl_context); - return true; - } else { - return false; } } @@ -287,11 +282,10 @@ void remote_process_response(pn_transport_t *transport, const pn_bytes_t *recv) } } -void pn_use_remote_authentication_service(const char* address) +void set_remote_impl(pn_transport_t *transport, pni_sasl_relay_t* context) { - authentication_service_address = address; pni_sasl_implementation remote_impl; - remote_impl.free = &remote_free; + remote_impl.free_impl = &remote_free; remote_impl.get_mechs = &remote_get_mechs; remote_impl.init_server = &remote_init_server; remote_impl.process_init = &remote_process_init; @@ -301,5 +295,24 @@ void pn_use_remote_authentication_service(const char* address) remote_impl.process_challenge = &remote_process_challenge; remote_impl.process_outcome = &remote_process_outcome; remote_impl.prepare = &remote_prepare; - pni_sasl_set_implementation(remote_impl); + pni_sasl_set_implementation(transport, remote_impl, context); +} + +void pn_use_remote_authentication_service(pn_transport_t *transport, const char* address) +{ + pni_sasl_relay_t* context = new_pni_sasl_relay_t(address); + set_remote_impl(transport, context); +} + +void pn_handle_authentication_service_connection_event(pn_event_t *e) +{ + pn_connection_t *conn = pn_event_connection(e); + if (pn_event_type(e) == PN_CONNECTION_BOUND) { + printf("Handling connection bound event for authentication service connection\n"); + pni_sasl_relay_t* context = get_sasl_relay_context(conn); + context->refcount++; + set_remote_impl(pn_event_transport(e), context); + } else { + printf("Ignoring event for authentication service connection: %s\n", pn_event_type_name(pn_event_type(e))); + } } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/75fc8419/proton-c/src/sasl/sasl-internal.h ---------------------------------------------------------------------- diff --git a/proton-c/src/sasl/sasl-internal.h b/proton-c/src/sasl/sasl-internal.h index 8fef243..8eb4b73 100644 --- a/proton-c/src/sasl/sasl-internal.h +++ b/proton-c/src/sasl/sasl-internal.h @@ -57,10 +57,10 @@ typedef void (*pni_sasl_challenge_response)(pn_transport_t *transport, const pn_ typedef void (*pni_sasl_init)(pn_transport_t *transport, const char *mechanism, const pn_bytes_t *recv); typedef bool (*pni_sasl_set_mechanisms)(pn_transport_t *transport, const char *mechanism); typedef int (*pni_sasl_get_mechanisms)(pn_transport_t *transport, char **mechlist); +typedef void (*pni_sasl_free_function)(pn_transport_t *transport); typedef struct { - pni_sasl_function free; pni_sasl_get_mechanisms get_mechs; pni_sasl_function init_server; pni_sasl_init process_init; @@ -70,10 +70,9 @@ typedef struct pni_sasl_challenge_response process_challenge; pni_sasl_function process_outcome; pni_sasl_function prepare; + pni_sasl_free_function free_impl; } pni_sasl_implementation; -PN_EXTERN void pni_sasl_set_implementation(pni_sasl_implementation); - // Shared SASL API used by the actual SASL authenticators enum pni_sasl_state { SASL_NONE, @@ -89,6 +88,7 @@ enum pni_sasl_state { struct pni_sasl_t { void *impl_context; + pni_sasl_implementation* impl; char *selected_mechanism; char *included_mechanisms; const char *username; @@ -113,5 +113,7 @@ struct pni_sasl_t { void pni_split_mechs(char *mechlist, const char* included_mechs, char *mechs[], int *count); bool pni_included_mech(const char *included_mech_list, pn_bytes_t s); PN_EXTERN void pni_sasl_set_desired_state(pn_transport_t *transport, enum pni_sasl_state desired_state); +PN_EXTERN void pni_sasl_set_implementation(pn_transport_t *transport, pni_sasl_implementation impl, void* context); + #endif /* sasl-internal.h */ http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/75fc8419/proton-c/src/sasl/sasl.c ---------------------------------------------------------------------- diff --git a/proton-c/src/sasl/sasl.c b/proton-c/src/sasl/sasl.c index dcdcd17..cb05d53 100644 --- a/proton-c/src/sasl/sasl.c +++ b/proton-c/src/sasl/sasl.c @@ -136,83 +136,49 @@ static void pni_emit(pn_transport_t *transport) } } -static pni_sasl_implementation* implementation = 0; - -void pni_sasl_set_implementation(pni_sasl_implementation i) +void pni_sasl_set_implementation(pn_transport_t *transport, pni_sasl_implementation i, void* context) { - implementation = (pni_sasl_implementation*) malloc(sizeof(pni_sasl_implementation)); - *implementation = i; + *(transport->sasl->impl) = i; + transport->sasl->impl_context = context; } void pni_sasl_impl_free_(pn_transport_t *transport) { - if (implementation) { - implementation->free(transport); - } else { - pni_sasl_impl_free(transport); - } + transport->sasl->impl->free_impl(transport); } int pni_sasl_impl_list_mechs_(pn_transport_t *transport, char **mechlist) { - if (implementation) { - return implementation->get_mechs(transport, mechlist); - } else { - return pni_sasl_impl_list_mechs(transport, mechlist); - } + return transport->sasl->impl->get_mechs(transport, mechlist); } bool pni_init_server_(pn_transport_t *transport) { - if (implementation) { - return implementation->init_server(transport); - } else { - return pni_init_server(transport); - } + return transport->sasl->impl->init_server(transport); } void pni_process_init_(pn_transport_t *transport, const char *mechanism, const pn_bytes_t *recv) { - if (implementation) { - implementation->process_init(transport, mechanism, recv); - } else { - pni_process_init(transport, mechanism, recv); - } + transport->sasl->impl->process_init(transport, mechanism, recv); } void pni_process_response_(pn_transport_t *transport, const pn_bytes_t *recv) { - if (implementation) { - implementation->process_response(transport, recv); - } else { - pni_process_response(transport, recv); - } + transport->sasl->impl->process_response(transport, recv); } bool pni_init_client_(pn_transport_t *transport) { - if (implementation) { - return implementation->init_client(transport); - } else { - return pni_init_client(transport); - } + return transport->sasl->impl->init_client(transport); } bool pni_process_mechanisms_(pn_transport_t *transport, const char *mechs) { - if (implementation) { - return implementation->process_mechanisms(transport, mechs); - } else { - return pni_process_mechanisms(transport, mechs); - } + return transport->sasl->impl->process_mechanisms(transport, mechs); } void pni_process_challenge_(pn_transport_t *transport, const pn_bytes_t *recv) { - if (implementation) { - implementation->process_challenge(transport, recv); - } else { - pni_process_challenge(transport, recv); - } + transport->sasl->impl->process_challenge(transport, recv); } void pni_sasl_set_desired_state(pn_transport_t *transport, enum pni_sasl_state desired_state) @@ -446,8 +412,8 @@ static ssize_t pn_output_write_sasl(pn_transport_t* transport, unsigned int laye pni_sasl_start_server_if_needed(transport); - if (implementation) { - implementation->prepare(transport);//allow impl to adjust sasl object on the right thread if needed + if (transport->sasl->impl->prepare) { + transport->sasl->impl->prepare(transport);//allow impl to adjust sasl object on the right thread if needed } pni_post_sasl_frame(transport); @@ -562,6 +528,17 @@ pn_sasl_t *pn_sasl(pn_transport_t *transport) const char *sasl_config_path = getenv("PN_SASL_CONFIG_PATH"); sasl->impl_context = NULL; + sasl->impl = (pni_sasl_implementation*) malloc(sizeof(pni_sasl_implementation)); + sasl->impl->free_impl = &pni_sasl_impl_free; + sasl->impl->get_mechs = &pni_sasl_impl_list_mechs; + sasl->impl->init_server = &pni_init_server; + sasl->impl->process_init = &pni_process_init; + sasl->impl->process_response = &pni_process_response; + sasl->impl->init_client = &pni_init_client; + sasl->impl->process_mechanisms = &pni_process_mechanisms; + sasl->impl->process_challenge = &pni_process_challenge; + sasl->impl->process_outcome = 0; + sasl->impl->prepare = 0; sasl->client = !transport->server; sasl->selected_mechanism = NULL; sasl->included_mechanisms = NULL; @@ -594,6 +571,7 @@ void pn_sasl_free(pn_transport_t *transport) if (transport) { pni_sasl_t *sasl = transport->sasl; if (sasl) { + free(sasl->impl); free(sasl->selected_mechanism); free(sasl->included_mechanisms); free(sasl->password); @@ -792,8 +770,8 @@ int pn_do_outcome(pn_transport_t *transport, uint8_t frame_type, uint16_t channe transport->authenticated = authenticated; pni_sasl_set_desired_state(transport, authenticated ? SASL_RECVED_OUTCOME_SUCCEED : SASL_RECVED_OUTCOME_FAIL); - if (implementation) { - implementation->process_outcome(transport); + if (transport->sasl->impl->process_outcome) { + transport->sasl->impl->process_outcome(transport); } return 0; --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org