Commit 7c400375 authored by Dominik Charousset's avatar Dominik Charousset

Bundle auth_success and auth_failure

parent 1e81bfb5
...@@ -77,6 +77,10 @@ if(NOT CAF_NO_OPENCL) ...@@ -77,6 +77,10 @@ if(NOT CAF_NO_OPENCL)
set(CAF_NO_OPENCL no) set(CAF_NO_OPENCL no)
endif() endif()
if(NOT CAF_NO_OPENSSL)
set(CAF_NO_OPENSSL no)
endif()
if(NOT CAF_NO_PYTHON) if(NOT CAF_NO_PYTHON)
set(CAF_NO_PYTHON no) set(CAF_NO_PYTHON no)
endif() endif()
...@@ -495,11 +499,15 @@ add_caf_lib(core) ...@@ -495,11 +499,15 @@ add_caf_lib(core)
add_optional_caf_lib(io) add_optional_caf_lib(io)
# build SSL module if OpenSSL library is available # build SSL module if OpenSSL library is available
find_package(OpenSSL) if(NOT CAF_NO_OPENSSL)
if(OPENSSL_FOUND) find_package(OpenSSL)
include_directories(BEFORE ${OPENSSL_INCLUDE_DIR}) if(OPENSSL_FOUND)
add_optional_caf_lib(openssl) include_directories(BEFORE ${OPENSSL_INCLUDE_DIR})
endif(OPENSSL_FOUND) add_optional_caf_lib(openssl)
else(OPENSSL_FOUND)
set(CAF_NO_OPENSSL yes)
endif(OPENSSL_FOUND)
endif()
# build opencl library if not told otherwise and OpenCL package was found # build opencl library if not told otherwise and OpenCL package was found
if(NOT CAF_NO_OPENCL) if(NOT CAF_NO_OPENCL)
...@@ -507,6 +515,8 @@ if(NOT CAF_NO_OPENCL) ...@@ -507,6 +515,8 @@ if(NOT CAF_NO_OPENCL)
if(OpenCL_FOUND) if(OpenCL_FOUND)
add_optional_caf_lib(opencl) add_optional_caf_lib(opencl)
add_optional_caf_binaries(libcaf_opencl/examples) add_optional_caf_binaries(libcaf_opencl/examples)
else()
set(CAF_NO_OPENCL yes)
endif() endif()
endif() endif()
...@@ -689,6 +699,7 @@ invertYesNo(CAF_NO_EXCEPTIONS CAF_BUILD_WITH_EXCEPTIONS) ...@@ -689,6 +699,7 @@ invertYesNo(CAF_NO_EXCEPTIONS CAF_BUILD_WITH_EXCEPTIONS)
invertYesNo(CAF_NO_MEM_MANAGEMENT CAF_BUILD_MEM_MANAGEMENT) invertYesNo(CAF_NO_MEM_MANAGEMENT CAF_BUILD_MEM_MANAGEMENT)
invertYesNo(CAF_NO_BENCHMARKS CAF_BUILD_BENCHMARKS) invertYesNo(CAF_NO_BENCHMARKS CAF_BUILD_BENCHMARKS)
invertYesNo(CAF_NO_OPENCL CAF_BUILD_OPENCL) invertYesNo(CAF_NO_OPENCL CAF_BUILD_OPENCL)
invertYesNo(CAF_NO_OPENSSL CAF_BUILD_OPENSSL)
invertYesNo(CAF_NO_PYTHON CAF_BUILD_PYTHON) invertYesNo(CAF_NO_PYTHON CAF_BUILD_PYTHON)
# collect all compiler flags # collect all compiler flags
string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPER_BUILD_TYPE) string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPER_BUILD_TYPE)
...@@ -713,7 +724,8 @@ if(NOT CAF_NO_SUMMARY) ...@@ -713,7 +724,8 @@ if(NOT CAF_NO_SUMMARY)
"\nBuild examples: ${CAF_BUILD_EXAMPLES}" "\nBuild examples: ${CAF_BUILD_EXAMPLES}"
"\nBuild unit tests: ${CAF_BUILD_UNIT_TESTS}" "\nBuild unit tests: ${CAF_BUILD_UNIT_TESTS}"
"\nBuild benchmarks: ${CAF_BUILD_BENCHMARKS}" "\nBuild benchmarks: ${CAF_BUILD_BENCHMARKS}"
"\nBuild opencl: ${CAF_BUILD_OPENCL}" "\nBuild OpenCL: ${CAF_BUILD_OPENCL}"
"\nBuild OpenSSL: ${CAF_BUILD_OPENSSL}"
"\nBuild Python: ${CAF_BUILD_PYTHON}" "\nBuild Python: ${CAF_BUILD_PYTHON}"
"\n" "\n"
"\nCXX: ${CMAKE_CXX_COMPILER}" "\nCXX: ${CMAKE_CXX_COMPILER}"
......
...@@ -65,6 +65,7 @@ Usage: $0 [OPTION]... [VAR=VALUE]... ...@@ -65,6 +65,7 @@ Usage: $0 [OPTION]... [VAR=VALUE]...
--no-curl-examples build without libcurl examples --no-curl-examples build without libcurl examples
--no-unit-tests build without unit tests --no-unit-tests build without unit tests
--no-opencl build without OpenCL module --no-opencl build without OpenCL module
--no-openssl build without OpenSSL module
--no-benchmarks build without benchmarks --no-benchmarks build without benchmarks
--no-tools build without CAF tools such as caf-run --no-tools build without CAF tools such as caf-run
--no-io build without I/O module --no-io build without I/O module
...@@ -339,6 +340,9 @@ while [ $# -ne 0 ]; do ...@@ -339,6 +340,9 @@ while [ $# -ne 0 ]; do
--no-opencl) --no-opencl)
append_cache_entry CAF_NO_OPENCL BOOL yes append_cache_entry CAF_NO_OPENCL BOOL yes
;; ;;
--no-openssl)
append_cache_entry CAF_NO_OPENSSL BOOL yes
;;
--build-static) --build-static)
append_cache_entry CAF_BUILD_STATIC BOOL yes append_cache_entry CAF_BUILD_STATIC BOOL yes
;; ;;
......
...@@ -29,9 +29,19 @@ ...@@ -29,9 +29,19 @@
namespace caf { namespace caf {
namespace openssl { namespace openssl {
static int pem_passwd_cb(char* buf, int size, int rwflag, void* session); namespace {
int pem_passwd_cb(char* buf, int size, int, void* ptr) {
auto passphrase = reinterpret_cast<session*>(ptr)->openssl_passphrase();
strncpy(buf, passphrase, size);
buf[size - 1] = '\0';
return strlen(buf);
}
} // namespace <anonymous>
session::session(actor_system& sys) : sys_(sys) { session::session(actor_system& sys) : sys_(sys) {
// nop
} }
void session::init() { void session::init() {
...@@ -55,10 +65,9 @@ bool session::read_some(size_t& result, native_socket /* fd */, void* buf, ...@@ -55,10 +65,9 @@ bool session::read_some(size_t& result, native_socket /* fd */, void* buf,
if (ret > 0) { if (ret > 0) {
result = ret; result = ret;
return true; return true;
} else {
result = 0;
return handle_ssl_result(ret);
} }
result = 0;
return handle_ssl_result(ret);
} }
bool session::write_some(size_t& result, native_socket /* fd */, bool session::write_some(size_t& result, native_socket /* fd */,
...@@ -68,12 +77,11 @@ bool session::write_some(size_t& result, native_socket /* fd */, ...@@ -68,12 +77,11 @@ bool session::write_some(size_t& result, native_socket /* fd */,
return true; return true;
auto ret = SSL_write(ssl_, buf, len); auto ret = SSL_write(ssl_, buf, len);
if (ret > 0) { if (ret > 0) {
result = ret; result = static_cast<size_t>(ret);
return true; return true;
} else {
result = 0;
return handle_ssl_result(ret);
} }
result = 0;
return handle_ssl_result(ret);
} }
bool session::connect(native_socket fd) { bool session::connect(native_socket fd) {
...@@ -89,10 +97,7 @@ bool session::try_accept(native_socket fd) { ...@@ -89,10 +97,7 @@ bool session::try_accept(native_socket fd) {
SSL_set_fd(ssl_, fd); SSL_set_fd(ssl_, fd);
SSL_set_accept_state(ssl_); SSL_set_accept_state(ssl_);
auto ret = SSL_accept(ssl_); auto ret = SSL_accept(ssl_);
if (ret > 0) return ret > 0 || handle_ssl_result(ret);
return true;
else
return handle_ssl_result(ret);
} }
const char* session::openssl_passphrase() { const char* session::openssl_passphrase() {
...@@ -129,12 +134,11 @@ SSL_CTX* session::create_ssl_context() { ...@@ -129,12 +134,11 @@ SSL_CTX* session::create_ssl_context() {
if (SSL_CTX_load_verify_locations(ctx, cafile, capath) != 1) if (SSL_CTX_load_verify_locations(ctx, cafile, capath) != 1)
raise_ssl_error("cannot load trusted CA certificates"); raise_ssl_error("cannot load trusted CA certificates");
} }
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr); SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
nullptr);
if (SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL:!MD5") != 1) if (SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL:!MD5") != 1)
raise_ssl_error("cannot set cipher list"); raise_ssl_error("cannot set cipher list");
} } else {
else {
// No authentication. // No authentication.
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, nullptr); SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, nullptr);
auto ecdh = EC_KEY_new_by_curve_name(NID_secp384r1); auto ecdh = EC_KEY_new_by_curve_name(NID_secp384r1);
...@@ -144,7 +148,6 @@ SSL_CTX* session::create_ssl_context() { ...@@ -144,7 +148,6 @@ SSL_CTX* session::create_ssl_context() {
if (SSL_CTX_set_cipher_list(ctx, "AECDH-AES256-SHA") != 1) if (SSL_CTX_set_cipher_list(ctx, "AECDH-AES256-SHA") != 1)
raise_ssl_error("cannot set anonymous cipher"); raise_ssl_error("cannot set anonymous cipher");
} }
return ctx; return ctx;
} }
...@@ -180,12 +183,5 @@ bool session::handle_ssl_result(int ret) { ...@@ -180,12 +183,5 @@ bool session::handle_ssl_result(int ret) {
} }
} }
static int pem_passwd_cb(char* buf, int size, int /* rwflag */, void* session) {
auto passphrase = static_cast<class session*>(session)->openssl_passphrase();
strncpy(buf, passphrase, size);
buf[size - 1] = '\0';
return strlen(buf);
}
} // namespace openssl } // namespace openssl
} // namespace caf } // namespace caf
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright (C) 2011 - 2017 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/config.hpp"
#define CAF_SUITE openssl_authentication_success
#include "caf/test/unit_test.hpp"
#include <vector>
#include <sstream>
#include <utility>
#include <algorithm>
#include <limits.h>
#include <stdlib.h>
#include "caf/all.hpp"
#include "caf/io/all.hpp"
#include "caf/openssl/all.hpp"
using namespace caf;
namespace {
constexpr char local_host[] = "127.0.0.1";
class config : public actor_system_config {
public:
config() {
load<io::middleman>();
load<openssl::manager>();
add_message_type<std::vector<int>>("std::vector<int>");
actor_system_config::parse(test::engine::argc(),
test::engine::argv());
}
static std::string data_dir() {
auto path = std::string(::caf::test::engine::path());
auto found = path.find_last_of("/");
path = path.substr(0, path.find_last_of("/"));
path += "/../../libcaf_openssl/test";
char rpath[PATH_MAX];
return realpath(path.c_str(), rpath);
}
};
behavior make_pong_behavior() {
return {
[](int val) -> int {
CAF_MESSAGE("pong with " << ++val);
return val;
}
};
}
behavior make_ping_behavior(event_based_actor* self, const actor& pong) {
CAF_MESSAGE("ping with " << 0);
self->send(pong, 0);
return {
[=](int val) -> int {
if (val == 3) {
CAF_MESSAGE("ping with exit");
self->send_exit(self->current_sender(),
exit_reason::user_shutdown);
CAF_MESSAGE("ping quits");
self->quit();
}
CAF_MESSAGE("ping with " << val);
return val;
}
};
}
} // namespace <anonymous>
struct fixture_certs_success {
config server_side_config;
actor_system server_side{server_side_config};
config client_side_config;
actor_system client_side{client_side_config};
fixture_certs_success()
{
server_side_config.openssl_cafile = config::data_dir() + "/ca.pem";
server_side_config.openssl_certificate = config::data_dir() + "/cert.1.pem";
server_side_config.openssl_key = config::data_dir() + "/key.1.enc.pem";
server_side_config.openssl_passphrase = "12345";
client_side_config.openssl_cafile = config::data_dir() + "/ca.pem";
client_side_config.openssl_certificate = config::data_dir() + "/cert.2.pem";
client_side_config.openssl_key = config::data_dir() + "/key.2.pem";
}
};
CAF_TEST_FIXTURE_SCOPE(authentication_success, fixture_certs_success)
using openssl::remote_actor;
using openssl::publish;
CAF_TEST(authentication_success_ping_pong) {
// server side
CAF_EXP_THROW(port,
publish(server_side.spawn(make_pong_behavior), 0, local_host));
// client side
CAF_EXP_THROW(pong, remote_actor(client_side, local_host, port));
client_side.spawn(make_ping_behavior, pong);
}
CAF_TEST_FIXTURE_SCOPE_END()
...@@ -19,9 +19,11 @@ ...@@ -19,9 +19,11 @@
#include "caf/config.hpp" #include "caf/config.hpp"
#define CAF_SUITE openssl_authentication_failure #define CAF_SUITE openssl_authentication
#include "caf/test/unit_test.hpp" #include "caf/test/unit_test.hpp"
#include <unistd.h>
#include <vector> #include <vector>
#include <sstream> #include <sstream>
#include <utility> #include <utility>
...@@ -48,15 +50,20 @@ public: ...@@ -48,15 +50,20 @@ public:
add_message_type<std::vector<int>>("std::vector<int>"); add_message_type<std::vector<int>>("std::vector<int>");
actor_system_config::parse(test::engine::argc(), actor_system_config::parse(test::engine::argc(),
test::engine::argv()); test::engine::argv());
scheduler_max_threads = 1;
} }
static std::string data_dir() { static std::string data_dir() {
auto path = std::string(::caf::test::engine::path()); std::string path{::caf::test::engine::path()};
auto found = path.find_last_of("/");
path = path.substr(0, path.find_last_of("/")); path = path.substr(0, path.find_last_of("/"));
// TODO: https://github.com/actor-framework/actor-framework/issues/555
path += "/../../libcaf_openssl/test"; path += "/../../libcaf_openssl/test";
char rpath[PATH_MAX]; char rpath[PATH_MAX];
return realpath(path.c_str(), rpath); auto rp = realpath(path.c_str(), rpath);
std::string result;
if (rp)
result = rp;
return result;
} }
}; };
...@@ -87,33 +94,65 @@ behavior make_ping_behavior(event_based_actor* self, const actor& pong) { ...@@ -87,33 +94,65 @@ behavior make_ping_behavior(event_based_actor* self, const actor& pong) {
}; };
} }
} // namespace <anonymous> struct fixture {
struct fixture_certs_failure {
config server_side_config; config server_side_config;
actor_system server_side{server_side_config};
config client_side_config; config client_side_config;
actor_system client_side{client_side_config}; bool initialized;
union { actor_system server_side; };
fixture_certs_failure() union { actor_system client_side; };
{
server_side_config.openssl_cafile = config::data_dir() + "/ca.pem"; fixture() : initialized(false) {
server_side_config.openssl_certificate = config::data_dir() + "/cert.1.pem"; // nop
server_side_config.openssl_key = config::data_dir() + "/key.1.enc.pem"; }
server_side_config.openssl_passphrase = "12345";
~fixture() {
// client_side_config.openssl_cafile = config::data_dir() + "/ca.pem"; if (initialized) {
client_side_config.openssl_certificate = config::data_dir() + "/cert.2.pem"; server_side.~actor_system();
client_side_config.openssl_key = config::data_dir() + "/key.2.pem"; client_side.~actor_system();
} }
}
bool init(bool skip_client_side_ca) {
auto cd = config::data_dir();
cd += '/';
server_side_config.openssl_passphrase = "12345";
// check whether all files exist before setting config parameters
std::string dummy;
std::pair<const char*, std::string*> cfg[] {
{"ca.pem", &server_side_config.openssl_cafile},
{"cert.1.pem", &server_side_config.openssl_certificate},
{"key.1.enc.pem", &server_side_config.openssl_key},
{"ca.pem", skip_client_side_ca ? &dummy
: &client_side_config.openssl_cafile},
{"cert.2.pem", &client_side_config.openssl_certificate},
{"key.2.pem", &client_side_config.openssl_key}
};
// return if any file is unreadable or non-existend
for (auto& x : cfg) {
auto path = cd + x.first;
if (access(path.c_str(), F_OK) == -1) {
CAF_MESSAGE("pem files missing, skip test");
return false;
}
*x.second = std::move(path);
}
new (&server_side) actor_system(server_side_config);
new (&client_side) actor_system(client_side_config);
initialized = true;
return true;
}
}; };
CAF_TEST_FIXTURE_SCOPE(authentication_failure, fixture_certs_failure) } // namespace <anonymous>
CAF_TEST_FIXTURE_SCOPE(authentication, fixture)
using openssl::remote_actor; using openssl::remote_actor;
using openssl::publish; using openssl::publish;
CAF_TEST(authentication_failure_ping_pong) { CAF_TEST(authentication_succes) {
if (!init(false))
return;
// server side // server side
CAF_EXP_THROW(port, CAF_EXP_THROW(port,
publish(server_side.spawn(make_pong_behavior), 0, local_host)); publish(server_side.spawn(make_pong_behavior), 0, local_host));
...@@ -122,4 +161,16 @@ CAF_TEST(authentication_failure_ping_pong) { ...@@ -122,4 +161,16 @@ CAF_TEST(authentication_failure_ping_pong) {
client_side.spawn(make_ping_behavior, pong); client_side.spawn(make_ping_behavior, pong);
} }
CAF_TEST(authentication_failure) {
if (!init(true))
return;
// server side
auto pong = server_side.spawn(make_pong_behavior);
CAF_EXP_THROW(port, publish(pong, 0, local_host));
// client side
auto remote_pong = remote_actor(client_side, local_host, port);
CAF_REQUIRE(!remote_pong);
anon_send_exit(pong, exit_reason::user_shutdown);
}
CAF_TEST_FIXTURE_SCOPE_END() CAF_TEST_FIXTURE_SCOPE_END()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment