diff --git a/Builds/VisualStudio2012/RippleD.vcxproj b/Builds/VisualStudio2012/RippleD.vcxproj
index d3ab2c7e53..6af88cb577 100644
--- a/Builds/VisualStudio2012/RippleD.vcxproj
+++ b/Builds/VisualStudio2012/RippleD.vcxproj
@@ -31,12 +31,6 @@
true
true
-
- true
- true
- true
- true
-
true
true
@@ -1371,7 +1365,6 @@
-
diff --git a/Builds/VisualStudio2012/RippleD.vcxproj.filters b/Builds/VisualStudio2012/RippleD.vcxproj.filters
index 78b06af64d..a8f2710c79 100644
--- a/Builds/VisualStudio2012/RippleD.vcxproj.filters
+++ b/Builds/VisualStudio2012/RippleD.vcxproj.filters
@@ -849,9 +849,6 @@
[1] Ripple\ripple_app\boost
-
- [1] Ripple\ripple_app\boost
-
[1] Ripple\ripple_asio\sockets
@@ -1619,9 +1616,6 @@
[1] Ripple\ripple_app\boost
-
- [1] Ripple\ripple_app\boost
-
[1] Ripple\ripple_basics\utility
diff --git a/modules/ripple_app/boost/ripple_SslContext.cpp b/modules/ripple_app/boost/ripple_SslContext.cpp
deleted file mode 100644
index e3f66260b5..0000000000
--- a/modules/ripple_app/boost/ripple_SslContext.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-//------------------------------------------------------------------------------
-/*
- Copyright (c) 2011-2013, OpenCoin, Inc.
-*/
-//==============================================================================
-
-namespace basio
-{
-
-SslContext* SslContext::New ()
-{
- return new SslContext;
-}
-
-SslContext::~SslContext ()
-{
-}
-
-SslContext::operator boost::asio::ssl::context& ()
-{
- return *m_impl;
-}
-
-SslContext::SslContext ()
- : m_impl (new boost::asio::ssl::context (boost::asio::ssl::context::sslv23))
-{
-}
-
-// VFALCO TODO Can we call this function from the ctor of PeerDoor as well?
-// Or can we move the common code to a new function?
-//
-void SslContext::initializeFromFile (
- boost::asio::ssl::context& context,
- std::string key_file,
- std::string cert_file,
- std::string chain_file)
-{
- SSL_CTX* sslContext = context.native_handle ();
-
- context.set_options (boost::asio::ssl::context::default_workarounds |
- boost::asio::ssl::context::no_sslv2 |
- boost::asio::ssl::context::single_dh_use);
-
- bool cert_set = false;
-
- if (!cert_file.empty ())
- {
- boost::system::error_code error;
- context.use_certificate_file (cert_file, boost::asio::ssl::context::pem, error);
-
- if (error)
- throw std::runtime_error ("Unable to use certificate file");
-
- cert_set = true;
- }
-
- if (!chain_file.empty ())
- {
- // VFALCO Replace fopen() with RAII
- FILE* f = fopen (chain_file.c_str (), "r");
-
- if (!f)
- throw std::runtime_error ("Unable to open chain file");
-
- try
- {
- for (;;)
- {
- X509* x = PEM_read_X509 (f, NULL, NULL, NULL);
-
- if (x == NULL)
- break;
-
- if (!cert_set)
- {
- if (SSL_CTX_use_certificate (sslContext, x) != 1)
- throw std::runtime_error ("Unable to get certificate from chain file");
-
- cert_set = true;
- }
- else if (SSL_CTX_add_extra_chain_cert (sslContext, x) != 1)
- {
- X509_free (x);
- throw std::runtime_error ("Unable to add chain certificate");
- }
- }
-
- fclose (f);
- }
- catch (...)
- {
- fclose (f);
- throw;
- }
- }
-
- if (!key_file.empty ())
- {
- boost::system::error_code error;
- context.use_private_key_file (key_file, boost::asio::ssl::context::pem, error);
-
- if (error)
- throw std::runtime_error ("Unable to use private key file");
- }
-
- if (SSL_CTX_check_private_key (sslContext) != 1)
- throw std::runtime_error ("Private key not valid");
-}
-
-}
diff --git a/modules/ripple_app/boost/ripple_SslContext.h b/modules/ripple_app/boost/ripple_SslContext.h
deleted file mode 100644
index f19c01f707..0000000000
--- a/modules/ripple_app/boost/ripple_SslContext.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//------------------------------------------------------------------------------
-/*
- Copyright (c) 2011-2013, OpenCoin, Inc.
-*/
-//==============================================================================
-
-#ifndef RIPPLE_SSLCONTEXT_H_INCLUDED
-#define RIPPLE_SSLCONTEXT_H_INCLUDED
-
-namespace basio
-{
-
-/** Hides a boost::asio::ssl::context implementation.
-*/
-class SslContext
-{
-public:
- static SslContext* New ();
-
- virtual ~SslContext ();
-
- operator boost::asio::ssl::context& ();
-
- static void initializeFromFile (
- boost::asio::ssl::context& context,
- std::string key_file,
- std::string cert_file,
- std::string chain_file);
-
-private:
- SslContext ();
-
-private:
- beast::ScopedPointer m_impl;
-};
-
-}
-
-#endif
diff --git a/modules/ripple_app/main/ripple_Application.cpp b/modules/ripple_app/main/ripple_Application.cpp
index 7d233a5622..1ea5327085 100644
--- a/modules/ripple_app/main/ripple_Application.cpp
+++ b/modules/ripple_app/main/ripple_Application.cpp
@@ -577,7 +577,7 @@ public:
}
else
{
- m_wsSSLContext = RippleSSLContext::createBare ();
+ m_wsSSLContext = RippleSSLContext::createWebSocket ();
}
// Create private listening WebSocket socket
@@ -627,7 +627,7 @@ public:
{
try
{
- mRPCDoor = new RPCDoor (m_mainService, m_rpcServerHandler);
+ mRPCDoor = RPCDoor::New (m_mainService, m_rpcServerHandler);
}
catch (const std::exception& e)
{
diff --git a/modules/ripple_app/ripple_app.cpp b/modules/ripple_app/ripple_app.cpp
index 436bf6d74b..39b0bd5f7d 100644
--- a/modules/ripple_app/ripple_app.cpp
+++ b/modules/ripple_app/ripple_app.cpp
@@ -158,7 +158,6 @@ namespace ripple
#include "main/ripple_LocalCredentials.h"
#include "websocket/WSDoor.h"
#include "boost/ripple_IoService.h"
- #include "boost/ripple_SslContext.h"
#include "main/ripple_Application.h"
#include "rpc/RPCHandler.h"
#include "tx/TransactionQueue.h"
@@ -296,7 +295,6 @@ static const uint64 tenTo17m1 = tenTo17 - 1;
#include "data/ripple_DBInit.cpp"
#include "boost/ripple_IoService.cpp"
-#include "boost/ripple_SslContext.cpp"
#endif
@@ -334,7 +332,6 @@ static const uint64 tenTo17m1 = tenTo17 - 1;
#include "tx/PaymentTransactor.cpp"
#include "tx/RegularKeySetTransactor.cpp"
#include "paths/ripple_RippleState.cpp"
-#include "rpc/RPCDoor.cpp"
#include "tx/TransactionCheck.cpp"
#include "tx/TransactionMaster.cpp"
#include "tx/TransactionQueue.cpp"
@@ -354,16 +351,16 @@ static const uint64 tenTo17m1 = tenTo17 - 1;
namespace ripple
{
-#include "peers/ripple_Peer.cpp"
-#include "main/ripple_Application.cpp"
-#include "tx/OfferCreateTransactor.cpp"
-#include "misc/ripple_Validations.cpp"
-
-#include "main/ripple_LocalCredentials.cpp"
-#include "tx/WalletAddTransactor.cpp"
-#include "ledger/ripple_AcceptedLedgerTx.cpp"
-#include "misc/ripple_FeeVote.cpp"
#include "ledger/LedgerTiming.cpp"
+#include "ledger/ripple_AcceptedLedgerTx.cpp"
+#include "main/ripple_Application.cpp"
+#include "main/ripple_LocalCredentials.cpp"
+#include "misc/ripple_FeeVote.cpp"
+#include "misc/ripple_Validations.cpp"
+#include "peers/ripple_Peer.cpp"
+#include "rpc/RPCDoor.cpp"
+#include "tx/OfferCreateTransactor.cpp"
+#include "tx/WalletAddTransactor.cpp"
#endif
diff --git a/modules/ripple_app/rpc/RPCDoor.cpp b/modules/ripple_app/rpc/RPCDoor.cpp
index cb2233ddff..5997725b9a 100644
--- a/modules/ripple_app/rpc/RPCDoor.cpp
+++ b/modules/ripple_app/rpc/RPCDoor.cpp
@@ -6,96 +6,123 @@
SETUP_LOG (RPCDoor)
-RPCDoor::RPCDoor (boost::asio::io_service& io_service, RPCServer::Handler& handler)
- : m_rpcServerHandler (handler)
- , mAcceptor (io_service,
- boost::asio::ip::tcp::endpoint (boost::asio::ip::address::from_string (getConfig ().getRpcIP ()), getConfig ().getRpcPort ()))
- , mDelayTimer (io_service)
- , mSSLContext (boost::asio::ssl::context::sslv23)
+class RPCDoorImp : public RPCDoor, public LeakChecked
{
- WriteLog (lsINFO, RPCDoor) << "RPC port: " << getConfig ().getRpcAddress().toRawUTF8() << " allow remote: " << getConfig ().RPC_ALLOW_REMOTE;
-
- if (getConfig ().RPC_SECURE != 0)
+public:
+ RPCDoorImp (boost::asio::io_service& io_service, RPCServer::Handler& handler)
+ : m_rpcServerHandler (handler)
+ , mAcceptor (io_service,
+ boost::asio::ip::tcp::endpoint (boost::asio::ip::address::from_string (getConfig ().getRpcIP ()), getConfig ().getRpcPort ()))
+ , mDelayTimer (io_service)
+ , m_sslContext ((getConfig ().RPC_SECURE == 0) ?
+ RippleSSLContext::createBare () :
+ RippleSSLContext::createAuthenticated (
+ getConfig ().RPC_SSL_KEY,
+ getConfig ().RPC_SSL_CERT,
+ getConfig ().RPC_SSL_CHAIN))
{
- // VFALCO TODO This could be a method of theConfig
- //
- basio::SslContext::initializeFromFile (
- mSSLContext,
- getConfig ().RPC_SSL_KEY,
- getConfig ().RPC_SSL_CERT,
- getConfig ().RPC_SSL_CHAIN);
+ WriteLog (lsINFO, RPCDoor) << "RPC port: " << getConfig ().getRpcAddress().toRawUTF8() << " allow remote: " << getConfig ().RPC_ALLOW_REMOTE;
+
+ startListening ();
}
- startListening ();
-}
+ //--------------------------------------------------------------------------
-RPCDoor::~RPCDoor ()
-{
- WriteLog (lsINFO, RPCDoor) << "RPC port: " << getConfig ().getRpcAddress().toRawUTF8() << " allow remote: " << getConfig ().RPC_ALLOW_REMOTE;
-}
-
-void RPCDoor::startListening ()
-{
- RPCServer::pointer new_connection = RPCServer::New (mAcceptor.get_io_service (), mSSLContext, m_rpcServerHandler);
- mAcceptor.set_option (boost::asio::ip::tcp::acceptor::reuse_address (true));
-
- mAcceptor.async_accept (new_connection->getRawSocket (),
- boost::bind (&RPCDoor::handleConnect, this, new_connection,
- boost::asio::placeholders::error));
-}
-
-bool RPCDoor::isClientAllowed (const std::string& ip)
-{
- if (getConfig ().RPC_ALLOW_REMOTE)
- return true;
-
- // VFALCO TODO Represent ip addresses as a structure. Use isLoopback() member here
- //
- if (ip == "127.0.0.1")
- return true;
-
- return false;
-}
-
-void RPCDoor::handleConnect (RPCServer::pointer new_connection, const boost::system::error_code& error)
-{
- bool delay = false;
-
- if (!error)
+ ~RPCDoorImp ()
{
- // Restrict callers by IP
- try
+ WriteLog (lsINFO, RPCDoor) <<
+ "RPC port: " << getConfig ().getRpcAddress().toRawUTF8() <<
+ " allow remote: " << getConfig ().RPC_ALLOW_REMOTE;
+ }
+
+ //--------------------------------------------------------------------------
+
+ void startListening ()
+ {
+ RPCServer::pointer new_connection = RPCServer::New (
+ mAcceptor.get_io_service (), m_sslContext->get (), m_rpcServerHandler);
+
+ mAcceptor.set_option (boost::asio::ip::tcp::acceptor::reuse_address (true));
+
+ mAcceptor.async_accept (new_connection->getRawSocket (),
+ boost::bind (&RPCDoorImp::handleConnect, this, new_connection,
+ boost::asio::placeholders::error));
+ }
+
+ //--------------------------------------------------------------------------
+
+ bool isClientAllowed (const std::string& ip)
+ {
+ if (getConfig ().RPC_ALLOW_REMOTE)
+ return true;
+
+ // VFALCO TODO Represent ip addresses as a structure. Use isLoopback() member here
+ //
+ if (ip == "127.0.0.1")
+ return true;
+
+ return false;
+ }
+
+ //--------------------------------------------------------------------------
+
+ void handleConnect (RPCServer::pointer new_connection, boost::system::error_code const& error)
+ {
+ bool delay = false;
+
+ if (!error)
{
- if (! isClientAllowed (new_connection->getRemoteAddressText ()))
+ // Restrict callers by IP
+ // VFALCO NOTE Prevent exceptions from being thrown at all.
+ try
{
+ if (! isClientAllowed (new_connection->getRemoteAddressText ()))
+ {
+ startListening ();
+ return;
+ }
+ }
+ catch (...)
+ {
+ // client may have disconnected
startListening ();
return;
}
+
+ new_connection->getSocket ().async_handshake (AutoSocket::ssl_socket::server,
+ boost::bind (&RPCServer::connected, new_connection));
}
- catch (...)
+ else
{
- // client may have disconnected
- startListening ();
- return;
+ if (error == boost::system::errc::too_many_files_open)
+ delay = true;
+
+ WriteLog (lsINFO, RPCDoor) << "RPCDoorImp::handleConnect Error: " << error;
}
- new_connection->getSocket ().async_handshake (AutoSocket::ssl_socket::server,
- boost::bind (&RPCServer::connected, new_connection));
- }
- else
- {
- if (error == boost::system::errc::too_many_files_open)
- delay = true;
-
- WriteLog (lsINFO, RPCDoor) << "RPCDoor::handleConnect Error: " << error;
+ if (delay)
+ {
+ mDelayTimer.expires_from_now (boost::posix_time::milliseconds (1000));
+ mDelayTimer.async_wait (boost::bind (&RPCDoorImp::startListening, this));
+ }
+ else
+ {
+ startListening ();
+ }
}
- if (delay)
- {
- mDelayTimer.expires_from_now (boost::posix_time::milliseconds (1000));
- mDelayTimer.async_wait (boost::bind (&RPCDoor::startListening, this));
- }
- else
- startListening ();
+private:
+ RPCServer::Handler& m_rpcServerHandler;
+ boost::asio::ip::tcp::acceptor mAcceptor;
+ boost::asio::deadline_timer mDelayTimer;
+ ScopedPointer m_sslContext;
+};
+
+//------------------------------------------------------------------------------
+
+RPCDoor* RPCDoor::New (boost::asio::io_service& io_service, RPCServer::Handler& handler)
+{
+ ScopedPointer result (new RPCDoorImp (io_service, handler));
+
+ return result.release ();
}
-// vim:ts=4
diff --git a/modules/ripple_app/rpc/RPCDoor.h b/modules/ripple_app/rpc/RPCDoor.h
index c9d1562e69..4990da43b4 100644
--- a/modules/ripple_app/rpc/RPCDoor.h
+++ b/modules/ripple_app/rpc/RPCDoor.h
@@ -7,29 +7,14 @@
#ifndef RIPPLE_RPCDOOR_H
#define RIPPLE_RPCDOOR_H
-/*
-Handles incoming connections from people making RPC Requests
+/** Listening socket for RPC requests.
*/
-
-class RPCDoor : LeakChecked
+class RPCDoor
{
public:
- explicit RPCDoor (
- boost::asio::io_service& io_service,
- RPCServer::Handler& handler);
- ~RPCDoor ();
+ static RPCDoor* New (boost::asio::io_service& io_service, RPCServer::Handler& handler);
-private:
- RPCServer::Handler& m_rpcServerHandler;
- boost::asio::ip::tcp::acceptor mAcceptor;
- boost::asio::deadline_timer mDelayTimer;
- boost::asio::ssl::context mSSLContext;
-
- void startListening ();
- void handleConnect (RPCServer::pointer new_connection,
- const boost::system::error_code& error);
-
- bool isClientAllowed (const std::string& ip);
+ virtual ~RPCDoor () { }
};
#endif
diff --git a/modules/ripple_asio/sockets/RippleSSLContext.cpp b/modules/ripple_asio/sockets/RippleSSLContext.cpp
index 0ef7159c3f..1dd1dbcce5 100644
--- a/modules/ripple_asio/sockets/RippleSSLContext.cpp
+++ b/modules/ripple_asio/sockets/RippleSSLContext.cpp
@@ -14,14 +14,6 @@ public:
: RippleSSLContext (m_context)
, m_context (boost::asio::ssl::context::sslv23)
{
- m_context.set_options (
- boost::asio::ssl::context::default_workarounds |
- boost::asio::ssl::context::no_sslv2 |
- boost::asio::ssl::context::single_dh_use);
-
- SSL_CTX_set_tmp_dh_callback (
- m_context.native_handle (),
- tmp_dh_handler);
}
~RippleSSLContextImp ()
@@ -70,8 +62,25 @@ public:
//--------------------------------------------------------------------------
+ // Does common initialization for all but the bare context type.
+ void initCommon ()
+ {
+ m_context.set_options (
+ boost::asio::ssl::context::default_workarounds |
+ boost::asio::ssl::context::no_sslv2 |
+ boost::asio::ssl::context::single_dh_use);
+
+ SSL_CTX_set_tmp_dh_callback (
+ m_context.native_handle (),
+ tmp_dh_handler);
+ }
+
+ //--------------------------------------------------------------------------
+
void initAnonymous (String const& cipherList)
{
+ initCommon ();
+
int const result = SSL_CTX_set_cipher_list (
m_context.native_handle (),
cipherList.toStdString ().c_str ());
@@ -85,6 +94,8 @@ public:
void initAuthenticated (
std::string key_file, std::string cert_file, std::string chain_file)
{
+ initCommon ();
+
SSL_CTX* const ssl = m_context.native_handle ();
bool cert_set = false;
@@ -241,6 +252,7 @@ RippleSSLContext::RippleSSLContext (ContextType& context)
: SSLContext (context)
{
}
+
RippleSSLContext* RippleSSLContext::createBare ()
{
ScopedPointer context (new RippleSSLContextImp ());
@@ -248,6 +260,15 @@ RippleSSLContext* RippleSSLContext::createBare ()
return context.release ();
}
+RippleSSLContext* RippleSSLContext::createWebSocket ()
+{
+ ScopedPointer context (new RippleSSLContextImp ());
+
+ context->initCommon ();
+
+ return context.release ();
+}
+
RippleSSLContext* RippleSSLContext::createAnonymous (String const& cipherList)
{
ScopedPointer context (new RippleSSLContextImp ());
diff --git a/modules/ripple_asio/sockets/RippleSSLContext.h b/modules/ripple_asio/sockets/RippleSSLContext.h
index 6310450b47..48f7ff47d2 100644
--- a/modules/ripple_asio/sockets/RippleSSLContext.h
+++ b/modules/ripple_asio/sockets/RippleSSLContext.h
@@ -25,11 +25,16 @@ public:
*/
static std::string getRawDHParams (int keySize);
- /** Creates a bare context.
- This is for WebSocket connections that don't use certificates.
+ /** Creates a bare SSL context with just sslv23 set.
+ This is used for RPC connections.
*/
static RippleSSLContext* createBare ();
+ /** Creates a suitable for WebSocket without authentication.
+ This is for WebSocket connections that don't use certificates.
+ */
+ static RippleSSLContext* createWebSocket ();
+
/** Create a context that allows anonymous connections.
No certificates are required. Peers use this context.
If the cipher list is invalid, a fatal error is raised.