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 2019/03/14 20:05:33 UTC

[qpid-proton] 04/06: PROTON-2018: [c] Introduce some ssl protocol tests

This is an automated email from the ASF dual-hosted git repository.

astitcher pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-proton.git

commit 2e7b4027ae63471b95d0f2a829a798d3329b395a
Author: Andrew Stitcher <as...@apache.org>
AuthorDate: Thu Mar 7 15:50:08 2019 -0500

    PROTON-2018: [c] Introduce some ssl protocol tests
---
 c/tests/CMakeLists.txt        |   5 +
 c/tests/ssl_proactor_test.cpp | 213 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 218 insertions(+)

diff --git a/c/tests/CMakeLists.txt b/c/tests/CMakeLists.txt
index 502e9a5..3642112 100644
--- a/c/tests/CMakeLists.txt
+++ b/c/tests/CMakeLists.txt
@@ -42,6 +42,8 @@ if (CMAKE_CXX_COMPILER)
     set_target_properties(${exe} PROPERTIES
       COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_WARNING_FLAGS}")
     add_test(NAME ${exe} COMMAND ${test_env} ${TEST_EXE_PREFIX_CMD} $<TARGET_FILE:${exe}>)
+    set_tests_properties(${exe} PROPERTIES
+      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
   endmacro()
 
   ## Tests that depend only on qpid-proton-core
@@ -66,6 +68,9 @@ if (CMAKE_CXX_COMPILER)
     add_c_test(c-proactor-test pn_test_proactor.cpp proactor_test.cpp)
     target_link_libraries(c-proactor-test qpid-proton-core qpid-proton-proactor ${PLATFORM_LIBS})
 
+    add_c_test(c-ssl-proactor-test pn_test_proactor.cpp ssl_proactor_test.cpp)
+    target_link_libraries(c-ssl-proactor-test qpid-proton-core qpid-proton-proactor ${PLATFORM_LIBS})
+
     # Thread race test.
     #
     # TODO aconway 2018-11-14: enable by default when races and xcode
diff --git a/c/tests/ssl_proactor_test.cpp b/c/tests/ssl_proactor_test.cpp
new file mode 100644
index 0000000..c9eafc7
--- /dev/null
+++ b/c/tests/ssl_proactor_test.cpp
@@ -0,0 +1,213 @@
+/*
+ *
+ * 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 "./pn_test_proactor.hpp"
+
+#include <proton/connection.h>
+#include <proton/condition.h>
+#include <proton/delivery.h>
+#include <proton/link.h>
+#include <proton/listener.h>
+#include <proton/netaddr.h>
+#include <proton/proactor.h>
+#include <proton/session.h>
+#include <proton/sasl.h>
+#include <proton/ssl.h>
+#include <proton/transport.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct app_data_t {
+  const char *amqp_address;
+  const char *container_id;
+
+  pn_ssl_domain_t *server_ssl_domain;
+
+  bool connection_succeeded;
+  bool transport_error;
+} app_data_t;
+
+/* Note must be run in the current directory to find certificate files */
+#define SSL_FILE(NAME) "ssl-certs/" NAME
+#define SSL_PW "tclientpw"
+/* Windows vs. OpenSSL certificates */
+#if defined(_WIN32)
+#  define CERTIFICATE(NAME) SSL_FILE(NAME "-certificate.p12")
+#  define SET_CREDENTIALS(DOMAIN, NAME)                                 \
+  pn_ssl_domain_set_credentials(DOMAIN, SSL_FILE(NAME "-full.p12"), "", SSL_PW)
+#else
+#  define CERTIFICATE(NAME) SSL_FILE(NAME "-certificate.pem")
+#  define SET_CREDENTIALS(DOMAIN, NAME)                                 \
+  pn_ssl_domain_set_credentials(DOMAIN, CERTIFICATE(NAME), SSL_FILE(NAME "-private-key.pem"), SSL_PW)
+#endif
+
+
+/* Returns true to continue, false if finished */
+static bool server_handler(app_data_t* app, pn_event_t* event) {
+  pn_listener_t *l = pn_event_listener(event);
+  switch (pn_event_type(event)) {
+
+   // Server side
+   case PN_LISTENER_ACCEPT: {
+     /* Configure a transport to allow SSL and SASL connections. See ssl_domain setup in main() */
+     pn_transport_t *t = pn_transport();
+     pn_transport_set_server(t); /* Must call before pn_sasl() */
+     pn_sasl_allowed_mechs(pn_sasl(t), "ANONYMOUS");
+     if (app->server_ssl_domain) {
+       pn_ssl_init(pn_ssl(t), app->server_ssl_domain, NULL);
+     }
+     pn_listener_accept2(l, NULL, t);
+
+     /* Accept only one connection */
+     pn_listener_close(l);
+     break;
+   }
+
+   case PN_TRANSPORT_CLOSED:
+    break;
+
+   default: break;
+  }
+  return true;
+}
+
+static bool client_handler(app_data_t* app, pn_event_t* event) {
+  switch (pn_event_type(event)) {
+   // Client side
+   case PN_CONNECTION_INIT: {
+     pn_connection_t* c = pn_event_connection(event);
+     pn_session_t* s = pn_session(pn_event_connection(event));
+     pn_connection_set_container(c, app->container_id);
+     pn_connection_open(c);
+     pn_session_open(s);
+     {
+     pn_link_t* l = pn_sender(s, "my_sender");
+     pn_terminus_set_address(pn_link_target(l), app->amqp_address);
+     pn_link_open(l);
+     break;
+     }
+   }
+
+   case PN_CONNECTION_BOUND: {
+     break;
+   }
+
+   case PN_CONNECTION_REMOTE_OPEN:
+    app->connection_succeeded = true;
+    pn_connection_close(pn_event_connection(event));
+    break;
+
+   case PN_TRANSPORT_ERROR:
+    app->transport_error = true;
+    break;
+
+   case PN_CONNECTION_REMOTE_CLOSE:
+    pn_connection_close(pn_event_connection(event));
+    break;
+
+   case PN_SESSION_REMOTE_CLOSE:
+    pn_connection_close(pn_event_connection(event));
+    break;
+
+   case PN_LINK_REMOTE_CLOSE:
+   case PN_LINK_REMOTE_DETACH:
+    pn_connection_close(pn_event_connection(event));
+    break;
+
+   default: break;
+  }
+  return true;
+}
+
+typedef bool handler_t(app_data_t* app, pn_event_t* event);
+void run(pn_proactor_t *p, app_data_t *app, handler_t *shandler, handler_t *chandler) {
+  /* Loop and handle server/client events */
+  do {
+    pn_event_batch_t *events = pn_proactor_wait(p);
+    pn_event_t *e;
+    for (e = pn_event_batch_next(events); e; e = pn_event_batch_next(events)) {
+      if (pn_event_type(e)==PN_PROACTOR_INACTIVE) {
+        return;
+      }
+
+      if (pn_event_listener(e)) {
+        if (!shandler(app, e)) {
+          return;
+        }
+      } else {
+        if (!chandler(app, e)) {
+          return;
+        }
+      }
+    }
+    pn_proactor_done(p, events);
+  } while(true);
+}
+
+TEST_CASE("ssl") {
+  struct app_data_t app = {0};
+
+  app.container_id = "ssl-test";
+  app.amqp_address = "fubar";
+
+  pn_test::auto_free<pn_proactor_t, pn_proactor_free> proactor(pn_proactor());
+
+  /* Configure server for default SSL */
+  pn_test::auto_free<pn_ssl_domain_t, pn_ssl_domain_free>
+    sd(pn_ssl_domain(PN_SSL_MODE_SERVER));
+  app.server_ssl_domain = sd;
+
+  /* Configure a client for SSL */
+  pn_transport_t *t = pn_transport();
+  pn_test::auto_free<pn_ssl_domain_t, pn_ssl_domain_free>
+    cd(pn_ssl_domain(PN_SSL_MODE_CLIENT));
+
+  SECTION("Anonymous connections don't verify") {
+    REQUIRE(pn_ssl_domain_set_trusted_ca_db(cd, CERTIFICATE("tclient")) == 0);
+    REQUIRE(pn_ssl_domain_set_peer_authentication(cd, PN_SSL_VERIFY_PEER_NAME, NULL) == 0);
+    REQUIRE(pn_ssl_init(pn_ssl(t), cd, NULL) == 0);
+
+    pn_proactor_listen(proactor, pn_listener(), "", 16);
+    pn_proactor_connect2(proactor, NULL, t, "");
+
+    run(proactor, &app, server_handler, client_handler);
+    CHECK(app.connection_succeeded==false);
+    CHECK(app.transport_error==true);
+  }
+
+  SECTION("Anonymous connections connect if anonymous allowed") {
+#ifndef _WIN32
+    REQUIRE(pn_ssl_domain_set_peer_authentication(cd, PN_SSL_ANONYMOUS_PEER, NULL) == 0);
+    REQUIRE(pn_ssl_init(pn_ssl(t), cd, NULL) == 0);
+
+    pn_proactor_listen(proactor, pn_listener(), "", 16);
+    pn_proactor_connect2(proactor, NULL, t, "");
+
+    run(proactor, &app, server_handler, client_handler);
+    CHECK(app.connection_succeeded==true);
+    CHECK(app.transport_error==false);
+#else
+    SUCCEED("Skipped: Windows schannel does not support anonymous connections");
+#endif
+  }
+}


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