Skip to content
Snippets Groups Projects
Verified Commit c6b1674a authored by Timm Fitschen's avatar Timm Fitschen
Browse files

WIP: TLS

parent e4c6eefd
Branches
Tags
No related merge requests found
Pipeline #9279 failed
...@@ -35,7 +35,8 @@ set(gRPC_BUILD_GRPC_PHP_PLUGIN OFF) ...@@ -35,7 +35,8 @@ set(gRPC_BUILD_GRPC_PHP_PLUGIN OFF)
set(gRPC_BUILD_GRPC_OBJECTIVE_C_PLUGIN OFF) set(gRPC_BUILD_GRPC_OBJECTIVE_C_PLUGIN OFF)
set(gRPC_BUILD_GRPC_NODE_PLUGIN OFF) set(gRPC_BUILD_GRPC_NODE_PLUGIN OFF)
set(protobuf_BUILD_TESTS OFF) set(protobuf_BUILD_TESTS OFF)
set(vGRPC_TAG_VERSION_OF_YOUR_CHOICE "v1.38.1") set(gRPC_VERSION "1.38.1")
set(vGRPC_TAG_VERSION_OF_YOUR_CHOICE "v${gRPC_VERSION}")
if(GRPC_AS_SUBMODULE) if(GRPC_AS_SUBMODULE)
# One way to build a projects that uses gRPC is to just include the # One way to build a projects that uses gRPC is to just include the
...@@ -209,8 +210,8 @@ else() ...@@ -209,8 +210,8 @@ else()
# Find gRPC installation # Find gRPC installation
# Looks for gRPCConfig.cmake file installed by gRPC's cmake installation. # Looks for gRPCConfig.cmake file installed by gRPC's cmake installation.
find_package(gRPC CONFIG REQUIRED) find_package(gRPC ${gRPC_VERSION} EXACT CONFIG REQUIRED)
message(STATUS "Using gRPC ${gRPC_VERSION}") message(STATUS "Using gRPC ${gRPC_VERSION} at ${gRPC}")
set(_GRPC_GRPCPP gRPC::grpc++) set(_GRPC_GRPCPP gRPC::grpc++)
if(CMAKE_CROSSCOMPILING) if(CMAKE_CROSSCOMPILING)
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
set(libcaosdb_INCL set(libcaosdb_INCL
${CMAKE_CURRENT_BINARY_DIR}/constants.h ${CMAKE_CURRENT_BINARY_DIR}/constants.h
${CMAKE_CURRENT_SOURCE_DIR}/connection.h ${CMAKE_CURRENT_SOURCE_DIR}/connection.h
${CMAKE_CURRENT_SOURCE_DIR}/utils.h
) )
# pass variable to parent scope # pass variable to parent scope
......
/* /*
*
* This file is a part of the CaosDB Project. * This file is a part of the CaosDB Project.
* *
* Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com> * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
...@@ -37,16 +36,40 @@ ...@@ -37,16 +36,40 @@
#include <grpcpp/create_channel.h> #include <grpcpp/create_channel.h>
#include <grpcpp/security/credentials.h> #include <grpcpp/security/credentials.h>
#include "caosdb/info/v1alpha1/main.grpc.pb.h" #include "caosdb/info/v1alpha1/main.grpc.pb.h"
namespace grpc { class ChannelCredentials; }
namespace caosdb { namespace info { namespace v1alpha1 { class VersionInfo; } } }
namespace caosdb { namespace caosdb {
using caosdb::info::v1alpha1::GeneralInfoService; using caosdb::info::v1alpha1::GeneralInfoService;
using caosdb::info::v1alpha1::VersionInfo; using caosdb::info::v1alpha1::VersionInfo;
using grpc::ChannelCredentials; using grpc::ChannelCredentials;
class CACertificateProvider {
public:
[[nodiscard]] auto virtual getCACertPem() const -> std::string = 0;
};
class PemFileCACertProvider : public CACertificateProvider {
private:
std::string cacert;
public:
explicit PemFileCACertProvider(const std::string &path);
[[nodiscard]] auto getCACertPem() const -> std::string override;
};
class PemCACertProvider : public CACertificateProvider {
private:
std::string cacert;
public:
explicit PemCACertProvider(const std::string &cacert);
[[nodiscard]] auto getCACertPem() const -> std::string override;
};
/** /**
* @brief Configuration of the CaosDB connection. * @brief Configuration of the CaosDB connection.
*/ */
class CaosDBConnectionConfig { class CaosDBConnectionConfig {
private:
std::string host; std::string host;
int port; int port;
...@@ -59,19 +82,16 @@ public: ...@@ -59,19 +82,16 @@ public:
[[nodiscard]] auto virtual toString() const -> std::string = 0; [[nodiscard]] auto virtual toString() const -> std::string = 0;
[[nodiscard]] auto getHost() const -> std::string; [[nodiscard]] auto getHost() const -> std::string;
[[nodiscard]] auto getPort() const -> int; [[nodiscard]] auto getPort() const -> int;
[[nodiscard]] auto virtual getChannelCredentials() const [[nodiscard]] auto virtual getChannelCredentials() const -> std::shared_ptr<ChannelCredentials> = 0;
-> std::shared_ptr<ChannelCredentials> = 0;
}; };
class InsecureCaosDBConnectionConfig : public CaosDBConnectionConfig { class InsecureCaosDBConnectionConfig : public CaosDBConnectionConfig {
private: private:
std::shared_ptr<ChannelCredentials> credentials; std::shared_ptr<ChannelCredentials> credentials;
public: public:
InsecureCaosDBConnectionConfig(const std::string &host, int port); InsecureCaosDBConnectionConfig(const std::string &host, int port);
[[nodiscard]] auto getChannelCredentials() const -> std::shared_ptr<ChannelCredentials> override;
[[nodiscard]] auto toString() const -> std::string override; [[nodiscard]] auto toString() const -> std::string override;
[[nodiscard]] auto getChannelCredentials() const
-> std::shared_ptr<ChannelCredentials> override;
}; };
class SslCaosDBConnectionConfig : public CaosDBConnectionConfig { class SslCaosDBConnectionConfig : public CaosDBConnectionConfig {
...@@ -79,9 +99,10 @@ private: ...@@ -79,9 +99,10 @@ private:
std::shared_ptr<ChannelCredentials> credentials; std::shared_ptr<ChannelCredentials> credentials;
public: public:
SslCaosDBConnectionConfig(const std::string &host, int port);
SslCaosDBConnectionConfig(const std::string &host, int port, SslCaosDBConnectionConfig(const std::string &host, int port,
const std::string &cacert); const std::shared_ptr<CACertificateProvider> &cacert);
[[nodiscard]] auto getChannelCredentials() const -> std::shared_ptr<ChannelCredentials> override;
[[nodiscard]] auto toString() const -> std::string override;
}; };
/** /**
......
/*
* This file is a part of the CaosDB Project.
*
* Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
* Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifndef UTILS_H
#define UTILS_H
#include <string_view>
#include <fstream>
#include <string>
#include <cstdlib>
namespace caosdb::utils {
/**
* @brief Read a text file into a string and return the file's content.
* @todo use boost-filesystem's "load_string_file"!
*/
inline auto load_string_file(const std::string &path) -> std::string {
const auto path_view = std::string_view{path};
constexpr auto size = std::size_t{4096};
auto stream = std::ifstream{path_view.data()};
stream.exceptions(std::ios_base::badbit);
auto result = std::string();
auto buffer = std::string(size, '\0');
while (stream.read(& buffer[0], size)) {
result.append(buffer, 0, stream.gcount());
}
result.append(buffer, 0, stream.gcount());
return result;
}
/**
* @brief Return the value of an environment variable or - if undefined - the
* fall_back value.
*/
inline auto get_env_var(const std::string & key, const std::string & fall_back ) -> const std::string
{
const char * val = getenv( key.c_str() );
if ( val == nullptr ) {
return fall_back;
} else {
const auto result = std::string(val);
return result;
}
}
} // namespace caosdb::utils
#endif
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
# add all source files to this list # add all source files to this list
set(libcaosdb_SRC set(libcaosdb_SRC
src/utils.cpp
src/connection.cpp src/connection.cpp
) )
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "caosdb/info/v1alpha1/main.pb.h" #include "caosdb/info/v1alpha1/main.pb.h"
#include "constants.h" #include "constants.h"
#include "connection.h" #include "connection.h"
#include "utils.h"
auto main() -> int { auto main() -> int {
...@@ -35,22 +36,22 @@ auto main() -> int { ...@@ -35,22 +36,22 @@ auto main() -> int {
<< caosdb::LIBCAOSDB_VERSION_PATCH << ")" << std::endl; << caosdb::LIBCAOSDB_VERSION_PATCH << ")" << std::endl;
std::cout << "We don't miss the H of caos." << std::endl; std::cout << "We don't miss the H of caos." << std::endl;
const std::string host = "localhost"; const auto pem_file_path = caosdb::utils::get_env_var("CAOSDB_SERVER_CA_PEM", std::string());
// NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) std::string pem = caosdb::utils::load_string_file(pem_file_path);
const int port = 8080;
const std::string &test = host;
std::cout << test << std::endl;
std::shared_ptr<caosdb::InsecureCaosDBConnectionConfig> config = std::cout << "PEM" << pem << "\n";
std::make_shared<caosdb::InsecureCaosDBConnectionConfig>(host, port); const std::string host = caosdb::utils::get_env_var("CAOSDB_SERVER_HOST", "localhost");
const std::string port_str = caosdb::utils::get_env_var("CAOSDB_SERVER_PORT", "8000");
const int port = std::stoi(port_str);
auto cacert = std::make_shared<caosdb::PemCACertProvider>(pem);
auto config = std::make_shared<caosdb::SslCaosDBConnectionConfig>(host, port, cacert);
caosdb::CaosDBConnection connection(config); caosdb::CaosDBConnection connection(config);
std::cout << std::endl << connection << std::endl; std::cout << std::endl << connection << std::endl;
const caosdb::info::v1alpha1::VersionInfo &v_info = const auto &v_info = connection.getVersionInfo();
connection.getVersionInfo(); const auto &build = v_info.build();
const std::string &build = v_info.build(); //std::cout << "BUILD(" << build[0] << ")" << std::endl;
std::cout << "BUILD(" << build[0] << ")" << std::endl;
std::cout << "VersionInfo(" << v_info.major() << "." << v_info.minor() << "." std::cout << "VersionInfo(" << v_info.major() << "." << v_info.minor() << "."
<< v_info.patch() << ")" << std::endl; << v_info.patch() << ")" << std::endl;
std::cout << "PRE_RELEASE(" << v_info.pre_release() << ")" << std::endl;
return 0; return 0;
} }
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
*/ */
#include "connection.h" #include "connection.h"
#include "utils.h"
#include <grpcpp/create_channel.h> #include <grpcpp/create_channel.h>
#include <grpcpp/impl/codegen/client_context.h> #include <grpcpp/impl/codegen/client_context.h>
#include <grpcpp/impl/codegen/status.h> #include <grpcpp/impl/codegen/status.h>
...@@ -32,6 +33,7 @@ ...@@ -32,6 +33,7 @@
#include "caosdb/info/v1alpha1/main.pb.h" #include "caosdb/info/v1alpha1/main.pb.h"
namespace caosdb { namespace caosdb {
using caosdb::utils::load_string_file;
using caosdb::info::v1alpha1::GeneralInfoService; using caosdb::info::v1alpha1::GeneralInfoService;
using caosdb::info::v1alpha1::GetVersionInfoRequest; using caosdb::info::v1alpha1::GetVersionInfoRequest;
using caosdb::info::v1alpha1::GetVersionInfoResponse; using caosdb::info::v1alpha1::GetVersionInfoResponse;
...@@ -40,6 +42,22 @@ using grpc::InsecureChannelCredentials; ...@@ -40,6 +42,22 @@ using grpc::InsecureChannelCredentials;
using grpc::SslCredentials; using grpc::SslCredentials;
using grpc::SslCredentialsOptions; using grpc::SslCredentialsOptions;
PemFileCACertProvider::PemFileCACertProvider(const std::string &path) {
this->cacert = load_string_file(path);
}
auto PemFileCACertProvider::getCACertPem() const -> std::string {
return this->cacert;
}
PemCACertProvider::PemCACertProvider(const std::string &cacert) {
this->cacert = cacert;
}
auto PemCACertProvider::getCACertPem() const -> std::string {
return this->cacert;
}
CaosDBConnectionConfig::CaosDBConnectionConfig(const std::string &host, CaosDBConnectionConfig::CaosDBConnectionConfig(const std::string &host,
int port) { int port) {
this->host = host; this->host = host;
...@@ -64,36 +82,39 @@ InsecureCaosDBConnectionConfig::InsecureCaosDBConnectionConfig( ...@@ -64,36 +82,39 @@ InsecureCaosDBConnectionConfig::InsecureCaosDBConnectionConfig(
this->credentials = grpc::InsecureChannelCredentials(); this->credentials = grpc::InsecureChannelCredentials();
} }
auto InsecureCaosDBConnectionConfig::toString() const -> std::string {
return "InsecureCaosDBConnectionConfig(" + this->getHost() + "," +
std::to_string(this->getPort()) + ")";
}
auto InsecureCaosDBConnectionConfig::getChannelCredentials() const auto InsecureCaosDBConnectionConfig::getChannelCredentials() const
-> std::shared_ptr<ChannelCredentials> { -> std::shared_ptr<ChannelCredentials> {
return this->credentials; return this->credentials;
} }
SslCaosDBConnectionConfig::SslCaosDBConnectionConfig( auto InsecureCaosDBConnectionConfig::toString() const -> std::string {
const std::string &host, int port, const std::string &cacert) return "InsecureCaosDBConnectionConfig(" + this->getHost() + "," +
: CaosDBConnectionConfig(host, port) { std::to_string(this->getPort()) + ")";
auto options = SslCredentialsOptions();
options.pem_root_certs = cacert;
this->credentials = SslCredentials(options);
} }
SslCaosDBConnectionConfig::SslCaosDBConnectionConfig( SslCaosDBConnectionConfig::SslCaosDBConnectionConfig(
const std::string &host, int port) const std::string &host, int port, const std::shared_ptr<CACertificateProvider> &cacert)
: CaosDBConnectionConfig(host, port) { : CaosDBConnectionConfig(host, port) {
auto options = SslCredentialsOptions(); SslCredentialsOptions options;
options.pem_root_certs = cacert->getCACertPem();
this->credentials = SslCredentials(options); this->credentials = SslCredentials(options);
} }
auto SslCaosDBConnectionConfig::getChannelCredentials() const
-> std::shared_ptr<ChannelCredentials> {
return this->credentials;
}
auto SslCaosDBConnectionConfig::toString() const -> std::string {
return "SslCaosDBConnectionConfig(" + this->getHost() + "," +
std::to_string(this->getPort()) + ")";
}
CaosDBConnection::CaosDBConnection( CaosDBConnection::CaosDBConnection(
const std::shared_ptr<CaosDBConnectionConfig> &config) { const std::shared_ptr<CaosDBConnectionConfig> &config) {
this->config = config; this->config = config;
const std::string &target = const std::string target = this->config->getHost() + ":" + std::to_string(this->config->getPort());
this->config->getHost() + ":" + std::to_string(this->config->getPort());
const std::shared_ptr<grpc::Channel> &channel = const std::shared_ptr<grpc::Channel> &channel =
grpc::CreateChannel(target, this->config->getChannelCredentials()); grpc::CreateChannel(target, this->config->getChannelCredentials());
this->stub_ = GeneralInfoService::NewStub(channel); this->stub_ = GeneralInfoService::NewStub(channel);
......
#include "utils.h"
namespace caosdb::utils {
} // namespace caosdb::utils
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include <type_traits> #include <type_traits>
#include "gtest/gtest_pred_impl.h" #include "gtest/gtest_pred_impl.h"
TEST(test_connection, localhost_8080) { TEST(test_connection, configure_insecure_localhost_8080) {
caosdb::InsecureCaosDBConnectionConfig config("localhost", 8000); caosdb::InsecureCaosDBConnectionConfig config("localhost", 8000);
ASSERT_EQ("localhost", config.getHost()); ASSERT_EQ("localhost", config.getHost());
...@@ -36,3 +36,14 @@ TEST(test_connection, localhost_8080) { ...@@ -36,3 +36,14 @@ TEST(test_connection, localhost_8080) {
config.getChannelCredentials(); config.getChannelCredentials();
ASSERT_TRUE(icc != nullptr); ASSERT_TRUE(icc != nullptr);
} }
TEST(test_connection, configure_ssl_localhost_8080) {
auto cacert = std::make_shared<caosdb::PemCACertProvider>("ca chain");
caosdb::SslCaosDBConnectionConfig config("localhost", 44300, cacert);
ASSERT_EQ("localhost", config.getHost());
ASSERT_EQ(44300, config.getPort());
std::shared_ptr<grpc::ChannelCredentials> sslcc =
config.getChannelCredentials();
ASSERT_TRUE(sslcc != nullptr);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment