From 7580eac2d5437f6a131466d14cd68f08db4400d3 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Mon, 18 Mar 2024 18:56:46 +0100 Subject: [PATCH] Codechange: create helper class for useful NetworkAuthorizedKeys functions --- src/console_cmds.cpp | 21 ++----------- src/network/network.cpp | 51 +++++++++++++++++++++++++++++++ src/network/network_crypto.cpp | 8 ----- src/network/network_crypto.h | 8 +++-- src/network/network_type.h | 13 ++++++++ src/settings_type.h | 4 +-- src/tests/test_network_crypto.cpp | 14 ++++----- 7 files changed, 81 insertions(+), 38 deletions(-) diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 10e6810f14..6b88247dfb 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -1957,22 +1957,11 @@ DEF_CONSOLE_CMD(ConCompanyPassword) } /** All the known authorized keys with their name. */ -static std::vector *>> _console_cmd_authorized_keys{ +static std::vector> _console_cmd_authorized_keys{ { "rcon", &_settings_client.network.rcon_authorized_keys }, { "server", &_settings_client.network.server_authorized_keys }, }; -/** - * Simple helper to find the location of the given authorized key in the authorized keys. - * @param authorized_keys The keys to look through. - * @param authorized_key The key to look for. - * @return The iterator to the location of the authorized key, or \c authorized_keys.end(). - */ -static auto FindKey(std::vector *authorized_keys, std::string_view authorized_key) -{ - return std::find_if(authorized_keys->begin(), authorized_keys->end(), [authorized_key](auto &value) { return StrEqualsIgnoreCase(value, authorized_key); }); -} - DEF_CONSOLE_CMD(ConNetworkAuthorizedKey) { if (argc <= 2) { @@ -2016,11 +2005,8 @@ DEF_CONSOLE_CMD(ConNetworkAuthorizedKey) } } - auto iter = FindKey(authorized_keys, authorized_key); - if (StrEqualsIgnoreCase(argv[1], "add")) { - if (iter == authorized_keys->end()) { - authorized_keys->push_back(authorized_key); + if (authorized_keys->Add(authorized_key)) { IConsolePrint(CC_INFO, "Added {} to {}.", authorized_key, name); } else { IConsolePrint(CC_WARNING, "Not added {} to {} as it already exists.", authorized_key, name); @@ -2029,8 +2015,7 @@ DEF_CONSOLE_CMD(ConNetworkAuthorizedKey) } if (StrEqualsIgnoreCase(argv[1], "remove")) { - if (iter != authorized_keys->end()) { - authorized_keys->erase(iter); + if (authorized_keys->Remove(authorized_key)) { IConsolePrint(CC_INFO, "Removed {} from {}.", authorized_key, name); } else { IConsolePrint(CC_WARNING, "Not removed {} from {} as it does not exist.", authorized_key, name); diff --git a/src/network/network.cpp b/src/network/network.cpp index 784c5a8f37..717cf077dc 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -134,6 +134,57 @@ NetworkClientInfo::~NetworkClientInfo() return nullptr; } + +/** + * Simple helper to find the location of the given authorized key in the authorized keys. + * @param authorized_keys The keys to look through. + * @param authorized_key The key to look for. + * @return The iterator to the location of the authorized key, or \c authorized_keys.end(). + */ +static auto FindKey(auto *authorized_keys, std::string_view authorized_key) +{ + return std::find_if(authorized_keys->begin(), authorized_keys->end(), [authorized_key](auto &value) { return StrEqualsIgnoreCase(value, authorized_key); }); +} + +/** + * Check whether the given key is contains in these authorized keys. + * @param key The key to look for. + * @return \c true when the key has been found, otherwise \c false. + */ +bool NetworkAuthorizedKeys::Contains(std::string_view key) const +{ + return FindKey(this, key) != this->end(); +} + +/** + * Add the given key to the authorized keys, when it is not already contained. + * @param key The key to add. + * @return \c true when the key was added, \c false when the key already existed. + */ +bool NetworkAuthorizedKeys::Add(std::string_view key) +{ + auto iter = FindKey(this, key); + if (iter != this->end()) return false; + + this->emplace_back(key); + return true; +} + +/** + * Remove the given key from the authorized keys, when it is exists. + * @param key The key to remove. + * @return \c true when the key was removed, \c false when the key did not exist. + */ +bool NetworkAuthorizedKeys::Remove(std::string_view key) +{ + auto iter = FindKey(this, key); + if (iter == this->end()) return false; + + this->erase(iter); + return true; +} + + uint8_t NetworkSpectatorCount() { uint8_t count = 0; diff --git a/src/network/network_crypto.cpp b/src/network/network_crypto.cpp index 7c56a1d988..03ee988bb7 100644 --- a/src/network/network_crypto.cpp +++ b/src/network/network_crypto.cpp @@ -423,14 +423,6 @@ void CombinedAuthenticationServerHandler::Add(CombinedAuthenticationServerHandle this->SendResponse(); } -/* virtual */ bool NetworkAuthenticationDefaultAuthorizedKeyHandler::IsAllowed(std::string_view peer_public_key) const -{ - for (const auto &allowed : *this->authorized_keys) { - if (StrEqualsIgnoreCase(allowed, peer_public_key)) return true; - } - return false; -} - /** * Create a NetworkAuthenticationClientHandler. diff --git a/src/network/network_crypto.h b/src/network/network_crypto.h index 60e2b6b71b..d2fc604cd0 100644 --- a/src/network/network_crypto.h +++ b/src/network/network_crypto.h @@ -33,6 +33,8 @@ #ifndef NETWORK_CRYPTO_H #define NETWORK_CRYPTO_H +#include "network_type.h" + /** * Base class for handling the encryption (or decryption) of a network connection. */ @@ -158,16 +160,16 @@ public: */ class NetworkAuthenticationDefaultAuthorizedKeyHandler : public NetworkAuthenticationAuthorizedKeyHandler { private: - const std::vector *authorized_keys; ///< The authorized keys to check against. + const NetworkAuthorizedKeys *authorized_keys; ///< The authorized keys to check against. public: /** * Create the handler that uses the given authorized keys to check against. * @param authorized_keys The reference to the authorized keys to check against. */ - NetworkAuthenticationDefaultAuthorizedKeyHandler(const std::vector &authorized_keys) : authorized_keys(&authorized_keys) {} + NetworkAuthenticationDefaultAuthorizedKeyHandler(const NetworkAuthorizedKeys &authorized_keys) : authorized_keys(&authorized_keys) {} bool CanBeUsed() const override { return !this->authorized_keys->empty(); } - bool IsAllowed(std::string_view peer_public_key) const override; + bool IsAllowed(std::string_view peer_public_key) const override { return authorized_keys->Contains(peer_public_key); } }; diff --git a/src/network/network_type.h b/src/network/network_type.h index faa81a8d35..a3c0f47e74 100644 --- a/src/network/network_type.h +++ b/src/network/network_type.h @@ -150,4 +150,17 @@ enum NetworkErrorCode { NETWORK_ERROR_END, }; +/** + * Simple helper to (more easily) manage authorized keys. + * + * The authorized keys are hexadecimal representations of their binary form. + * The authorized keys are case insensitive. + */ +class NetworkAuthorizedKeys : public std::vector { +public: + bool Contains(std::string_view key) const; + bool Add(std::string_view key); + bool Remove(std::string_view key); +}; + #endif /* NETWORK_TYPE_H */ diff --git a/src/settings_type.h b/src/settings_type.h index 17941ae0a4..017a74664e 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -313,9 +313,9 @@ struct NetworkSettings { std::string server_invite_code_secret; ///< Secret to proof we got this invite code from the Game Coordinator. std::string server_name; ///< name of the server std::string server_password; ///< password for joining this server - std::vector server_authorized_keys; ///< Public keys of clients that are authorized to connect to the game. + NetworkAuthorizedKeys server_authorized_keys; ///< Public keys of clients that are authorized to connect to the game. std::string rcon_password; ///< password for rconsole (server side) - std::vector rcon_authorized_keys; ///< Public keys of clients that are authorized to use the rconsole (server side). + NetworkAuthorizedKeys rcon_authorized_keys; ///< Public keys of clients that are authorized to use the rconsole (server side). std::string admin_password; ///< password for the admin network std::string client_name; ///< name of the player (as client) std::string client_secret_key; ///< The secret key of the client for authorized key logins. diff --git a/src/tests/test_network_crypto.cpp b/src/tests/test_network_crypto.cpp index 34cbefaf27..33838a6ac9 100644 --- a/src/tests/test_network_crypto.cpp +++ b/src/tests/test_network_crypto.cpp @@ -118,8 +118,8 @@ TEST_CASE("Authentication_PAKE") static void TestAuthenticationAuthorizedKey(const X25519SecretKey &client_secret_key, const X25519PublicKey &server_expected_public_key, NetworkAuthenticationServerHandler::ResponseResult expected_response_result) { - std::vector authorized_keys; - authorized_keys.emplace_back(FormatArrayAsHex(server_expected_public_key)); + NetworkAuthorizedKeys authorized_keys; + authorized_keys.Add(FormatArrayAsHex(server_expected_public_key)); NetworkAuthenticationDefaultAuthorizedKeyHandler authorized_key_handler(authorized_keys); X25519AuthorizedKeyServerHandler server(X25519SecretKey::CreateRandom(), &authorized_key_handler); @@ -151,15 +151,15 @@ TEST_CASE("Authentication_Combined") auto client_public_key = client_secret_key.CreatePublicKey(); std::string client_public_key_str = FormatArrayAsHex(client_public_key); - std::vector valid_authorized_keys; - valid_authorized_keys.emplace_back(client_public_key_str); + NetworkAuthorizedKeys valid_authorized_keys; + valid_authorized_keys.Add(client_public_key_str); NetworkAuthenticationDefaultAuthorizedKeyHandler valid_authorized_key_handler(valid_authorized_keys); - std::vector invalid_authorized_keys; - invalid_authorized_keys.emplace_back("not-a-valid-authorized-key"); + NetworkAuthorizedKeys invalid_authorized_keys; + invalid_authorized_keys.Add("not-a-valid-authorized-key"); NetworkAuthenticationDefaultAuthorizedKeyHandler invalid_authorized_key_handler(invalid_authorized_keys); - std::vector no_authorized_keys; + NetworkAuthorizedKeys no_authorized_keys; NetworkAuthenticationDefaultAuthorizedKeyHandler no_authorized_key_handler(no_authorized_keys); std::string no_password = "";