blob: 6cc643c3fc8ebcb65bf9fcfe23d220271ab0898f [file] [log] [blame]
/**
*
* 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 <signal.h>
#include <sys/stat.h>
#include <chrono>
#include <thread>
#include <filesystem>
#undef NDEBUG
#include <cassert>
#include <utility>
#include <memory>
#include <string>
#include "properties/Configure.h"
#include "io/tls/TLSSocket.h"
#include "SimpleSSLTestServer.h"
namespace minifi = org::apache::nifi::minifi;
class SimpleSSLTestServerTLSv1 : public SimpleSSLTestServer {
public:
SimpleSSLTestServerTLSv1(int port, const std::filesystem::path& key_dir)
: SimpleSSLTestServer(TLSv1_server_method(), port, key_dir) {
}
};
class SimpleSSLTestServerTLSv1_1 : public SimpleSSLTestServer {
public:
SimpleSSLTestServerTLSv1_1(int port, const std::filesystem::path& key_dir)
: SimpleSSLTestServer(TLSv1_1_server_method(), port, key_dir) {
}
};
class SimpleSSLTestServerTLSv1_2 : public SimpleSSLTestServer {
public:
SimpleSSLTestServerTLSv1_2(int port, const std::filesystem::path& key_dir)
: SimpleSSLTestServer(TLSv1_2_server_method(), port, key_dir) {
}
};
class TLSClientSocketSupportedProtocolsTest {
public:
explicit TLSClientSocketSupportedProtocolsTest(const std::filesystem::path& key_dir)
: key_dir_(key_dir), configuration_(std::make_shared<minifi::Configure>()) {
}
void run() {
configureSecurity();
verifyTLSClientSocketExclusiveCompatibilityWithTLSv1_2();
}
protected:
void configureSecurity() {
host_ = minifi::io::Socket::getMyHostName();
if (!key_dir_.empty()) {
configuration_->set(minifi::Configure::nifi_remote_input_secure, "true");
configuration_->set(minifi::Configure::nifi_security_client_certificate, (key_dir_ / "cn.crt.pem").string());
configuration_->set(minifi::Configure::nifi_security_client_private_key, (key_dir_ / "cn.ckey.pem").string());
configuration_->set(minifi::Configure::nifi_security_client_pass_phrase, (key_dir_ / "cn.pass").string());
configuration_->set(minifi::Configure::nifi_security_client_ca_certificate, (key_dir_ / "nifi-cert.pem").string());
configuration_->set(minifi::Configure::nifi_default_directory, key_dir_.string());
}
}
void verifyTLSClientSocketExclusiveCompatibilityWithTLSv1_2() {
verifyTLSProtocolCompatibility<SimpleSSLTestServerTLSv1>(false);
verifyTLSProtocolCompatibility<SimpleSSLTestServerTLSv1_1>(false);
verifyTLSProtocolCompatibility<SimpleSSLTestServerTLSv1_2>(true);
}
template <class TLSTestSever>
void verifyTLSProtocolCompatibility(const bool should_be_compatible) {
// bind to random port
TLSTestSever server(0, key_dir_);
server.waitForConnection();
int port = server.getPort();
const auto socket_context = std::make_shared<minifi::io::TLSContext>(configuration_);
client_socket_ = std::make_unique<minifi::io::TLSSocket>(socket_context, host_, port, 0);
const bool client_initialized_successfully = (client_socket_->initialize() == 0);
assert(client_initialized_successfully == should_be_compatible);
server.shutdownServer();
assert(server.hadConnection() == should_be_compatible);
}
protected:
std::unique_ptr<minifi::io::TLSSocket> client_socket_;
std::string host_;
std::filesystem::path key_dir_;
std::shared_ptr<minifi::Configure> configuration_;
};
static void sigpipe_handle(int) {
}
int main(int argc, char **argv) {
std::string key_dir;
if (argc > 1) {
key_dir = argv[1];
}
#ifndef WIN32
signal(SIGPIPE, sigpipe_handle);
#endif
TLSClientSocketSupportedProtocolsTest client_socket_supported_protocols_verifier(key_dir);
client_socket_supported_protocols_verifier.run();
return 0;
}