Skip to content
Snippets Groups Projects
Commit 4325f0ff authored by Amna Snene's avatar Amna Snene Committed by Amna Snene
Browse files

tools: add certification check

If the server disable the anonymous connection option, it accept a client only if the CA of the client matches the CA of the server.
Else (anonymous connection option enabled), the server accept any request.

Change-Id: I6ff6ec72d6f6452ce50fd8aa35896ff7117be6c0
parent ad16157b
No related branches found
No related tags found
No related merge requests found
......@@ -59,12 +59,14 @@ Dnc::Dnc(const std::filesystem::path& path,
const std::string& turn_host,
const std::string& turn_user,
const std::string& turn_pass,
const std::string& turn_realm)
const std::string& turn_realm,
const bool anonymous)
: logger(dht::log::getStdLogger())
, ioContext(std::make_shared<asio::io_context>()),
iceFactory(std::make_shared<IceTransportFactory>(logger))
iceFactory(std::make_shared<IceTransportFactory>(logger)),
certStore(std::make_shared<tls::CertificateStore>(path / "certstore", logger)),
trustStore(std::make_shared<tls::TrustStore>(*certStore))
{
auto certStore = std::make_shared<tls::CertificateStore>(path / "certstore", logger);
ioContextRunner = std::thread([context = ioContext, logger = logger] {
try {
auto work = asio::make_work_guard(*context);
......@@ -75,6 +77,9 @@ Dnc::Dnc(const std::filesystem::path& path,
}
});
auto ca = identity.second->issuer;
trustStore->setCertificateStatus(ca->getId().toString(), tls::TrustStore::PermissionStatus::ALLOWED);
auto config = connectionManagerConfig(path,
identity,
bootstrap,
......@@ -90,10 +95,9 @@ Dnc::Dnc(const std::filesystem::path& path,
connectionManager = std::make_unique<ConnectionManager>(std::move(config));
connectionManager->onDhtConnected(identity.first->getPublicKey());
connectionManager->onICERequest([this](const dht::Hash<32>&) { // handle ICE request
if (logger)
logger->debug("ICE request received");
return true;
connectionManager->onICERequest([this, identity, anonymous](const DeviceId& deviceId) {
auto cert = certStore->getCertificate(deviceId.toString());
return trustStore->isAllowed(*cert, anonymous);
});
std::mutex mtx;
......@@ -177,7 +181,7 @@ Dnc::Dnc(const std::filesystem::path& path,
const std::string& turn_user,
const std::string& turn_pass,
const std::string& turn_realm)
: Dnc(path, identity, bootstrap,turn_host,turn_user,turn_pass, turn_realm)
: Dnc(path, identity, bootstrap,turn_host,turn_user,turn_pass, turn_realm, true)
{
std::condition_variable cv;
auto name = fmt::format("nc://{:s}:{:d}", remote_host, remote_port);
......
......@@ -38,7 +38,8 @@ public:
const std::string& turn_host,
const std::string& turn_user,
const std::string& turn_pass,
const std::string& turn_realm);
const std::string& turn_realm,
const bool anonymous);
// Build a client
Dnc(const std::filesystem::path& path,
dht::crypto::Identity identity,
......@@ -46,10 +47,10 @@ public:
dht::InfoHash peer_id,
const std::string& remote_host,
int remote_port,
const std::string& turn_host = "",
const std::string& turn_user = "",
const std::string& turn_pass = "",
const std::string& turn_realm = "");
const std::string& turn_host,
const std::string& turn_user,
const std::string& turn_pass,
const std::string& turn_realm);
~Dnc();
void run();
......@@ -60,6 +61,7 @@ private:
std::shared_ptr<IceTransportFactory> iceFactory;
std::shared_ptr<asio::io_context> ioContext;
std::thread ioContextRunner;
std::shared_ptr<tls::TrustStore> trustStore;
std::pair<std::string, std::string> parseName(const std::string_view name);
};
......
......@@ -6,4 +6,5 @@ turn_pass: "ring"
turn_realm: "ring"
port: 22
ip: "127.0.0.1"
CA: Home/.dhtnet # Change this to the path of the CA directory
CA: HOME/.dhtnet # Change this to the path of the CA directory
anonymous: false
\ No newline at end of file
......@@ -47,6 +47,7 @@ struct dhtnc_params
std::string turn_realm {};
std::string ca {};
std::string dnc_configuration {};
bool anonymous_cnx {false};
};
static const constexpr struct option long_options[]
......@@ -63,6 +64,7 @@ static const constexpr struct option long_options[]
{"turn_realm", required_argument, nullptr, 'r'},
{"CA", required_argument, nullptr, 'C'},
{"dnc_configuration", required_argument, nullptr, 'd'},
{"anonymous_cnx", no_argument, nullptr, 'a'},
{nullptr, 0, nullptr, 0}};
dhtnc_params
......@@ -70,7 +72,7 @@ parse_args(int argc, char** argv)
{
dhtnc_params params;
int opt;
while ((opt = getopt_long(argc, argv, "hvlw:r:u:t:I:b:p:i:C:d:", long_options, nullptr)) != -1) {
while ((opt = getopt_long(argc, argv, "ahvlw:r:u:t:I:b:p:i:C:d:", long_options, nullptr)) != -1) {
switch (opt) {
case 'h':
params.help = true;
......@@ -110,6 +112,10 @@ parse_args(int argc, char** argv)
break;
case 'd':
params.dnc_configuration = optarg;
break;
case 'a':
params.anonymous_cnx = true;
break;
default:
std::cerr << "Invalid option" << std::endl;
exit(EXIT_FAILURE);
......@@ -162,6 +168,9 @@ parse_args(int argc, char** argv)
if (config["port"] && params.remote_port == 0) {
params.remote_port = config["port"].as<int>();
}
if (config["anonymous"] && !params.anonymous_cnx) {
params.anonymous_cnx = config["anonymous"].as<bool>();
}
}
}
return params;
......@@ -202,16 +211,20 @@ main(int argc, char** argv)
" -u, --turn_user Specify the turn_user option with an argument.\n"
" -w, --turn_pass Specify the turn_pass option with an argument.\n"
" -r, --turn_realm Specify the turn_realm option with an argument.\n"
" -C, --CA Specify the CA option with an argument.\n");
" -C, --CA Specify the CA option with an argument.\n"
" -d, --dnc_configuration Specify the dnc_configuration option with an argument.\n"
" -a, --anonymous_cnx Enable the anonymous mode.\n");
return EXIT_SUCCESS;
}
if (params.version) {
fmt::print("dnc v1.0\n");
return EXIT_SUCCESS;
}
auto identity = dhtnet::loadIdentity(params.path, params.ca);
fmt::print("dnc 1.0\n");
auto identity = dhtnet::loadIdentity(params.path, params.ca);
fmt::print("Loaded identity: {} from {}\n", identity.second->getId(), params.path);
std::unique_ptr<dhtnet::Dnc> dhtnc;
......@@ -223,7 +236,8 @@ main(int argc, char** argv)
params.turn_host,
params.turn_user,
params.turn_pass,
params.turn_realm);
params.turn_realm,
params.anonymous_cnx);
} else {
dhtnc = std::make_unique<dhtnet::Dnc>(params.path,
identity,
......
......@@ -91,13 +91,14 @@ dhtnet::Dsh::Dsh(const std::filesystem::path& path,
const std::string& turn_host,
const std::string& turn_user,
const std::string& turn_pass,
const std::string& turn_realm)
const std::string& turn_realm,
bool anonymous)
:logger(dht::log::getStdLogger())
, ioContext(std::make_shared<asio::io_context>()),
iceFactory(std::make_shared<IceTransportFactory>(logger))
iceFactory(std::make_shared<IceTransportFactory>(logger)),
certStore(std::make_shared<tls::CertificateStore>(path / "certstore", logger)),
trustStore(std::make_shared<tls::TrustStore>(*certStore))
{
auto certStore = std::make_shared<tls::CertificateStore>(path / "certstore", logger);
ioContext = std::make_shared<asio::io_context>();
ioContextRunner = std::thread([context = ioContext, logger = logger] {
try {
......@@ -108,6 +109,8 @@ dhtnet::Dsh::Dsh(const std::filesystem::path& path,
logger->error("Error in ioContextRunner: {}", ex.what());
}
});
auto ca = identity.second->issuer;
trustStore->setCertificateStatus(ca->getId().toString(), tls::TrustStore::PermissionStatus::ALLOWED);
// Build a server
auto config = connectionManagerConfig(path,
identity,
......@@ -120,10 +123,8 @@ dhtnet::Dsh::Dsh(const std::filesystem::path& path,
connectionManager = std::make_unique<ConnectionManager>(std::move(config));
connectionManager->onDhtConnected(identity.first->getPublicKey());
connectionManager->onICERequest([this](const dht::Hash<32>&) { // handle ICE request
if (logger)
logger->debug("ICE request received");
return true;
connectionManager->onICERequest([this,identity,anonymous](const DeviceId& deviceId ) { // handle ICE request
return trustStore->isAllowed(*certStore->getCertificate(deviceId.toString()), anonymous);
});
std::mutex mtx;
......@@ -228,7 +229,7 @@ dhtnet::Dsh::Dsh(const std::filesystem::path& path,
const std::string& turn_user,
const std::string& turn_pass,
const std::string& turn_realm)
: Dsh(path, identity, bootstrap, turn_host, turn_user, turn_pass, turn_realm)
: Dsh(path, identity, bootstrap, turn_host, turn_user, turn_pass, turn_realm, false)
{
// Build a client
std::condition_variable cv;
......
......@@ -33,7 +33,8 @@ public:
const std::string& turn_host,
const std::string& turn_user,
const std::string& turn_pass,
const std::string& turn_realm);
const std::string& turn_realm,
const bool anonymous);
// Build a client
Dsh(const std::filesystem::path& path,
dht::crypto::Identity identity,
......@@ -54,6 +55,8 @@ private:
std::shared_ptr<dhtnet::IceTransportFactory> iceFactory {nullptr};
std::shared_ptr<asio::io_context> ioContext;
std::thread ioContextRunner;
std::shared_ptr<tls::TrustStore> trustStore;
};
} // namespace dhtnet
......@@ -6,3 +6,4 @@ turn_pass: "ring"
turn_realm: "ring"
binary: "bash"
CA: HOME/.dhtnet # Change this to the path of the CA directory
anonymous: false
......@@ -46,6 +46,7 @@ struct dhtsh_params
std::string turn_pass {};
std::string turn_realm {};
std::string dsh_configuration {};
bool anonymous_cnx {false};
};
static const constexpr struct option long_options[]
......@@ -61,6 +62,7 @@ static const constexpr struct option long_options[]
{"turn_pass", required_argument, nullptr, 'w'},
{"turn_realm", required_argument, nullptr, 'r'},
{"dsh_configuration", required_argument, nullptr, 'd'},
{"anonymous", no_argument, nullptr, 'a'},
{nullptr, 0, nullptr, 0}};
dhtsh_params
......@@ -105,6 +107,10 @@ parse_args(int argc, char** argv)
break;
case 'd':
params.dsh_configuration = optarg;
break;
case 'a':
params.anonymous_cnx = true;
break;
default:
std::cerr << "Invalid option" << std::endl;
exit(EXIT_FAILURE);
......@@ -154,6 +160,10 @@ parse_args(int argc, char** argv)
if (config["binary"] && params.binary.empty()) {
params.binary = config["binary"].as<std::string>();
}
if (config["anonymous"] && !params.anonymous_cnx) {
params.anonymous_cnx = config["anonymous"].as<bool>();
}
}
}
return params;
......@@ -211,14 +221,15 @@ main(int argc, char** argv)
std::unique_ptr<dhtnet::Dsh> dhtsh;
if (params.listen) {
// create dnc instance
// create dsh instance
dhtsh = std::make_unique<dhtnet::Dsh>(params.path,
identity,
params.bootstrap,
params.turn_host,
params.turn_user,
params.turn_pass,
params.turn_realm);
params.turn_realm,
params.anonymous_cnx);
} else {
dhtsh = std::make_unique<dhtnet::Dsh>(params.path,
identity,
......
......@@ -166,9 +166,10 @@ dhtnet::Dvpn::Dvpn(const std::filesystem::path& path,
const std::string& configuration_file)
: logger(dht::log::getStdLogger())
, ioContext(std::make_shared<asio::io_context>()),
iceFactory(std::make_shared<IceTransportFactory>(logger))
iceFactory(std::make_shared<IceTransportFactory>(logger)),
certStore(std::make_shared<tls::CertificateStore>(path / "certstore", logger)),
trustStore(std::make_shared<tls::TrustStore>(*certStore))
{
auto certStore = std::make_shared<tls::CertificateStore>(path / "certstore", logger);
ioContextRunner = std::thread([context = ioContext, logger = logger] {
try {
auto work = asio::make_work_guard(*context);
......@@ -178,6 +179,8 @@ dhtnet::Dvpn::Dvpn(const std::filesystem::path& path,
logger->error("Error in ioContextRunner: {}", ex.what());
}
});
auto ca = identity.second->issuer;
trustStore->setCertificateStatus(ca->getId().toString(), tls::TrustStore::PermissionStatus::ALLOWED);
auto config = connectionManagerConfig(path,
identity,
......@@ -194,11 +197,7 @@ dhtnet::Dvpn::Dvpn(const std::filesystem::path& path,
connectionManager = std::make_unique<ConnectionManager>(std::move(config));
connectionManager->onDhtConnected(identity.first->getPublicKey());
connectionManager->onICERequest([this](const dht::Hash<32>&) { // handle ICE request
if (logger)
logger->debug("ICE request received");
return true;
});
}
dhtnet::DvpnServer::DvpnServer(const std::filesystem::path& path,
......@@ -208,7 +207,8 @@ dhtnet::DvpnServer::DvpnServer(const std::filesystem::path& path,
const std::string& turn_user,
const std::string& turn_pass,
const std::string& turn_realm,
const std::string& configuration_file)
const std::string& configuration_file,
bool anonymous)
: Dvpn(path, identity, bootstrap, turn_host, turn_user, turn_pass, turn_realm, configuration_file)
{
std::mutex mtx;
......@@ -222,6 +222,9 @@ dhtnet::DvpnServer::DvpnServer(const std::filesystem::path& path,
return true;
});
connectionManager->onICERequest([this, identity, anonymous](const DeviceId& deviceId) {
return trustStore->isAllowed(*certStore->getCertificate(deviceId.toString()), anonymous);
});
connectionManager->onConnectionReady([=](const DeviceId&,
const std::string& channel,
std::shared_ptr<ChannelSocket> socket) {
......
......@@ -66,7 +66,7 @@ public:
std::shared_ptr<asio::io_context> ioContext;
std::thread ioContextRunner;
enum class CommunicationState { METADATA, DATA };
std::shared_ptr<tls::TrustStore> trustStore;
};
class DvpnServer : public Dvpn
......@@ -80,7 +80,8 @@ public:
const std::string& turn_user,
const std::string& turn_pass,
const std::string& turn_realm,
const std::string& configuration_file);
const std::string& configuration_file,
bool anonymous);
};
class DvpnClient : public Dvpn
......@@ -103,7 +104,6 @@ private:
int tun_fd;
char tun_device[IFNAMSIZ] = {0}; // IFNAMSIZ is typically the maximum size for interface names
std::shared_ptr<asio::posix::stream_descriptor> tun_stream;
};
} // namespace dhtnet
\ No newline at end of file
......@@ -4,6 +4,6 @@ turn_host: "turn.jami.net"
turn_user: "ring"
turn_pass: "ring"
turn_realm: "ring"
configuration_file: "./test_config.yaml"
configuration_file: "HOME/dhtnet/tools/dvpn/dvpn.yaml" # Change this to the path of the dvpn.yaml file
CA: HOME/.dhtnet # Change this to the path of the CA directory
anonymous: false
\ No newline at end of file
......@@ -46,6 +46,7 @@ struct dhtvpn_params
std::string configuration_file {};
std::string ca {};
std::string dvpn_configuration_file {};
bool anonymous_cnx {false};
};
static const constexpr struct option long_options[]
......@@ -61,6 +62,7 @@ static const constexpr struct option long_options[]
{"vpn_configuration_file", required_argument, nullptr, 'c'},
{"CA", required_argument, nullptr, 'C'},
{"dvpn_configuration_file", required_argument, nullptr, 'd'},
{"anonymous", no_argument, nullptr, 'a'},
{nullptr, 0, nullptr, 0}};
dhtvpn_params
......@@ -106,6 +108,9 @@ parse_args(int argc, char** argv)
case 'd':
params.dvpn_configuration_file = optarg;
break;
case 'a':
params.anonymous_cnx = true;
break;
default:
std::cerr << "Invalid option" << std::endl;
exit(EXIT_FAILURE);
......@@ -143,6 +148,9 @@ parse_args(int argc, char** argv)
if (config["configuration_file"] && params.configuration_file.empty()) {
params.configuration_file = config["configuration_file"].as<std::string>();
}
if (config["anonymous"] && !params.anonymous_cnx) {
params.anonymous_cnx = config["anonymous"].as<bool>();
}
}
}
......@@ -196,6 +204,7 @@ main(int argc, char** argv)
" -c, --vpn_configuration_file Specify the vpn_configuration_file path option with an argument.\n"
" -C, --CA Specify the CA path option with an argument.\n"
" -d, --dvpn_configuration_file Specify the dvpn_configuration_file path option with an argument.\n"
" -a, --anonymous Specify the anonymous option with an argument.\n"
"\n");
return EXIT_SUCCESS;
}
......@@ -219,7 +228,8 @@ main(int argc, char** argv)
params.turn_user,
params.turn_pass,
params.turn_realm,
params.configuration_file);
params.configuration_file,
params.anonymous_cnx);
} else {
dvpn = std::make_unique<dhtnet::DvpnClient>(params.peer_id,
params.path,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment