mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 19:15:54 +00:00
Support secure RPC.
This commit is contained in:
@@ -7,11 +7,18 @@ SETUP_LOG (RPCDoor)
|
||||
using namespace std;
|
||||
using namespace boost::asio::ip;
|
||||
|
||||
extern void initSSLContext(boost::asio::ssl::context& context,
|
||||
std::string key_file, std::string cert_file, std::string chain_file);
|
||||
|
||||
RPCDoor::RPCDoor(boost::asio::io_service& io_service) :
|
||||
mAcceptor(io_service, tcp::endpoint(address::from_string(theConfig.RPC_IP), theConfig.RPC_PORT)),
|
||||
mDelayTimer(io_service)
|
||||
mDelayTimer(io_service), mSSLContext(boost::asio::ssl::context::sslv23)
|
||||
{
|
||||
WriteLog (lsINFO, RPCDoor) << "RPC port: " << theConfig.RPC_IP << " " << theConfig.RPC_PORT << " allow remote: " << theConfig.RPC_ALLOW_REMOTE;
|
||||
|
||||
if (theConfig.RPC_SECURE != 0)
|
||||
initSSLContext(mSSLContext, theConfig.RPC_SSL_KEY, theConfig.RPC_SSL_CERT, theConfig.RPC_SSL_CHAIN);
|
||||
|
||||
startListening();
|
||||
}
|
||||
|
||||
@@ -22,10 +29,10 @@ RPCDoor::~RPCDoor()
|
||||
|
||||
void RPCDoor::startListening()
|
||||
{
|
||||
RPCServer::pointer new_connection = RPCServer::create(mAcceptor.get_io_service(), &theApp->getOPs());
|
||||
RPCServer::pointer new_connection = RPCServer::create(mAcceptor.get_io_service(), mSSLContext, &theApp->getOPs());
|
||||
mAcceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
|
||||
|
||||
mAcceptor.async_accept(new_connection->getSocket(),
|
||||
mAcceptor.async_accept(new_connection->getRawSocket(),
|
||||
boost::bind(&RPCDoor::handleConnect, this, new_connection,
|
||||
boost::asio::placeholders::error));
|
||||
}
|
||||
@@ -41,8 +48,7 @@ bool RPCDoor::isClientAllowed(const std::string& ip)
|
||||
return false;
|
||||
}
|
||||
|
||||
void RPCDoor::handleConnect(RPCServer::pointer new_connection,
|
||||
const boost::system::error_code& error)
|
||||
void RPCDoor::handleConnect(RPCServer::pointer new_connection, const boost::system::error_code& error)
|
||||
{
|
||||
bool delay = false;
|
||||
if (!error)
|
||||
@@ -50,7 +56,7 @@ void RPCDoor::handleConnect(RPCServer::pointer new_connection,
|
||||
// Restrict callers by IP
|
||||
try
|
||||
{
|
||||
if (!isClientAllowed(new_connection->getSocket().remote_endpoint().address().to_string()))
|
||||
if (!isClientAllowed(new_connection->getRawSocket().remote_endpoint().address().to_string()))
|
||||
{
|
||||
startListening();
|
||||
return;
|
||||
@@ -62,7 +68,8 @@ void RPCDoor::handleConnect(RPCServer::pointer new_connection,
|
||||
return;
|
||||
}
|
||||
|
||||
new_connection->connected();
|
||||
new_connection->getSocket().async_handshake(AutoSocket::ssl_socket::server,
|
||||
boost::bind(&RPCServer::connected, new_connection));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -14,8 +14,9 @@ public:
|
||||
~RPCDoor ();
|
||||
|
||||
private:
|
||||
boost::asio::ip::tcp::acceptor mAcceptor;
|
||||
boost::asio::deadline_timer mDelayTimer;
|
||||
boost::asio::ip::tcp::acceptor mAcceptor;
|
||||
boost::asio::deadline_timer mDelayTimer;
|
||||
boost::asio::ssl::context mSSLContext;
|
||||
|
||||
void startListening();
|
||||
void handleConnect(RPCServer::pointer new_connection,
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
|
||||
SETUP_LOG (RPCServer)
|
||||
|
||||
RPCServer::RPCServer(boost::asio::io_service& io_service , NetworkOPs* nopNetwork)
|
||||
: mNetOps(nopNetwork), mSocket(io_service)
|
||||
RPCServer::RPCServer(boost::asio::io_service& io_service, boost::asio::ssl::context& context, NetworkOPs* nopNetwork)
|
||||
: mNetOps(nopNetwork), mSocket(io_service, context)
|
||||
{
|
||||
mRole = RPCHandler::GUEST;
|
||||
}
|
||||
@@ -52,6 +52,11 @@ void RPCServer::handle_read_req(const boost::system::error_code& e)
|
||||
boost::bind(&RPCServer::handle_write, shared_from_this(), boost::asio::placeholders::error));
|
||||
}
|
||||
|
||||
static void dummy_handler()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
void RPCServer::handle_read_line(const boost::system::error_code& e)
|
||||
{
|
||||
if (e)
|
||||
@@ -62,8 +67,7 @@ void RPCServer::handle_read_line(const boost::system::error_code& e)
|
||||
if (action == haDO_REQUEST)
|
||||
{ // request with no body
|
||||
WriteLog (lsWARNING, RPCServer) << "RPC HTTP request with no body";
|
||||
boost::system::error_code ignore_ec;
|
||||
mSocket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignore_ec);
|
||||
mSocket.async_shutdown(boost::bind(&dummy_handler));
|
||||
return;
|
||||
}
|
||||
else if (action == haREAD_LINE)
|
||||
@@ -78,8 +82,7 @@ void RPCServer::handle_read_line(const boost::system::error_code& e)
|
||||
if ((rLen < 0) || (rLen > RPC_MAXIMUM_QUERY))
|
||||
{
|
||||
WriteLog (lsWARNING, RPCServer) << "Illegal RPC request length " << rLen;
|
||||
boost::system::error_code ignore_ec;
|
||||
mSocket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignore_ec);
|
||||
mSocket.async_shutdown(boost::bind(&dummy_handler));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -99,10 +102,7 @@ void RPCServer::handle_read_line(const boost::system::error_code& e)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::system::error_code ignore_ec;
|
||||
mSocket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignore_ec);
|
||||
}
|
||||
mSocket.async_shutdown(boost::bind(&dummy_handler));
|
||||
}
|
||||
|
||||
std::string RPCServer::handleRequest(const std::string& requestStr)
|
||||
@@ -143,7 +143,7 @@ std::string RPCServer::handleRequest(const std::string& requestStr)
|
||||
|
||||
try
|
||||
{
|
||||
mRole = iAdminGet(jvRequest, mSocket.remote_endpoint().address().to_string());
|
||||
mRole = iAdminGet(jvRequest, mSocket.PlainSocket().remote_endpoint().address().to_string());
|
||||
}
|
||||
catch (...)
|
||||
{ // endpoint already disconnected
|
||||
@@ -187,10 +187,7 @@ void RPCServer::handle_write(const boost::system::error_code& e)
|
||||
{
|
||||
HTTPRequestAction action = mHTTPRequest.requestDone(false);
|
||||
if (action == haCLOSE_CONN)
|
||||
{
|
||||
boost::system::error_code ignored_ec;
|
||||
mSocket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
|
||||
}
|
||||
mSocket.async_shutdown(boost::bind(&dummy_handler));
|
||||
else
|
||||
{
|
||||
boost::asio::async_read_until(mSocket, mLineBuffer, "\r\n",
|
||||
|
||||
@@ -15,7 +15,7 @@ private:
|
||||
|
||||
NetworkOPs* mNetOps;
|
||||
|
||||
boost::asio::ip::tcp::socket mSocket;
|
||||
AutoSocket mSocket;
|
||||
|
||||
boost::asio::streambuf mLineBuffer;
|
||||
Blob mQueryVec;
|
||||
@@ -26,7 +26,7 @@ private:
|
||||
|
||||
int mRole;
|
||||
|
||||
RPCServer(boost::asio::io_service& io_service, NetworkOPs* nopNetwork);
|
||||
RPCServer(boost::asio::io_service& io_service, boost::asio::ssl::context& ssl_context, NetworkOPs* nopNetwork);
|
||||
|
||||
RPCServer(const RPCServer&); // no implementation
|
||||
RPCServer& operator=(const RPCServer&); // no implementation
|
||||
@@ -38,16 +38,21 @@ private:
|
||||
std::string handleRequest(const std::string& requestStr);
|
||||
|
||||
public:
|
||||
static pointer create(boost::asio::io_service& io_service, NetworkOPs* mNetOps)
|
||||
static pointer create(boost::asio::io_service& io_service, boost::asio::ssl::context& context, NetworkOPs* mNetOps)
|
||||
{
|
||||
return pointer(new RPCServer(io_service, mNetOps));
|
||||
return pointer(new RPCServer(io_service, context, mNetOps));
|
||||
}
|
||||
|
||||
boost::asio::ip::tcp::socket& getSocket()
|
||||
AutoSocket& getSocket()
|
||||
{
|
||||
return mSocket;
|
||||
}
|
||||
|
||||
boost::asio::ip::tcp::socket& getRawSocket()
|
||||
{
|
||||
return mSocket.PlainSocket();
|
||||
}
|
||||
|
||||
void connected();
|
||||
};
|
||||
|
||||
|
||||
@@ -54,6 +54,8 @@ public:
|
||||
|
||||
bool getPublic() { return mPublic; };
|
||||
|
||||
boost::asio::ssl::context& getASIOContext() { return *mCtx; }
|
||||
|
||||
static void ssend(connection_ptr cpClient, message_ptr mpMessage)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
#define SECTION_RPC_USER "rpc_user"
|
||||
#define SECTION_RPC_PASSWORD "rpc_password"
|
||||
#define SECTION_RPC_STARTUP "rpc_startup"
|
||||
#define SECTION_RPC_SECURE "rpc_secure"
|
||||
#define SECTION_RPC_SSL_CERT "rpc_ssl_cert"
|
||||
#define SECTION_RPC_SSL_CHAIN "rpc_ssl_chain"
|
||||
#define SECTION_RPC_SSL_KEY "rpc_ssl_key"
|
||||
#define SECTION_SMS_FROM "sms_from"
|
||||
#define SECTION_SMS_KEY "sms_key"
|
||||
#define SECTION_SMS_SECRET "sms_secret"
|
||||
@@ -198,6 +202,7 @@ Config::Config()
|
||||
|
||||
PEER_PORT = SYSTEM_PEER_PORT;
|
||||
RPC_PORT = 5001;
|
||||
RPC_SECURE = 0;
|
||||
WEBSOCKET_PORT = SYSTEM_WEBSOCKET_PORT;
|
||||
WEBSOCKET_PUBLIC_PORT = SYSTEM_WEBSOCKET_PUBLIC_PORT;
|
||||
WEBSOCKET_PUBLIC_SECURE = 1;
|
||||
@@ -408,6 +413,13 @@ void Config::load()
|
||||
sectionSingleB(secConfig, SECTION_WEBSOCKET_SSL_CHAIN, WEBSOCKET_SSL_CHAIN);
|
||||
sectionSingleB(secConfig, SECTION_WEBSOCKET_SSL_KEY, WEBSOCKET_SSL_KEY);
|
||||
|
||||
if (sectionSingleB(secConfig, SECTION_RPC_SECURE, strTemp))
|
||||
RPC_SECURE = boost::lexical_cast<int>(strTemp);
|
||||
sectionSingleB(secConfig, SECTION_RPC_SSL_CERT, RPC_SSL_CERT);
|
||||
sectionSingleB(secConfig, SECTION_RPC_SSL_CHAIN, RPC_SSL_CHAIN);
|
||||
sectionSingleB(secConfig, SECTION_RPC_SSL_KEY, RPC_SSL_KEY);
|
||||
|
||||
|
||||
sectionSingleB(secConfig, SECTION_SSL_VERIFY_FILE, SSL_VERIFY_FILE);
|
||||
sectionSingleB(secConfig, SECTION_SSL_VERIFY_DIR, SSL_VERIFY_DIR);
|
||||
if (sectionSingleB(secConfig, SECTION_SSL_VERIFY, strTemp))
|
||||
|
||||
@@ -137,6 +137,11 @@ public:
|
||||
bool RPC_ALLOW_REMOTE;
|
||||
Json::Value RPC_STARTUP;
|
||||
|
||||
int RPC_SECURE;
|
||||
std::string RPC_SSL_CERT;
|
||||
std::string RPC_SSL_CHAIN;
|
||||
std::string RPC_SSL_KEY;
|
||||
|
||||
// Path searching
|
||||
int PATH_SEARCH_SIZE;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user