diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 5deb7c60..368c5e21 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -451,26 +451,26 @@ namespace http { s << "
\r\n"; } - static void ShowCommands (std::stringstream& s) + static void ShowCommands (std::stringstream& s, uint32_t token) { /* commands */ s << "Router Commands
\r\n"; - s << " Run peer test
\r\n"; + s << " Run peer test
\r\n"; //s << " Reload config
\r\n"; if (i2p::context.AcceptsTunnels ()) - s << " Decline transit tunnels
\r\n"; + s << " Decline transit tunnels
\r\n"; else - s << " Accept transit tunnels
\r\n"; + s << " Accept transit tunnels
\r\n"; #if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) if (Daemon.gracefulShutdownInterval) - s << " Cancel graceful shutdown
"; + s << " Cancel graceful shutdown
"; else - s << " Start graceful shutdown
\r\n"; + s << " Start graceful shutdown
\r\n"; #endif #ifdef WIN32_APP - s << " Graceful shutdown
\r\n"; + s << " Graceful shutdown
\r\n"; #endif - s << " Force shutdown
\r\n"; + s << " Force shutdown
\r\n"; } static void ShowTransitTunnels (std::stringstream& s) @@ -756,6 +756,7 @@ namespace http { SendReply (res, content); } + std::map HTTPConnection::m_Tokens; void HTTPConnection::HandlePage (const HTTPReq& req, HTTPRes& res, std::stringstream& s) { std::map params; @@ -771,7 +772,20 @@ namespace http { else if (page == HTTP_PAGE_TUNNELS) ShowTunnels (s); else if (page == HTTP_PAGE_COMMANDS) - ShowCommands (s); + { + uint32_t token; + RAND_bytes ((uint8_t *)&token, 4); + auto ts = i2p::util::GetSecondsSinceEpoch (); + for (auto it = m_Tokens.begin (); it != m_Tokens.end (); ) + { + if (ts > it->second + TOKEN_EXPIRATION_TIMEOUT) + it = m_Tokens.erase (it); + else + ++it; + } + m_Tokens[token] = ts; + ShowCommands (s, token); + } else if (page == HTTP_PAGE_TRANSIT_TUNNELS) ShowTransitTunnels (s); else if (page == HTTP_PAGE_LOCAL_DESTINATIONS) @@ -798,13 +812,19 @@ namespace http { void HTTPConnection::HandleCommand (const HTTPReq& req, HTTPRes& res, std::stringstream& s) { std::map params; - std::string cmd(""); URL url; url.parse(req.uri); url.parse_query(params); - cmd = params["cmd"]; + std::string token = params["token"]; + if (!token.empty () || m_Tokens.find (std::stoi (token)) == m_Tokens.end ()) + { + ShowError(s, "Invalid token"); + return; + } + + std::string cmd = params["cmd"]; if (cmd == HTTP_COMMAND_RUN_PEER_TEST) i2p::transport::transports.PeerTest (); else if (cmd == HTTP_COMMAND_RELOAD_CONFIG) diff --git a/HTTPServer.h b/HTTPServer.h index 4a32702d..ec56e08a 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -1,10 +1,20 @@ #ifndef HTTP_SERVER_H__ #define HTTP_SERVER_H__ -namespace i2p { -namespace http { - extern const char *itoopieFavicon; - const size_t HTTP_CONNECTION_BUFFER_SIZE = 8192; +#include +#include +#include +#include +#include +#include +#include "HTTP.h" + +namespace i2p +{ +namespace http +{ + const size_t HTTP_CONNECTION_BUFFER_SIZE = 8192; + const int TOKEN_EXPIRATION_TIMEOUT = 30; // in seconds class HTTPConnection: public std::enable_shared_from_this { @@ -35,6 +45,8 @@ namespace http { bool needAuth; std::string user; std::string pass; + + static std::map m_Tokens; // token->timestamp in seconds }; class HTTPServer