diff --git a/tools/dnc/dnc.cpp b/tools/dnc/dnc.cpp index 37c8b229e0ae21e54464e7101145f8b12f927683..88bf61d93ef7821273241edf1d8895e02d7e2b2c 100644 --- a/tools/dnc/dnc.cpp +++ b/tools/dnc/dnc.cpp @@ -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); diff --git a/tools/dnc/dnc.h b/tools/dnc/dnc.h index b9545c151aff6468df3e1f53f3a7e06d833b46b6..77cfe9feeccb92f47863b6507fb7c92869a19025 100644 --- a/tools/dnc/dnc.h +++ b/tools/dnc/dnc.h @@ -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); }; diff --git a/tools/dnc/dnc.yaml b/tools/dnc/dnc.yaml index 6e092fa3a5a0d869c477c348776476cc78ffafe9..a107615b3493e7e1cf9933db133cda6d5062bcf9 100644 --- a/tools/dnc/dnc.yaml +++ b/tools/dnc/dnc.yaml @@ -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 diff --git a/tools/dnc/main.cpp b/tools/dnc/main.cpp index 0ba8b572ce97b20c08f7d4adbbe81e833715487b..363e05e6d30f4459356b32c67d4e3affe085760b 100644 --- a/tools/dnc/main.cpp +++ b/tools/dnc/main.cpp @@ -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, diff --git a/tools/dsh/dsh.cpp b/tools/dsh/dsh.cpp index ca4e99d2f38ee754114b73ac1d4a3234ae72ed82..4e7507d7e555b02deca73d7fe9a16be6761be73a 100644 --- a/tools/dsh/dsh.cpp +++ b/tools/dsh/dsh.cpp @@ -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; diff --git a/tools/dsh/dsh.h b/tools/dsh/dsh.h index 3bdc93476e65135d065c79539e31e2aa4970edff..dd6a4ea616c9e43e019619ad4986f5d293dedab1 100644 --- a/tools/dsh/dsh.h +++ b/tools/dsh/dsh.h @@ -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 diff --git a/tools/dsh/dsh.yaml b/tools/dsh/dsh.yaml index 54e13abb7252b4ae0745ddcbbebaf612bc70828d..a023aa3afde6270837bcf3f66976f210be92402e 100644 --- a/tools/dsh/dsh.yaml +++ b/tools/dsh/dsh.yaml @@ -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 diff --git a/tools/dsh/main.cpp b/tools/dsh/main.cpp index 7c5e006a6dbf8cdd2dc01caab4006a65d93f93c9..19ff4e5950e20ef59cb8cddbd69e29b7a863a898 100644 --- a/tools/dsh/main.cpp +++ b/tools/dsh/main.cpp @@ -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, diff --git a/tools/dvpn/dvpn.cpp b/tools/dvpn/dvpn.cpp index f0fc8209fd384bfb628223ce190ea59ff8a810b8..b7a0d03e9771839f6e5e10b43bfc61cdefb7b707 100644 --- a/tools/dvpn/dvpn.cpp +++ b/tools/dvpn/dvpn.cpp @@ -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) { diff --git a/tools/dvpn/dvpn.h b/tools/dvpn/dvpn.h index 42382aa57fb221e008a3dc0e7a953ed5cf2fd42c..6331907b86b34a2dd195cff9703f4316129f8e69 100644 --- a/tools/dvpn/dvpn.h +++ b/tools/dvpn/dvpn.h @@ -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 diff --git a/tools/dvpn/dvpn.yaml b/tools/dvpn/dvpn.yaml index 20929ecd27f4c3e31f7da5efea58c03c40a6e6b9..7e14842752658645dbefe7b8e10551026bf1fc49 100644 --- a/tools/dvpn/dvpn.yaml +++ b/tools/dvpn/dvpn.yaml @@ -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 diff --git a/tools/dvpn/main.cpp b/tools/dvpn/main.cpp index 97dd0de06d757114be672282f29ac9aaf6bada05..5b1945900da02e2d833854663ac3b9e77ce313f2 100644 --- a/tools/dvpn/main.cpp +++ b/tools/dvpn/main.cpp @@ -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,