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
diff --git a/tools/dvpn/dvpn.cpp b/tools/dvpn/dvpn.cpp
index f0fc820..b7a0d03 100644
--- a/tools/dvpn/dvpn.cpp
+++ b/tools/dvpn/dvpn.cpp
@@ -166,9 +166,10 @@
                    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 @@
                 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 @@
     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 @@
                                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 @@
             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 42382aa..6331907 100644
--- a/tools/dvpn/dvpn.h
+++ b/tools/dvpn/dvpn.h
@@ -66,7 +66,7 @@
     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 @@
                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 @@
     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 20929ec..7e14842 100644
--- a/tools/dvpn/dvpn.yaml
+++ b/tools/dvpn/dvpn.yaml
@@ -4,6 +4,6 @@
 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 97dd0de..5b19459 100644
--- a/tools/dvpn/main.cpp
+++ b/tools/dvpn/main.cpp
@@ -46,6 +46,7 @@
     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 @@
        {"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 @@
         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 @@
             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 @@
             "  -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 @@
                                                     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,