mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 00:00:29 +03:00
I2PControl through SSL
This commit is contained in:
parent
d015538bb4
commit
c9d03a8094
@ -27,15 +27,24 @@ namespace client
|
|||||||
I2PControlService::I2PControlService (int port):
|
I2PControlService::I2PControlService (int port):
|
||||||
m_Password (I2P_CONTROL_DEFAULT_PASSWORD), m_IsRunning (false), m_Thread (nullptr),
|
m_Password (I2P_CONTROL_DEFAULT_PASSWORD), m_IsRunning (false), m_Thread (nullptr),
|
||||||
m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)),
|
m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)),
|
||||||
|
m_SSLContext (m_Service, boost::asio::ssl::context::sslv23),
|
||||||
m_ShutdownTimer (m_Service)
|
m_ShutdownTimer (m_Service)
|
||||||
{
|
{
|
||||||
|
// certificate
|
||||||
auto path = GetPath ();
|
auto path = GetPath ();
|
||||||
if (!boost::filesystem::exists (path))
|
if (!boost::filesystem::exists (path))
|
||||||
{
|
{
|
||||||
if (!boost::filesystem::create_directory (path))
|
if (!boost::filesystem::create_directory (path))
|
||||||
LogPrint (eLogError, "Failed to create i2pcontrol directory");
|
LogPrint (eLogError, "Failed to create i2pcontrol directory");
|
||||||
}
|
}
|
||||||
|
if (!boost::filesystem::exists (path / I2P_CONTROL_KEY_FILE) ||
|
||||||
|
!boost::filesystem::exists (path / I2P_CONTROL_CERT_FILE))
|
||||||
|
// create new certificate
|
||||||
|
CreateCertificate ();
|
||||||
|
m_SSLContext.use_certificate_chain_file ((path / I2P_CONTROL_CERT_FILE).string ());
|
||||||
|
m_SSLContext.use_private_key_file ((path / I2P_CONTROL_KEY_FILE).string (), boost::asio::ssl::context::pem);
|
||||||
|
|
||||||
|
// handlers
|
||||||
m_MethodHandlers[I2P_CONTROL_METHOD_AUTHENTICATE] = &I2PControlService::AuthenticateHandler;
|
m_MethodHandlers[I2P_CONTROL_METHOD_AUTHENTICATE] = &I2PControlService::AuthenticateHandler;
|
||||||
m_MethodHandlers[I2P_CONTROL_METHOD_ECHO] = &I2PControlService::EchoHandler;
|
m_MethodHandlers[I2P_CONTROL_METHOD_ECHO] = &I2PControlService::EchoHandler;
|
||||||
m_MethodHandlers[I2P_CONTROL_METHOD_I2PCONTROL] = &I2PControlService::I2PControlHandler;
|
m_MethodHandlers[I2P_CONTROL_METHOD_I2PCONTROL] = &I2PControlService::I2PControlHandler;
|
||||||
@ -108,27 +117,34 @@ namespace client
|
|||||||
|
|
||||||
void I2PControlService::Accept ()
|
void I2PControlService::Accept ()
|
||||||
{
|
{
|
||||||
auto newSocket = std::make_shared<boost::asio::ip::tcp::socket> (m_Service);
|
auto newSocket = std::make_shared<ssl_socket> (m_Service, m_SSLContext);
|
||||||
m_Acceptor.async_accept (*newSocket, std::bind (&I2PControlService::HandleAccept, this,
|
m_Acceptor.async_accept (newSocket->lowest_layer(), std::bind (&I2PControlService::HandleAccept, this,
|
||||||
std::placeholders::_1, newSocket));
|
std::placeholders::_1, newSocket));
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<boost::asio::ip::tcp::socket> socket)
|
void I2PControlService::HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<ssl_socket> socket)
|
||||||
{
|
{
|
||||||
if (ecode != boost::asio::error::operation_aborted)
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
Accept ();
|
Accept ();
|
||||||
|
|
||||||
if (!ecode)
|
if (!ecode)
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "New I2PControl request from ", socket->remote_endpoint ());
|
LogPrint (eLogInfo, "New I2PControl request from ", socket->lowest_layer ().remote_endpoint ());
|
||||||
std::this_thread::sleep_for (std::chrono::milliseconds(5));
|
boost::system::error_code ec;
|
||||||
ReadRequest (socket);
|
socket->handshake (boost::asio::ssl::stream_base::client, ec);
|
||||||
|
if (!ec)
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for (std::chrono::milliseconds(5));
|
||||||
|
ReadRequest (socket);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogError, "I2PControl handshake error: ", ecode.message ());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "I2PControl accept error: ", ecode.message ());
|
LogPrint (eLogError, "I2PControl accept error: ", ecode.message ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::ReadRequest (std::shared_ptr<boost::asio::ip::tcp::socket> socket)
|
void I2PControlService::ReadRequest (std::shared_ptr<ssl_socket> socket)
|
||||||
{
|
{
|
||||||
auto request = std::make_shared<I2PControlBuffer>();
|
auto request = std::make_shared<I2PControlBuffer>();
|
||||||
socket->async_read_some (
|
socket->async_read_some (
|
||||||
@ -142,7 +158,7 @@ namespace client
|
|||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::HandleRequestReceived (const boost::system::error_code& ecode,
|
void I2PControlService::HandleRequestReceived (const boost::system::error_code& ecode,
|
||||||
size_t bytes_transferred, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
size_t bytes_transferred, std::shared_ptr<ssl_socket> socket,
|
||||||
std::shared_ptr<I2PControlBuffer> buf)
|
std::shared_ptr<I2PControlBuffer> buf)
|
||||||
{
|
{
|
||||||
if (ecode)
|
if (ecode)
|
||||||
@ -218,7 +234,7 @@ namespace client
|
|||||||
ss << "\"" << name << "\":" << std::fixed << std::setprecision(2) << value;
|
ss << "\"" << name << "\":" << std::fixed << std::setprecision(2) << value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::SendResponse (std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
void I2PControlService::SendResponse (std::shared_ptr<ssl_socket> socket,
|
||||||
std::shared_ptr<I2PControlBuffer> buf, std::ostringstream& response, bool isHtml)
|
std::shared_ptr<I2PControlBuffer> buf, std::ostringstream& response, bool isHtml)
|
||||||
{
|
{
|
||||||
size_t len = response.str ().length (), offset = 0;
|
size_t len = response.str ().length (), offset = 0;
|
||||||
@ -245,11 +261,10 @@ namespace client
|
|||||||
}
|
}
|
||||||
|
|
||||||
void I2PControlService::HandleResponseSent (const boost::system::error_code& ecode, std::size_t bytes_transferred,
|
void I2PControlService::HandleResponseSent (const boost::system::error_code& ecode, std::size_t bytes_transferred,
|
||||||
std::shared_ptr<boost::asio::ip::tcp::socket> socket, std::shared_ptr<I2PControlBuffer> buf)
|
std::shared_ptr<ssl_socket> socket, std::shared_ptr<I2PControlBuffer> buf)
|
||||||
{
|
{
|
||||||
if (ecode)
|
if (ecode)
|
||||||
LogPrint (eLogError, "I2PControl write error: ", ecode.message ());
|
LogPrint (eLogError, "I2PControl write error: ", ecode.message ());
|
||||||
socket->close ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// handlers
|
// handlers
|
||||||
|
13
I2PControl.h
13
I2PControl.h
@ -10,6 +10,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
|
#include <boost/asio/ssl.hpp>
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <boost/property_tree/ptree.hpp>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@ -74,6 +75,7 @@ namespace client
|
|||||||
|
|
||||||
class I2PControlService
|
class I2PControlService
|
||||||
{
|
{
|
||||||
|
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
I2PControlService (int port);
|
I2PControlService (int port);
|
||||||
@ -86,14 +88,14 @@ namespace client
|
|||||||
|
|
||||||
void Run ();
|
void Run ();
|
||||||
void Accept ();
|
void Accept ();
|
||||||
void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<ssl_socket> socket);
|
||||||
void ReadRequest (std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
void ReadRequest (std::shared_ptr<ssl_socket> socket);
|
||||||
void HandleRequestReceived (const boost::system::error_code& ecode, size_t bytes_transferred,
|
void HandleRequestReceived (const boost::system::error_code& ecode, size_t bytes_transferred,
|
||||||
std::shared_ptr<boost::asio::ip::tcp::socket> socket, std::shared_ptr<I2PControlBuffer> buf);
|
std::shared_ptr<ssl_socket> socket, std::shared_ptr<I2PControlBuffer> buf);
|
||||||
void SendResponse (std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
void SendResponse (std::shared_ptr<ssl_socket> socket,
|
||||||
std::shared_ptr<I2PControlBuffer> buf, std::ostringstream& response, bool isHtml);
|
std::shared_ptr<I2PControlBuffer> buf, std::ostringstream& response, bool isHtml);
|
||||||
void HandleResponseSent (const boost::system::error_code& ecode, std::size_t bytes_transferred,
|
void HandleResponseSent (const boost::system::error_code& ecode, std::size_t bytes_transferred,
|
||||||
std::shared_ptr<boost::asio::ip::tcp::socket> socket, std::shared_ptr<I2PControlBuffer> buf);
|
std::shared_ptr<ssl_socket> socket, std::shared_ptr<I2PControlBuffer> buf);
|
||||||
|
|
||||||
boost::filesystem::path GetPath () const { return i2p::util::filesystem::GetDefaultDataDir() / I2P_CONTROL_PATH; };
|
boost::filesystem::path GetPath () const { return i2p::util::filesystem::GetDefaultDataDir() / I2P_CONTROL_PATH; };
|
||||||
void CreateCertificate ();
|
void CreateCertificate ();
|
||||||
@ -147,6 +149,7 @@ namespace client
|
|||||||
|
|
||||||
boost::asio::io_service m_Service;
|
boost::asio::io_service m_Service;
|
||||||
boost::asio::ip::tcp::acceptor m_Acceptor;
|
boost::asio::ip::tcp::acceptor m_Acceptor;
|
||||||
|
boost::asio::ssl::context m_SSLContext;
|
||||||
boost::asio::deadline_timer m_ShutdownTimer;
|
boost::asio::deadline_timer m_ShutdownTimer;
|
||||||
std::set<std::string> m_Tokens;
|
std::set<std::string> m_Tokens;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user