You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by as...@apache.org on 2017/06/02 22:55:54 UTC

[1/5] qpid-proton git commit: build remote sasl support as a separate library [Forced Update!]

Repository: qpid-proton
Updated Branches:
  refs/heads/PROTON-1488 53b905449 -> 5b69776c2 (forced update)


build remote sasl support as a separate library


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/fe5dffdd
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/fe5dffdd
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/fe5dffdd

Branch: refs/heads/PROTON-1488
Commit: fe5dffddeeaff9f4668904f8b6e07c4eb105d6cf
Parents: 75fc841
Author: Gordon Sim <gs...@redhat.com>
Authored: Thu May 25 14:44:22 2017 +0100
Committer: Gordon Sim <gs...@redhat.com>
Committed: Thu May 25 14:44:45 2017 +0100

----------------------------------------------------------------------
 proton-c/CMakeLists.txt               | 18 ++++++++++++--
 proton-c/include/proton/proactor.h    |  4 ----
 proton-c/include/proton/remote_sasl.h | 38 ++++++++++++++++++++++++++++++
 proton-c/src/ProtonConfig.cmake.in    |  1 +
 proton-c/src/sasl/remote_sasl.c       |  1 +
 5 files changed, 56 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/fe5dffdd/proton-c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/CMakeLists.txt b/proton-c/CMakeLists.txt
index 094fba4..f0688bb 100644
--- a/proton-c/CMakeLists.txt
+++ b/proton-c/CMakeLists.txt
@@ -456,6 +456,7 @@ set (qpid-proton-include
   include/proton/netaddr.h
   include/proton/object.h
   include/proton/proactor.h
+  include/proton/remote_sasl.h
   include/proton/sasl.h
   include/proton/session.h
   include/proton/ssl.h
@@ -486,7 +487,7 @@ if (PROACTOR STREQUAL "epoll" OR (NOT PROACTOR AND NOT BUILD_PROACTOR))
   check_symbol_exists(epoll_wait "sys/epoll.h" HAVE_EPOLL)
   if (HAVE_EPOLL)
     set (PROACTOR_OK epoll)
-    set (qpid-proton-proactor src/proactor/epoll.c src/proactor/proactor-internal.c src/sasl/remote_sasl.c)
+    set (qpid-proton-proactor src/proactor/epoll.c src/proactor/proactor-internal.c)
     set (PROACTOR_LIBS -lpthread)
     set_source_files_properties (${qpid-proton-proactor} PROPERTIES
       COMPILE_FLAGS "${COMPILE_WARNING_FLAGS} ${COMPILE_LANGUAGE_FLAGS} ${LTO}"
@@ -498,7 +499,7 @@ if (PROACTOR STREQUAL "libuv" OR (NOT PROACTOR AND NOT PROACTOR_OK))
   find_package(Libuv)
   if (LIBUV_FOUND)
     set (PROACTOR_OK libuv)
-    set (qpid-proton-proactor src/proactor/libuv.c src/proactor/proactor-internal.c src/sasl/remote_sasl.c)
+    set (qpid-proton-proactor src/proactor/libuv.c src/proactor/proactor-internal.c)
     set (PROACTOR_LIBS ${Libuv_LIBRARIES})
     set_source_files_properties (${qpid-proton-proactor} PROPERTIES
       COMPILE_FLAGS "${COMPILE_WARNING_FLAGS} ${COMPILE_LANGUAGE_FLAGS} ${LTO}"
@@ -623,6 +624,18 @@ if (qpid-proton-proactor)
     SOVERSION "${PN_LIB_SOMAJOR}"
     LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}"
     )
+
+  add_library (qpid-proton-remotesasl SHARED src/sasl/remote_sasl.c)
+  target_link_libraries (qpid-proton-remotesasl LINK_PUBLIC qpid-proton-proactor)
+  target_link_libraries (qpid-proton-remotesasl LINK_PUBLIC qpid-proton-core)
+  list(APPEND LIB_TARGETS qpid-proton-remotesasl)
+  set_target_properties (
+    qpid-proton-remotesasl
+    PROPERTIES
+    VERSION   "${PN_LIB_SOMAJOR}.${PN_LIB_SOMINOR}"
+    SOVERSION "${PN_LIB_SOMAJOR}"
+    LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}"
+    )
 endif()
 
 # Install executables and libraries
@@ -667,6 +680,7 @@ configure_lib(PROTONLIB qpid-proton)
 configure_lib(PROTONCORELIB qpid-proton-core)
 if(HAS_PROACTOR)
   configure_lib(PROTONPROACTORLIB qpid-proton-proactor)
+  configure_lib(PROTONREMOTESASLLIB qpid-proton-remotesasl)
 endif(HAS_PROACTOR)
 
 include(WriteBasicConfigVersionFile)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/fe5dffdd/proton-c/include/proton/proactor.h
----------------------------------------------------------------------
diff --git a/proton-c/include/proton/proactor.h b/proton-c/include/proton/proactor.h
index 978453b..861afbe 100644
--- a/proton-c/include/proton/proactor.h
+++ b/proton-c/include/proton/proactor.h
@@ -285,10 +285,6 @@ 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(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/fe5dffdd/proton-c/include/proton/remote_sasl.h
----------------------------------------------------------------------
diff --git a/proton-c/include/proton/remote_sasl.h b/proton-c/include/proton/remote_sasl.h
new file mode 100644
index 0000000..462d1ec
--- /dev/null
+++ b/proton-c/include/proton/remote_sasl.h
@@ -0,0 +1,38 @@
+#ifndef PROTON_REMOTE_SASL_H
+#define PROTON_REMOTE_SASL_H 1
+
+/*
+ * 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.
+ */
+
+#include <proton/import_export.h>
+#include <proton/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PN_EXPORT void pn_use_remote_authentication_service(pn_transport_t* transport, const char* address);
+PN_EXPORT bool pn_is_authentication_service_connection(pn_connection_t* conn);
+PN_EXPORT void pn_handle_authentication_service_connection_event(pn_event_t *e);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* remote_sasl.h */

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/fe5dffdd/proton-c/src/ProtonConfig.cmake.in
----------------------------------------------------------------------
diff --git a/proton-c/src/ProtonConfig.cmake.in b/proton-c/src/ProtonConfig.cmake.in
index 5b23be0..78bb586 100644
--- a/proton-c/src/ProtonConfig.cmake.in
+++ b/proton-c/src/ProtonConfig.cmake.in
@@ -37,6 +37,7 @@ if (HAS_PROACTOR)
   set (Proton_Proactor_INCLUDE_DIRS  @INCLUDEDIR@)
   set (Proton_Proactor_LIBRARIES     optimized @LIBDIR@/@PROTONPROACTORLIB@ debug @LIBDIR@/@PROTONPROACTORLIBDEBUG@)
   set (Proton_Proactor_FOUND True)
+  set (Proton_Remote_SASL_LIBRARIES     optimized @LIBDIR@/@PROTONREMOTESASLLIB@ debug @LIBDIR@/@PROTONREMOTESASLLIBDEBUG@)
 endif()
 
 # Check for all required components

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/fe5dffdd/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 d799a93..8721a51 100644
--- a/proton-c/src/sasl/remote_sasl.c
+++ b/proton-c/src/sasl/remote_sasl.c
@@ -24,6 +24,7 @@
 #include "core/engine-internal.h"
 #include "core/util.h"
 #include "proton/proactor.h"
+#include "proton/remote_sasl.h"
 
 typedef struct
 {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[4/5] qpid-proton git commit: further WIP

Posted by as...@apache.org.
further WIP


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/52e75d97
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/52e75d97
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/52e75d97

Branch: refs/heads/PROTON-1488
Commit: 52e75d979a98fd67677943da84c496f1490ac99f
Parents: 4894265
Author: Gordon Sim <gs...@redhat.com>
Authored: Wed May 17 20:31:30 2017 +0100
Committer: Gordon Sim <gs...@redhat.com>
Committed: Thu May 25 14:44:45 2017 +0100

----------------------------------------------------------------------
 proton-c/include/proton/proactor.h |  1 +
 proton-c/src/sasl/remote_sasl.c    | 70 ++++++++++++++++++++++++---------
 2 files changed, 53 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/52e75d97/proton-c/include/proton/proactor.h
----------------------------------------------------------------------
diff --git a/proton-c/include/proton/proactor.h b/proton-c/include/proton/proactor.h
index 5dd16f9..761fb86 100644
--- a/proton-c/include/proton/proactor.h
+++ b/proton-c/include/proton/proactor.h
@@ -286,6 +286,7 @@ 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 bool pn_is_authentication_service_connection(pn_connection_t* conn);
 
 /**
  * @defgroup proactor_events Events

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/52e75d97/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 9ef3484..54a96e5 100644
--- a/proton-c/src/sasl/remote_sasl.c
+++ b/proton-c/src/sasl/remote_sasl.c
@@ -96,6 +96,39 @@ void release_pni_sasl_relay_t(pni_sasl_relay_t* instance)
     }
 }
 
+PN_HANDLE(REMOTE_SASL_CTXT)
+
+bool pn_is_authentication_service_connection(pn_connection_t* conn)
+{
+    if (conn) {
+        pn_record_t *r = pn_connection_attachments(conn);
+        return pn_record_has(r, REMOTE_SASL_CTXT);
+    } else {
+        return false;
+    }
+}
+
+pni_sasl_relay_t* get_sasl_relay_context(pn_connection_t* conn)
+{
+    if (conn) {
+        pn_record_t *r = pn_connection_attachments(conn);
+        if (pn_record_has(r, REMOTE_SASL_CTXT)) {
+            return (pni_sasl_relay_t*) pn_record_get(r, REMOTE_SASL_CTXT);
+        } else {
+            return NULL;
+        }
+    } else {
+        return NULL;
+    }
+}
+
+void set_sasl_relay_context(pn_connection_t* conn, pni_sasl_relay_t* context)
+{
+    pn_record_t *r = pn_connection_attachments(conn);
+    pn_record_def(r, REMOTE_SASL_CTXT, PN_VOID);
+    pn_record_set(r, REMOTE_SASL_CTXT, context);
+}
+
 bool remote_init_server(pn_transport_t* transport)
 {
     pn_connection_t* upstream = pn_transport_connection(transport);
@@ -103,6 +136,7 @@ bool remote_init_server(pn_transport_t* transport)
         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;
         impl->upstream = upstream;
@@ -110,10 +144,8 @@ bool remote_init_server(pn_transport_t* transport)
         if (!proactor) return false;
         impl->downstream = pn_connection();
         pn_connection_set_hostname(impl->downstream, pn_connection_get_hostname(upstream));
-        //do I need to explicitly set up sasl? if so how? need to handle connection_bound?
-        //for now just fake it with dummy user
-        pn_connection_set_user(impl->downstream, "dummy");
-        pn_connection_set_context(impl->downstream, transport->sasl->impl_context);//TODO: use record?
+        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);
         return true;
@@ -128,9 +160,15 @@ bool remote_init_client(pn_transport_t* transport)
     //service, need to use the same context as the server side of the
     //connection it is authenticating on behalf of
     pn_connection_t* conn = pn_transport_connection(transport);
-    transport->sasl->impl_context = pn_connection_get_context(conn);
-    ((pni_sasl_relay_t*) transport->sasl->impl_context)->refcount++;
-    return true;
+    pni_sasl_relay_t* impl = get_sasl_relay_context(conn);
+    if (impl) {
+        transport->sasl->impl_context = impl;
+        impl->refcount++;
+        return true;
+    } else {
+        return false;
+        //return pni_init_client(transport);
+    }
 }
 
 bool remote_free(pn_transport_t *transport)
@@ -180,11 +218,9 @@ bool remote_process_mechanisms(pn_transport_t *transport, const char *mechs)
 {
     pni_sasl_relay_t* impl = (pni_sasl_relay_t*) transport->sasl->impl_context;
     if (impl) {
-        if (impl->upstream_state != DOWNSTREAM_MECHANISMS_RECEIVED) {
-            impl->mechlist = pn_strdup(mechs);
-            impl->upstream_state = DOWNSTREAM_MECHANISMS_RECEIVED;
-            pn_connection_wake(impl->upstream);
-        }
+        impl->mechlist = pn_strdup(mechs);
+        impl->upstream_state = DOWNSTREAM_MECHANISMS_RECEIVED;
+        pn_connection_wake(impl->upstream);
         return true;
     } else {
         return false;
@@ -195,7 +231,7 @@ bool remote_process_mechanisms(pn_transport_t *transport, const char *mechs)
 void remote_process_challenge(pn_transport_t *transport, const pn_bytes_t *recv)
 {
     pni_sasl_relay_t* impl = (pni_sasl_relay_t*) transport->sasl->impl_context;
-    if (impl && impl->upstream_state != DOWNSTREAM_CHALLENGE_RECEIVED) {
+    if (impl) {
         pni_copy_bytes(recv, &(impl->challenge));
         impl->upstream_state = DOWNSTREAM_CHALLENGE_RECEIVED;
         pn_connection_wake(impl->upstream);
@@ -207,11 +243,9 @@ bool remote_process_outcome(pn_transport_t *transport)
 {
     pni_sasl_relay_t* impl = (pni_sasl_relay_t*) transport->sasl->impl_context;
     if (impl) {
-        if (impl->upstream_state != DOWNSTREAM_OUTCOME_RECEIVED) {
-            impl->outcome = transport->sasl->outcome;
-            impl->upstream_state = DOWNSTREAM_OUTCOME_RECEIVED;
-            pn_connection_wake(impl->upstream);
-        }
+        impl->outcome = transport->sasl->outcome;
+        impl->upstream_state = DOWNSTREAM_OUTCOME_RECEIVED;
+        pn_connection_wake(impl->upstream);
         return true;
     } else {
         return false;


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[3/5] qpid-proton git commit: WIP: a sasl implementation that delegates to a remote authentication service, using AMQP SASL frame relaying

Posted by as...@apache.org.
WIP: a sasl implementation that delegates to a remote authentication service, using AMQP SASL frame relaying


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/4894265b
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/4894265b
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/4894265b

Branch: refs/heads/PROTON-1488
Commit: 4894265b3d1517f62265907000dfc948cbb1c75d
Parents: d652405
Author: Gordon Sim <gs...@redhat.com>
Authored: Wed May 17 16:19:47 2017 +0100
Committer: Gordon Sim <gs...@redhat.com>
Committed: Thu May 25 14:44:45 2017 +0100

----------------------------------------------------------------------
 proton-c/CMakeLists.txt            |   4 +-
 proton-c/include/proton/proactor.h |   2 +
 proton-c/src/core/util.h           |   2 +-
 proton-c/src/sasl/cyrus_sasl.c     |   9 +-
 proton-c/src/sasl/none_sasl.c      |   5 +
 proton-c/src/sasl/remote_sasl.c    | 271 ++++++++++++++++++++++++++++++++
 proton-c/src/sasl/sasl-internal.h  |  23 ++-
 proton-c/src/sasl/sasl.c           | 122 +++++++++++---
 8 files changed, 414 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4894265b/proton-c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/CMakeLists.txt b/proton-c/CMakeLists.txt
index 33933b8..094fba4 100644
--- a/proton-c/CMakeLists.txt
+++ b/proton-c/CMakeLists.txt
@@ -486,7 +486,7 @@ if (PROACTOR STREQUAL "epoll" OR (NOT PROACTOR AND NOT BUILD_PROACTOR))
   check_symbol_exists(epoll_wait "sys/epoll.h" HAVE_EPOLL)
   if (HAVE_EPOLL)
     set (PROACTOR_OK epoll)
-    set (qpid-proton-proactor src/proactor/epoll.c src/proactor/proactor-internal.c)
+    set (qpid-proton-proactor src/proactor/epoll.c src/proactor/proactor-internal.c src/sasl/remote_sasl.c)
     set (PROACTOR_LIBS -lpthread)
     set_source_files_properties (${qpid-proton-proactor} PROPERTIES
       COMPILE_FLAGS "${COMPILE_WARNING_FLAGS} ${COMPILE_LANGUAGE_FLAGS} ${LTO}"
@@ -498,7 +498,7 @@ if (PROACTOR STREQUAL "libuv" OR (NOT PROACTOR AND NOT PROACTOR_OK))
   find_package(Libuv)
   if (LIBUV_FOUND)
     set (PROACTOR_OK libuv)
-    set (qpid-proton-proactor src/proactor/libuv.c src/proactor/proactor-internal.c)
+    set (qpid-proton-proactor src/proactor/libuv.c src/proactor/proactor-internal.c src/sasl/remote_sasl.c)
     set (PROACTOR_LIBS ${Libuv_LIBRARIES})
     set_source_files_properties (${qpid-proton-proactor} PROPERTIES
       COMPILE_FLAGS "${COMPILE_WARNING_FLAGS} ${COMPILE_LANGUAGE_FLAGS} ${LTO}"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4894265b/proton-c/include/proton/proactor.h
----------------------------------------------------------------------
diff --git a/proton-c/include/proton/proactor.h b/proton-c/include/proton/proactor.h
index 861afbe..5dd16f9 100644
--- a/proton-c/include/proton/proactor.h
+++ b/proton-c/include/proton/proactor.h
@@ -285,6 +285,8 @@ 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);
+
 /**
  * @defgroup proactor_events Events
  *

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4894265b/proton-c/src/core/util.h
----------------------------------------------------------------------
diff --git a/proton-c/src/core/util.h b/proton-c/src/core/util.h
index 4d3ba3b..ee83f90 100644
--- a/proton-c/src/core/util.h
+++ b/proton-c/src/core/util.h
@@ -39,7 +39,7 @@ void pn_print_data(const char *bytes, size_t size);
 bool pn_env_bool(const char *name);
 pn_timestamp_t pn_timestamp_min(pn_timestamp_t a, pn_timestamp_t b);
 
-char *pn_strdup(const char *src);
+PN_EXTERN char *pn_strdup(const char *src);
 char *pn_strndup(const char *src, size_t n);
 int pn_strcasecmp(const char* a, const char* b);
 int pn_strncasecmp(const char* a, const char* b, size_t len);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4894265b/proton-c/src/sasl/cyrus_sasl.c
----------------------------------------------------------------------
diff --git a/proton-c/src/sasl/cyrus_sasl.c b/proton-c/src/sasl/cyrus_sasl.c
index ef1db9d..74e124f 100644
--- a/proton-c/src/sasl/cyrus_sasl.c
+++ b/proton-c/src/sasl/cyrus_sasl.c
@@ -247,6 +247,7 @@ bool pni_process_mechanisms(pn_transport_t *transport, const char *mechs)
         case SASL_OK:
         case SASL_CONTINUE:
           sasl->selected_mechanism = pn_strdup(mech_selected);
+          pni_sasl_set_desired_state(transport, SASL_POSTED_INIT);
           return true;
         case SASL_NOMECH:
         default:
@@ -350,7 +351,13 @@ bool pni_init_server(pn_transport_t* transport)
     }
   } while (false);
   cyrus_conn = (sasl_conn_t*) sasl->impl_context;
-  return pni_check_sasl_result(cyrus_conn, result, transport);
+  if (pni_check_sasl_result(cyrus_conn, result, transport)) {
+      // Setup to send SASL mechanisms frame
+      pni_sasl_set_desired_state(transport, SASL_POSTED_MECHANISMS);
+      return true;
+  } else {
+      return false;
+  }
 }
 
 static int pni_wrap_server_start(pni_sasl_t *sasl, const char *mech_selected, const pn_bytes_t *in)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4894265b/proton-c/src/sasl/none_sasl.c
----------------------------------------------------------------------
diff --git a/proton-c/src/sasl/none_sasl.c b/proton-c/src/sasl/none_sasl.c
index 0408a8f..84a6640 100644
--- a/proton-c/src/sasl/none_sasl.c
+++ b/proton-c/src/sasl/none_sasl.c
@@ -29,6 +29,8 @@ static const char PLAIN[] = "PLAIN";
 
 bool pni_init_server(pn_transport_t* transport)
 {
+  // Setup to send SASL mechanisms frame
+  pni_sasl_set_desired_state(transport, SASL_POSTED_MECHANISMS);
   return true;
 }
 
@@ -67,6 +69,7 @@ bool pni_process_mechanisms(pn_transport_t *transport, const char *mechs)
       transport->sasl->bytes_out.start = empty;
       transport->sasl->bytes_out.size =  0;
     }
+    pni_sasl_set_desired_state(transport, SASL_POSTED_INIT);
     return true;
   }
 
@@ -98,6 +101,7 @@ bool pni_process_mechanisms(pn_transport_t *transport, const char *mechs)
     free(memset(transport->sasl->password, 0, psize));
     transport->sasl->password = NULL;
 
+    pni_sasl_set_desired_state(transport, SASL_POSTED_INIT);
     return true;
   }
 
@@ -122,6 +126,7 @@ bool pni_process_mechanisms(pn_transport_t *transport, const char *mechs)
       transport->sasl->bytes_out.start = anon;
       transport->sasl->bytes_out.size =  sizeof anon-1;
     }
+    pni_sasl_set_desired_state(transport, SASL_POSTED_INIT);
     return true;
   }
   return false;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4894265b/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
new file mode 100644
index 0000000..9ef3484
--- /dev/null
+++ b/proton-c/src/sasl/remote_sasl.c
@@ -0,0 +1,271 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include "sasl-internal.h"
+
+#include "core/engine-internal.h"
+#include "core/util.h"
+#include "proton/proactor.h"
+
+typedef struct
+{
+    size_t size;
+    char *start;
+} pni_owned_bytes_t;
+
+const int8_t UPSTREAM_INIT_RECEIVED = 1;
+const int8_t UPSTREAM_RESPONSE_RECEIVED = 2;
+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
+{
+    pn_connection_t* downstream;
+    char* selected_mechanism;
+    pni_owned_bytes_t response;
+    int8_t downstream_state;
+
+    pn_connection_t* upstream;
+    char* mechlist;
+    pni_owned_bytes_t challenge;
+    int8_t upstream_state;
+
+    pn_sasl_outcome_t outcome;
+    int refcount;
+} pni_sasl_relay_t;
+
+void pni_copy_bytes(const pn_bytes_t* from, pni_owned_bytes_t* to)
+{
+    if (to->start) {
+        free(to->start);
+    }
+    to->start = (char*) malloc(from->size);
+    to->size = from->size;
+    memcpy(to->start, from->start, from->size);
+}
+
+pni_sasl_relay_t* new_pni_sasl_relay_t(void)
+{
+    pni_sasl_relay_t* instance = (pni_sasl_relay_t*) malloc(sizeof(pni_sasl_relay_t));
+    instance->selected_mechanism = 0;
+    instance->response.start = 0;
+    instance->response.size = 0;
+    instance->mechlist = 0;
+    instance->challenge.start = 0;
+    instance->challenge.size = 0;
+    instance->refcount = 1;
+    instance->upstream_state = 0;
+    instance->downstream_state = 0;
+    return instance;
+}
+
+void delete_pni_sasl_relay_t(pni_sasl_relay_t* instance)
+{
+    if (instance->mechlist) free(instance->mechlist);
+    if (instance->selected_mechanism) free(instance->selected_mechanism);
+    if (instance->response.start) free(instance->response.start);
+    if (instance->challenge.start) free(instance->challenge.start);
+    free(instance);
+}
+
+void release_pni_sasl_relay_t(pni_sasl_relay_t* instance)
+{
+    if (instance && --(instance->refcount) == 0) {
+        delete_pni_sasl_relay_t(instance);
+    }
+}
+
+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;
+        }
+        pni_sasl_relay_t* impl = new_pni_sasl_relay_t();
+        transport->sasl->impl_context = impl;
+        impl->upstream = upstream;
+        pn_proactor_t* proactor = pn_connection_proactor(upstream);
+        if (!proactor) return false;
+        impl->downstream = pn_connection();
+        pn_connection_set_hostname(impl->downstream, pn_connection_get_hostname(upstream));
+        //do I need to explicitly set up sasl? if so how? need to handle connection_bound?
+        //for now just fake it with dummy user
+        pn_connection_set_user(impl->downstream, "dummy");
+        pn_connection_set_context(impl->downstream, transport->sasl->impl_context);//TODO: use record?
+
+        pn_proactor_connect(proactor, impl->downstream, authentication_service_address);
+        return true;
+    } else {
+        return false;
+    }
+}
+
+bool remote_init_client(pn_transport_t* transport)
+{
+    //for the client side of the connection to the authentication
+    //service, need to use the same context as the server side of the
+    //connection it is authenticating on behalf of
+    pn_connection_t* conn = pn_transport_connection(transport);
+    transport->sasl->impl_context = pn_connection_get_context(conn);
+    ((pni_sasl_relay_t*) transport->sasl->impl_context)->refcount++;
+    return true;
+}
+
+bool 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;
+    }
+}
+
+bool remote_prepare(pn_transport_t *transport)
+{
+    pni_sasl_relay_t* impl = (pni_sasl_relay_t*) transport->sasl->impl_context;
+    if (!impl) return false;
+    if (transport->sasl->client) {
+        if (impl->downstream_state == UPSTREAM_INIT_RECEIVED) {
+            transport->sasl->selected_mechanism = impl->selected_mechanism;
+            transport->sasl->bytes_out.start = impl->response.start;
+            transport->sasl->bytes_out.size = impl->response.size;
+            pni_sasl_set_desired_state(transport, SASL_POSTED_INIT);
+        } else if (impl->downstream_state == UPSTREAM_RESPONSE_RECEIVED) {
+            transport->sasl->bytes_out.start = impl->response.start;
+            transport->sasl->bytes_out.size = impl->response.size;
+            pni_sasl_set_desired_state(transport, SASL_POSTED_RESPONSE);
+        }
+        impl->downstream_state = 0;
+    } else {
+        if (impl->upstream_state == DOWNSTREAM_MECHANISMS_RECEIVED) {
+            pni_sasl_set_desired_state(transport, SASL_POSTED_MECHANISMS);
+        } else if (impl->upstream_state == DOWNSTREAM_CHALLENGE_RECEIVED) {
+            transport->sasl->bytes_out.start = impl->challenge.start;
+            transport->sasl->bytes_out.size = impl->challenge.size;
+            pni_sasl_set_desired_state(transport, SASL_POSTED_CHALLENGE);
+        } else if (impl->upstream_state == DOWNSTREAM_OUTCOME_RECEIVED) {
+            transport->sasl->outcome = impl->outcome;
+            pni_sasl_set_desired_state(transport, SASL_POSTED_OUTCOME);
+        }
+        impl->upstream_state = 0;
+    }
+    return true;
+}
+
+// Client / Downstream
+bool remote_process_mechanisms(pn_transport_t *transport, const char *mechs)
+{
+    pni_sasl_relay_t* impl = (pni_sasl_relay_t*) transport->sasl->impl_context;
+    if (impl) {
+        if (impl->upstream_state != DOWNSTREAM_MECHANISMS_RECEIVED) {
+            impl->mechlist = pn_strdup(mechs);
+            impl->upstream_state = DOWNSTREAM_MECHANISMS_RECEIVED;
+            pn_connection_wake(impl->upstream);
+        }
+        return true;
+    } else {
+        return false;
+    }
+}
+
+// Client / Downstream
+void remote_process_challenge(pn_transport_t *transport, const pn_bytes_t *recv)
+{
+    pni_sasl_relay_t* impl = (pni_sasl_relay_t*) transport->sasl->impl_context;
+    if (impl && impl->upstream_state != DOWNSTREAM_CHALLENGE_RECEIVED) {
+        pni_copy_bytes(recv, &(impl->challenge));
+        impl->upstream_state = DOWNSTREAM_CHALLENGE_RECEIVED;
+        pn_connection_wake(impl->upstream);
+    }
+}
+
+// Client / Downstream
+bool remote_process_outcome(pn_transport_t *transport)
+{
+    pni_sasl_relay_t* impl = (pni_sasl_relay_t*) transport->sasl->impl_context;
+    if (impl) {
+        if (impl->upstream_state != DOWNSTREAM_OUTCOME_RECEIVED) {
+            impl->outcome = transport->sasl->outcome;
+            impl->upstream_state = DOWNSTREAM_OUTCOME_RECEIVED;
+            pn_connection_wake(impl->upstream);
+        }
+        return true;
+    } else {
+        return false;
+    }
+}
+
+// Server / Upstream
+int remote_get_mechs(pn_transport_t *transport, char **mechlist)
+{
+    pni_sasl_relay_t* impl = (pni_sasl_relay_t*) transport->sasl->impl_context;
+    if (impl && impl->mechlist) {
+        *mechlist = pn_strdup(impl->mechlist);
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+// Server / Upstream
+void remote_process_init(pn_transport_t *transport, const char *mechanism, const pn_bytes_t *recv)
+{
+    pni_sasl_relay_t* impl = (pni_sasl_relay_t*) transport->sasl->impl_context;
+    if (impl) {
+        impl->selected_mechanism = pn_strdup(mechanism);
+        pni_copy_bytes(recv, &(impl->response));
+        impl->downstream_state = UPSTREAM_INIT_RECEIVED;
+        pn_connection_wake(impl->downstream);
+    }
+}
+
+// Server / Upstream
+void remote_process_response(pn_transport_t *transport, const pn_bytes_t *recv)
+{
+    pni_sasl_relay_t* impl = (pni_sasl_relay_t*) transport->sasl->impl_context;
+    if (impl) {
+        pni_copy_bytes(recv, &(impl->response));
+        impl->downstream_state = UPSTREAM_RESPONSE_RECEIVED;
+        pn_connection_wake(impl->downstream);
+    }
+}
+
+void pn_use_remote_authentication_service(const char* address)
+{
+    authentication_service_address = address;
+    pni_sasl_implementation remote_impl;
+    remote_impl.free = &remote_free;
+    remote_impl.get_mechs = &remote_get_mechs;
+    remote_impl.init_server = &remote_init_server;
+    remote_impl.process_init = &remote_process_init;
+    remote_impl.process_response = &remote_process_response;
+    remote_impl.init_client = &remote_init_client;
+    remote_impl.process_mechanisms = &remote_process_mechanisms;
+    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);
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4894265b/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 2873777..8fef243 100644
--- a/proton-c/src/sasl/sasl-internal.h
+++ b/proton-c/src/sasl/sasl-internal.h
@@ -52,6 +52,27 @@ ssize_t pni_sasl_impl_max_encrypt_size(pn_transport_t *transport);
 ssize_t pni_sasl_impl_encode(pn_transport_t *transport, pn_bytes_t in, pn_bytes_t *out);
 ssize_t pni_sasl_impl_decode(pn_transport_t *transport, pn_bytes_t in, pn_bytes_t *out);
 
+typedef bool (*pni_sasl_function)(pn_transport_t *transport);
+typedef void (*pni_sasl_challenge_response)(pn_transport_t *transport, const pn_bytes_t *recv);
+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 struct
+{
+    pni_sasl_function free;
+    pni_sasl_get_mechanisms get_mechs;
+    pni_sasl_function init_server;
+    pni_sasl_init process_init;
+    pni_sasl_challenge_response process_response;
+    pni_sasl_function init_client;
+    pni_sasl_set_mechanisms process_mechanisms;
+    pni_sasl_challenge_response process_challenge;
+    pni_sasl_function process_outcome;
+    pni_sasl_function prepare;
+} 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 {
@@ -91,6 +112,6 @@ struct pni_sasl_t {
 // Shared Utility used by sasl implementations
 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);
-void pni_sasl_set_desired_state(pn_transport_t *transport, enum pni_sasl_state desired_state);
+PN_EXTERN void pni_sasl_set_desired_state(pn_transport_t *transport, enum pni_sasl_state desired_state);
 
 #endif /* sasl-internal.h */

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4894265b/proton-c/src/sasl/sasl.c
----------------------------------------------------------------------
diff --git a/proton-c/src/sasl/sasl.c b/proton-c/src/sasl/sasl.c
index 55c489d..dcdcd17 100644
--- a/proton-c/src/sasl/sasl.c
+++ b/proton-c/src/sasl/sasl.c
@@ -136,6 +136,85 @@ static void pni_emit(pn_transport_t *transport)
   }
 }
 
+static pni_sasl_implementation* implementation = 0;
+
+void pni_sasl_set_implementation(pni_sasl_implementation i)
+{
+  implementation = (pni_sasl_implementation*) malloc(sizeof(pni_sasl_implementation));
+  *implementation = i;
+}
+
+void pni_sasl_impl_free_(pn_transport_t *transport)
+{
+  if (implementation) {
+    implementation->free(transport);
+  } else {
+    pni_sasl_impl_free(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);
+  }
+}
+
+bool pni_init_server_(pn_transport_t *transport)
+{
+  if (implementation) {
+    return implementation->init_server(transport);
+  } else {
+    return pni_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);
+  }
+}
+
+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);
+  }
+}
+
+bool pni_init_client_(pn_transport_t *transport)
+{
+  if (implementation) {
+    return implementation->init_client(transport);
+  } else {
+    return pni_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);
+  }
+}
+
+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);
+  }
+}
+
 void pni_sasl_set_desired_state(pn_transport_t *transport, enum pni_sasl_state desired_state)
 {
   pni_sasl_t *sasl = transport->sasl;
@@ -157,9 +236,10 @@ void pni_sasl_set_desired_state(pn_transport_t *transport, enum pni_sasl_state d
     if (sasl->last_state==desired_state && desired_state==SASL_POSTED_CHALLENGE) {
       sasl->last_state = SASL_POSTED_MECHANISMS;
     }
+    bool changed = sasl->desired_state != desired_state;
     sasl->desired_state = desired_state;
     // Don't emit transport event on error as there will be a TRANSPORT_ERROR event
-    if (desired_state != SASL_ERROR) pni_emit(transport);
+    if (desired_state != SASL_ERROR && changed) pni_emit(transport);
   }
 }
 
@@ -182,7 +262,7 @@ static void pni_post_sasl_frame(pn_transport_t *transport)
       char *mechlist = NULL;
 
       int count = 0;
-      if (pni_sasl_impl_list_mechs(transport, &mechlist) > 0) {
+      if (pni_sasl_impl_list_mechs_(transport, &mechlist) > 0) {
         pni_split_mechs(mechlist, sasl->included_mechanisms, mechs, &count);
       }
 
@@ -192,16 +272,19 @@ static void pni_post_sasl_frame(pn_transport_t *transport)
       break;
     }
     case SASL_POSTED_RESPONSE:
-      pn_post_frame(transport, SASL_FRAME_TYPE, 0, "DL[z]", SASL_RESPONSE, out.size, out.start);
-      pni_emit(transport);
+      if (sasl->last_state != SASL_POSTED_RESPONSE) {
+          pn_post_frame(transport, SASL_FRAME_TYPE, 0, "DL[z]", SASL_RESPONSE, out.size, out.start);
+          pni_emit(transport);
+      }
       break;
     case SASL_POSTED_CHALLENGE:
       if (sasl->last_state < SASL_POSTED_MECHANISMS) {
         desired_state = SASL_POSTED_MECHANISMS;
         continue;
+      } else if (sasl->last_state != SASL_POSTED_CHALLENGE) {
+          pn_post_frame(transport, SASL_FRAME_TYPE, 0, "DL[z]", SASL_CHALLENGE, out.size, out.start);
+          pni_emit(transport);
       }
-      pn_post_frame(transport, SASL_FRAME_TYPE, 0, "DL[z]", SASL_CHALLENGE, out.size, out.start);
-      pni_emit(transport);
       break;
     case SASL_POSTED_OUTCOME:
       if (sasl->last_state < SASL_POSTED_MECHANISMS) {
@@ -277,10 +360,7 @@ static void pni_sasl_start_server_if_needed(pn_transport_t *transport)
 {
   pni_sasl_t *sasl = transport->sasl;
   if (!sasl->client && sasl->desired_state<SASL_POSTED_MECHANISMS) {
-    if (!pni_init_server(transport)) return;
-
-    // Setup to send SASL mechanisms frame
-    pni_sasl_set_desired_state(transport, SASL_POSTED_MECHANISMS);
+    if (!pni_init_server_(transport)) return;
   }
 }
 
@@ -366,6 +446,9 @@ 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
+  }
   pni_post_sasl_frame(transport);
 
   if (transport->available != 0 || !pni_sasl_is_final_output_state(sasl)) {
@@ -520,7 +603,7 @@ void pn_sasl_free(pn_transport_t *transport)
 
       // CYRUS_SASL
       if (sasl->impl_context) {
-          pni_sasl_impl_free(transport);
+          pni_sasl_impl_free_(transport);
       }
       pn_buffer_free(sasl->decoded_buffer);
       pn_buffer_free(sasl->encoded_buffer);
@@ -620,7 +703,7 @@ int pn_do_init(pn_transport_t *transport, uint8_t frame_type, uint16_t channel,
   if (err) return err;
   sasl->selected_mechanism = pn_strndup(mech.start, mech.size);
 
-  pni_process_init(transport, sasl->selected_mechanism, &recv);
+  pni_process_init_(transport, sasl->selected_mechanism, &recv);
 
   return 0;
 }
@@ -661,11 +744,9 @@ int pn_do_mechanisms(pn_transport_t *transport, uint8_t frame_type, uint16_t cha
     pn_string_setn(mechs, symbol.start, symbol.size);
   }
 
-  if (pni_init_client(transport) &&
+  if (!(pni_init_client_(transport) &&
       pn_string_size(mechs) &&
-      pni_process_mechanisms(transport, pn_string_get(mechs))) {
-    pni_sasl_set_desired_state(transport, SASL_POSTED_INIT);
-  } else {
+      pni_process_mechanisms_(transport, pn_string_get(mechs)))) {
     sasl->outcome = PN_SASL_PERM;
     pni_sasl_set_desired_state(transport, SASL_RECVED_OUTCOME_FAIL);
   }
@@ -681,7 +762,7 @@ int pn_do_challenge(pn_transport_t *transport, uint8_t frame_type, uint16_t chan
   int err = pn_data_scan(args, "D.[z]", &recv);
   if (err) return err;
 
-  pni_process_challenge(transport, &recv);
+  pni_process_challenge_(transport, &recv);
 
   return 0;
 }
@@ -693,7 +774,7 @@ int pn_do_response(pn_transport_t *transport, uint8_t frame_type, uint16_t chann
   int err = pn_data_scan(args, "D.[z]", &recv);
   if (err) return err;
 
-  pni_process_response(transport, &recv);
+  pni_process_response_(transport, &recv);
 
   return 0;
 }
@@ -711,7 +792,10 @@ 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);
+  }
+
   return 0;
 }
 
-


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[5/5] qpid-proton git commit: handle connection closing, cleanup freeing

Posted by as...@apache.org.
handle connection closing, cleanup freeing


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/5b69776c
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/5b69776c
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/5b69776c

Branch: refs/heads/PROTON-1488
Commit: 5b69776c2c4d73354144e29ea2dad35c1c57ee2d
Parents: fe5dffd
Author: Gordon Sim <gs...@redhat.com>
Authored: Tue May 30 21:12:57 2017 +0100
Committer: Gordon Sim <gs...@redhat.com>
Committed: Tue May 30 21:12:57 2017 +0100

----------------------------------------------------------------------
 proton-c/src/sasl/remote_sasl.c | 119 ++++++++++++++++++++++++++---------
 proton-c/src/sasl/sasl.c        |   2 +-
 2 files changed, 92 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5b69776c/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 8721a51..55d02d2 100644
--- a/proton-c/src/sasl/remote_sasl.c
+++ b/proton-c/src/sasl/remote_sasl.c
@@ -37,6 +37,7 @@ const int8_t UPSTREAM_RESPONSE_RECEIVED = 2;
 const int8_t DOWNSTREAM_MECHANISMS_RECEIVED = 3;
 const int8_t DOWNSTREAM_CHALLENGE_RECEIVED = 4;
 const int8_t DOWNSTREAM_OUTCOME_RECEIVED = 5;
+const int8_t DOWNSTREAM_CLOSED = 6;
 
 typedef struct
 {
@@ -46,14 +47,16 @@ typedef struct
     char* selected_mechanism;
     pni_owned_bytes_t response;
     int8_t downstream_state;
+    bool downstream_released;
 
     pn_connection_t* upstream;
     char* mechlist;
     pni_owned_bytes_t challenge;
     int8_t upstream_state;
+    bool upstream_released;
 
+    bool complete;
     pn_sasl_outcome_t outcome;
-    int refcount;
 } pni_sasl_relay_t;
 
 void pni_copy_bytes(const pn_bytes_t* from, pni_owned_bytes_t* to)
@@ -76,9 +79,13 @@ pni_sasl_relay_t* new_pni_sasl_relay_t(const char* address)
     instance->mechlist = 0;
     instance->challenge.start = 0;
     instance->challenge.size = 0;
-    instance->refcount = 1;
     instance->upstream_state = 0;
     instance->downstream_state = 0;
+    instance->upstream_released = false;
+    instance->downstream_released = false;
+    instance->complete = false;
+    instance->upstream = 0;
+    instance->downstream = 0;
     return instance;
 }
 
@@ -89,14 +96,11 @@ void delete_pni_sasl_relay_t(pni_sasl_relay_t* instance)
     if (instance->selected_mechanism) free(instance->selected_mechanism);
     if (instance->response.start) free(instance->response.start);
     if (instance->challenge.start) free(instance->challenge.start);
-    free(instance);
-}
-
-void release_pni_sasl_relay_t(pni_sasl_relay_t* instance)
-{
-    if (instance && --(instance->refcount) == 0) {
-        delete_pni_sasl_relay_t(instance);
+    if (instance->downstream) {
+        pn_connection_release(instance->downstream);
+        instance->downstream = 0;
     }
+    free(instance);
 }
 
 PN_HANDLE(REMOTE_SASL_CTXT)
@@ -162,18 +166,31 @@ bool remote_init_client(pn_transport_t* transport)
     pni_sasl_relay_t* impl = get_sasl_relay_context(conn);
     if (impl) {
         transport->sasl->impl_context = impl;
-        impl->refcount++;
         return true;
     } else {
         return false;
-        //return pni_init_client(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);
+    pni_sasl_relay_t* impl = (pni_sasl_relay_t*) transport->sasl->impl_context;
+    if (impl) {
+        if (transport->sasl->client) {
+            impl->downstream_released = true;
+            if (impl->upstream_released) {
+                delete_pni_sasl_relay_t(impl);
+            } else {
+                pn_connection_wake(impl->upstream);
+            }
+        } else {
+            impl->upstream_released = true;
+            if (impl->downstream_released) {
+                delete_pni_sasl_relay_t(impl);
+            } else {
+                pn_connection_wake(impl->downstream);
+            }
+        }
     }
 }
 
@@ -183,7 +200,7 @@ bool remote_prepare(pn_transport_t *transport)
     if (!impl) return false;
     if (transport->sasl->client) {
         if (impl->downstream_state == UPSTREAM_INIT_RECEIVED) {
-            transport->sasl->selected_mechanism = impl->selected_mechanism;
+            transport->sasl->selected_mechanism = pn_strdup(impl->selected_mechanism);
             transport->sasl->bytes_out.start = impl->response.start;
             transport->sasl->bytes_out.size = impl->response.size;
             pni_sasl_set_desired_state(transport, SASL_POSTED_INIT);
@@ -209,15 +226,40 @@ bool remote_prepare(pn_transport_t *transport)
     return true;
 }
 
+bool notify_upstream(pni_sasl_relay_t* impl, uint8_t state)
+{
+    if (!impl->upstream_released) {
+        impl->upstream_state = state;
+        pn_connection_wake(impl->upstream);
+        return true;
+    } else {
+        return false;
+    }
+}
+
+bool notify_downstream(pni_sasl_relay_t* impl, uint8_t state)
+{
+    if (!impl->downstream_released) {
+        impl->downstream_state = state;
+        pn_connection_wake(impl->downstream);
+        return true;
+    } else {
+        return false;
+    }
+}
+
 // Client / Downstream
 bool remote_process_mechanisms(pn_transport_t *transport, const char *mechs)
 {
     pni_sasl_relay_t* impl = (pni_sasl_relay_t*) transport->sasl->impl_context;
     if (impl) {
         impl->mechlist = pn_strdup(mechs);
-        impl->upstream_state = DOWNSTREAM_MECHANISMS_RECEIVED;
-        pn_connection_wake(impl->upstream);
-        return true;
+        if (notify_upstream(impl, DOWNSTREAM_MECHANISMS_RECEIVED)) {
+            return true;
+        } else {
+            pni_sasl_set_desired_state(transport, SASL_ERROR);
+            return false;
+        }
     } else {
         return false;
     }
@@ -229,8 +271,9 @@ void remote_process_challenge(pn_transport_t *transport, const pn_bytes_t *recv)
     pni_sasl_relay_t* impl = (pni_sasl_relay_t*) transport->sasl->impl_context;
     if (impl) {
         pni_copy_bytes(recv, &(impl->challenge));
-        impl->upstream_state = DOWNSTREAM_CHALLENGE_RECEIVED;
-        pn_connection_wake(impl->upstream);
+        if (!notify_upstream(impl, DOWNSTREAM_CHALLENGE_RECEIVED)) {
+            pni_sasl_set_desired_state(transport, SASL_ERROR);
+        }
     }
 }
 
@@ -240,8 +283,13 @@ bool remote_process_outcome(pn_transport_t *transport)
     pni_sasl_relay_t* impl = (pni_sasl_relay_t*) transport->sasl->impl_context;
     if (impl) {
         impl->outcome = transport->sasl->outcome;
-        impl->upstream_state = DOWNSTREAM_OUTCOME_RECEIVED;
-        pn_connection_wake(impl->upstream);
+        impl->complete = true;
+        if (notify_upstream(impl, DOWNSTREAM_OUTCOME_RECEIVED)) {
+            return true;
+        } else {
+            pni_sasl_set_desired_state(transport, SASL_ERROR);
+            return false;
+        }
         return true;
     } else {
         return false;
@@ -267,8 +315,9 @@ void remote_process_init(pn_transport_t *transport, const char *mechanism, const
     if (impl) {
         impl->selected_mechanism = pn_strdup(mechanism);
         pni_copy_bytes(recv, &(impl->response));
-        impl->downstream_state = UPSTREAM_INIT_RECEIVED;
-        pn_connection_wake(impl->downstream);
+        if (!notify_downstream(impl, UPSTREAM_INIT_RECEIVED)) {
+            pni_sasl_set_desired_state(transport, SASL_ERROR);
+        }
     }
 }
 
@@ -278,8 +327,9 @@ void remote_process_response(pn_transport_t *transport, const pn_bytes_t *recv)
     pni_sasl_relay_t* impl = (pni_sasl_relay_t*) transport->sasl->impl_context;
     if (impl) {
         pni_copy_bytes(recv, &(impl->response));
-        impl->downstream_state = UPSTREAM_RESPONSE_RECEIVED;
-        pn_connection_wake(impl->downstream);
+        if (!notify_downstream(impl, UPSTREAM_RESPONSE_RECEIVED)) {
+            pni_sasl_set_desired_state(transport, SASL_ERROR);
+        }
     }
 }
 
@@ -308,12 +358,25 @@ void pn_use_remote_authentication_service(pn_transport_t *transport, const char*
 void pn_handle_authentication_service_connection_event(pn_event_t *e)
 {
     pn_connection_t *conn = pn_event_connection(e);
+    pn_transport_t *transport = pn_event_transport(e);
     if (pn_event_type(e) == PN_CONNECTION_BOUND) {
-        printf("Handling connection bound event for authentication service connection\n");
+        pn_transport_logf(transport, "Handling connection bound event for authentication service connection");
         pni_sasl_relay_t* context = get_sasl_relay_context(conn);
-        context->refcount++;
         set_remote_impl(pn_event_transport(e), context);
+    } else if (pn_event_type(e) == PN_CONNECTION_REMOTE_OPEN) {
+        pn_transport_logf(transport, "authentication against service complete; closing connection");
+        pn_connection_close(conn);
+    } else if (pn_event_type(e) == PN_CONNECTION_REMOTE_CLOSE) {
+        pn_transport_logf(transport, "authentication service closed connection");
+        pn_connection_close(conn);
+        pn_transport_close_head(transport);
+    } else if (pn_event_type(e) == PN_TRANSPORT_CLOSED) {
+        pn_transport_logf(transport, "disconnected from authentication service");
+        pni_sasl_relay_t* impl = (pni_sasl_relay_t*) transport->sasl->impl_context;
+        if (!impl->complete) {
+            notify_upstream(impl, DOWNSTREAM_CLOSED);
+        }
     } else {
-        printf("Ignoring event for authentication service connection: %s\n", pn_event_type_name(pn_event_type(e)));
+        pn_transport_logf(transport, "Ignoring event for authentication service connection: %s", pn_event_type_name(pn_event_type(e)));
     }
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5b69776c/proton-c/src/sasl/sasl.c
----------------------------------------------------------------------
diff --git a/proton-c/src/sasl/sasl.c b/proton-c/src/sasl/sasl.c
index cb05d53..6625948 100644
--- a/proton-c/src/sasl/sasl.c
+++ b/proton-c/src/sasl/sasl.c
@@ -571,7 +571,6 @@ 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);
@@ -583,6 +582,7 @@ void pn_sasl_free(pn_transport_t *transport)
       if (sasl->impl_context) {
           pni_sasl_impl_free_(transport);
       }
+      free(sasl->impl);
       pn_buffer_free(sasl->decoded_buffer);
       pn_buffer_free(sasl->encoded_buffer);
       free(sasl);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[2/5] qpid-proton git commit: allow sasl implementation to be selected per connection

Posted by as...@apache.org.
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 <gs...@redhat.com>
Authored: Thu May 25 12:18:10 2017 +0100
Committer: Gordon Sim <gs...@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-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org