diff -U2 -r /var/lib/copr-rpmbuild/results/i2pd-git/upstream-unpacked/Source0/i2pd-openssl/daemon/I2PControl.cpp /var/lib/copr-rpmbuild/results/i2pd-git/srpm-unpacked/i2pd-openssl.tar.gz-extract/i2pd-openssl/daemon/I2PControl.cpp --- /var/lib/copr-rpmbuild/results/i2pd-git/upstream-unpacked/Source0/i2pd-openssl/daemon/I2PControl.cpp 2026-08-23 18:38:37.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/i2pd-git/srpm-unpacked/i2pd-openssl.tar.gz-extract/i2pd-openssl/daemon/I2PControl.cpp 2026-08-23 18:32:20.000000000 +0000 @@ -12,6 +12,4 @@ #include #include -#include -#include // Use global placeholders from boost introduced when local_time.hpp is loaded @@ -21,5 +19,4 @@ #include "FS.h" -#include "Base.h" #include "Log.h" #include "Config.h" @@ -282,5 +279,5 @@ auto params = pt.get_child ("params"); if (method != "Authenticate" && - !IsValidToken (params.get ("Token", ""))) + !m_Tokens.count (params.get ("Token", ""))) { LogPrint (eLogWarning, "I2PControl: Invalid or missing token for method ", method); @@ -356,40 +353,16 @@ int api = params.get ("API"); auto password = params.get ("Password"); - LogPrint (eLogDebug, "I2PControl: Authenticate API=", api); - bool isValid = password.size () == m_Password.size () && - CRYPTO_memcmp (password.data (), m_Password.data (), m_Password.size ()) == 0; - if (!isValid) { - LogPrint (eLogError, "I2PControl: Authenticate - Invalid password"); + LogPrint (eLogDebug, "I2PControl: Authenticate API=", api, " Password=", password); + if (password != m_Password) { + LogPrint (eLogError, "I2PControl: Authenticate - Invalid password: ", password); return; } InsertParam (results, "API", api); results << ","; - uint8_t tokenBytes[32]; - RAND_bytes (tokenBytes, 32); - std::string token = i2p::data::ByteStreamToBase64 (tokenBytes, 32); - m_Tokens[token] = i2p::util::GetSecondsSinceEpoch () + I2P_CONTROL_TOKEN_LIFETIME; + std::string token = boost::lexical_cast(i2p::util::GetSecondsSinceEpoch ()); + m_Tokens.insert (token); InsertParam (results, "Token", token); } - bool I2PControlService::IsValidToken (const std::string& token) - { - uint64_t ts = i2p::util::GetSecondsSinceEpoch (); - for (auto it = m_Tokens.begin (); it != m_Tokens.end ();) - { - if (ts > it->second) - it = m_Tokens.erase (it); // expired - else - ++it; - } - bool found = false; - for (const auto& it: m_Tokens) - { - if (it.first.size () == token.size () && - CRYPTO_memcmp (it.first.data (), token.data (), token.size ()) == 0) - found = true; // don't short-circuit; keep timing independent of match position - } - return found; - } - void I2PControlService::EchoHandler (const boost::property_tree::ptree& params, std::ostringstream& results) { diff -U2 -r /var/lib/copr-rpmbuild/results/i2pd-git/upstream-unpacked/Source0/i2pd-openssl/daemon/I2PControl.h /var/lib/copr-rpmbuild/results/i2pd-git/srpm-unpacked/i2pd-openssl.tar.gz-extract/i2pd-openssl/daemon/I2PControl.h --- /var/lib/copr-rpmbuild/results/i2pd-git/upstream-unpacked/Source0/i2pd-openssl/daemon/I2PControl.h 2026-08-23 18:38:37.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/i2pd-git/srpm-unpacked/i2pd-openssl.tar.gz-extract/i2pd-openssl/daemon/I2PControl.h 2026-08-23 18:32:20.000000000 +0000 @@ -30,5 +30,4 @@ typedef std::array I2PControlBuffer; - const uint64_t I2P_CONTROL_TOKEN_LIFETIME = 60*60; // 1 hour, in seconds const long I2P_CONTROL_CERTIFICATE_VALIDITY = 365*10; // 10 years const char I2P_CONTROL_CERTIFICATE_COMMON_NAME[] = "i2pd.i2pcontrol"; @@ -97,6 +96,5 @@ boost::asio::ssl::context m_SSLContext; boost::asio::steady_timer m_ShutdownTimer; - std::map m_Tokens; // token -> expiration time in seconds since epoch - bool IsValidToken (const std::string& token); + std::set m_Tokens; std::map m_MethodHandlers;