diff --git a/newcoin.vcxproj b/newcoin.vcxproj index 5b3889f069..83c3483efb 100644 --- a/newcoin.vcxproj +++ b/newcoin.vcxproj @@ -143,6 +143,7 @@ + @@ -184,6 +185,7 @@ + @@ -295,6 +297,17 @@ + + + + + + + + + + + diff --git a/newcoin.vcxproj.filters b/newcoin.vcxproj.filters index f8070562c7..f7dfc590ef 100644 --- a/newcoin.vcxproj.filters +++ b/newcoin.vcxproj.filters @@ -31,6 +31,9 @@ {92775c5f-dc9f-4a97-a9a6-6d4bd4e424b4} + + {cd4c41c0-3ee6-49f8-8322-d11422b892f9} + @@ -351,6 +354,12 @@ Source Files + + Source Files + + + Source Files + @@ -656,6 +665,39 @@ Header Files + + Header Files\websocket + + + Header Files\websocket + + + Header Files\websocket + + + Header Files\websocket + + + Header Files\websocket + + + Header Files\websocket + + + Header Files\websocket + + + Header Files\websocket + + + Header Files\websocket + + + Header Files\websocket + + + Header Files\websocket + diff --git a/src/cpp/ripple/Config.cpp b/src/cpp/ripple/Config.cpp index 03c5453321..8ada3d6070 100644 --- a/src/cpp/ripple/Config.cpp +++ b/src/cpp/ripple/Config.cpp @@ -39,6 +39,8 @@ #define SECTION_WEBSOCKET_PUBLIC_PORT "websocket_public_port" #define SECTION_WEBSOCKET_IP "websocket_ip" #define SECTION_WEBSOCKET_PORT "websocket_port" +#define SECTION_WEBSOCKET_SECURE "websocket_secure" +#define SECTION_WEBSOCKET_SSL_CERT "websocket_ssl_cert" #define SECTION_VALIDATORS "validators" #define SECTION_VALIDATORS_SITE "validators_site" @@ -134,6 +136,7 @@ void Config::setup(const std::string& strConf, bool bQuiet) RPC_PORT = 5001; WEBSOCKET_PORT = SYSTEM_WEBSOCKET_PORT; WEBSOCKET_PUBLIC_PORT = SYSTEM_WEBSOCKET_PUBLIC_PORT; + WEBSOCKET_SECURE = false; NUMBER_CONNECTIONS = 30; // a new ledger every minute @@ -256,6 +259,12 @@ void Config::load() if (sectionSingleB(secConfig, SECTION_WEBSOCKET_PUBLIC_PORT, strTemp)) WEBSOCKET_PUBLIC_PORT = boost::lexical_cast(strTemp); + if (sectionSingleB(secConfig, SECTION_WEBSOCKET_SECURE, strTemp)) + WEBSOCKET_SECURE = boost::lexical_cast(strTemp); + + sectionSingleB(secConfig, SECTION_WEBSOCKET_SSL_CERT, WEBSOCKET_SSL_CERT); + + if (sectionSingleB(secConfig, SECTION_VALIDATION_SEED, strTemp)) { VALIDATION_SEED.setSeedGeneric(strTemp); diff --git a/src/cpp/ripple/Config.h b/src/cpp/ripple/Config.h index b7e4898c03..b8094a1481 100644 --- a/src/cpp/ripple/Config.h +++ b/src/cpp/ripple/Config.h @@ -91,6 +91,8 @@ public: std::string WEBSOCKET_IP; int WEBSOCKET_PORT; + bool WEBSOCKET_SECURE; + std::string WEBSOCKET_SSL_CERT; // RPC parameters std::string RPC_IP; diff --git a/src/cpp/ripple/WSConnection.cpp b/src/cpp/ripple/WSConnection.cpp index f217f07dae..136e7304d5 100644 --- a/src/cpp/ripple/WSConnection.cpp +++ b/src/cpp/ripple/WSConnection.cpp @@ -13,25 +13,25 @@ SETUP_LOG(); #include "../json/reader.h" #include "../json/writer.h" -WSConnection::~WSConnection() -{ - mNetwork.unsubTransactions(this); - mNetwork.unsubRTTransactions(this); - mNetwork.unsubLedger(this); - mNetwork.unsubServer(this); - mNetwork.unsubAccount(this, mSubAccountInfo, true); - mNetwork.unsubAccount(this, mSubAccountInfo, false); -} -void WSConnection::send(const Json::Value& jvObj) +//template +//WSConnection::~WSConnection() + +//template WSConnection::~WSConnection(); +//template WSConnection::~WSConnection(); + +template +void WSConnection::send(const Json::Value& jvObj) { mHandler->send(mConnection, jvObj); } +template void WSConnection::send(const Json::Value& jvObj); +template void WSConnection::send(const Json::Value& jvObj); // // Utilities // - +template Json::Value WSConnection::invokeCommand(Json::Value& jvRequest) { if (!jvRequest.isMember("command")) diff --git a/src/cpp/ripple/WSConnection.h b/src/cpp/ripple/WSConnection.h index 2bc4914d4c..d90ddab4f9 100644 --- a/src/cpp/ripple/WSConnection.h +++ b/src/cpp/ripple/WSConnection.h @@ -12,16 +12,17 @@ class WSServerHandler; // Storage for connection specific info // - Subscriptions // +template class WSConnection : public InfoSub { public: - typedef websocketpp::WSDOOR_SERVER::handler::connection_ptr connection_ptr; - typedef websocketpp::WSDOOR_SERVER::handler::message_ptr message_ptr; + typedef typename endpoint_type::handler::connection_ptr connection_ptr; + typedef typename endpoint_type::handler::message_ptr message_ptr; protected: typedef void (WSConnection::*doFuncPtr)(Json::Value& jvResult, Json::Value &jvRequest); - WSServerHandler* mHandler; + WSServerHandler* mHandler; connection_ptr mConnection; NetworkOPs& mNetwork; @@ -30,17 +31,29 @@ public: // : mHandler((WSServerHandler*)(NULL)), // mConnection(connection_ptr()) { ; } - WSConnection(WSServerHandler* wshpHandler, connection_ptr cpConnection) + WSConnection(WSServerHandler* wshpHandler, connection_ptr cpConnection) : mHandler(wshpHandler), mConnection(cpConnection), mNetwork(theApp->getOPs()) { ; } - virtual ~WSConnection(); + + virtual ~WSConnection() + { + mNetwork.unsubTransactions(this); + mNetwork.unsubRTTransactions(this); + mNetwork.unsubLedger(this); + mNetwork.unsubServer(this); + mNetwork.unsubAccount(this, mSubAccountInfo, true); + mNetwork.unsubAccount(this, mSubAccountInfo, false); + } // Implement overridden functions from base class: + template void send(const Json::Value& jvObj); // Utilities + template Json::Value invokeCommand(Json::Value& jvRequest); }; + // vim:ts=4 diff --git a/src/cpp/ripple/WSDoor.cpp b/src/cpp/ripple/WSDoor.cpp index 55e46b58a1..9bd25a2703 100644 --- a/src/cpp/ripple/WSDoor.cpp +++ b/src/cpp/ripple/WSDoor.cpp @@ -9,6 +9,7 @@ SETUP_LOG(); #include "utils.h" #include "WSConnection.h" #include "WSHandler.h" +#include "Config.h" #include "WSDoor.h" @@ -53,21 +54,42 @@ void WSDoor::startListening() SSL_CTX_set_tmp_dh_callback(mCtx->native_handle(), handleTmpDh); - // Construct a single handler for all requests. - websocketpp::WSDOOR_SERVER::handler::ptr handler(new WSServerHandler(mCtx, mPublic)); + if(theConfig.WEBSOCKET_SECURE) + { + // Construct a single handler for all requests. + websocketpp::server_tls::handler::ptr handler(new WSServerHandler(mCtx, mPublic)); - // Construct a websocket server. - mEndpoint = new websocketpp::WSDOOR_SERVER(handler); + // Construct a websocket server. + mSEndpoint = new websocketpp::server_tls(handler); - // mEndpoint->alog().unset_level(websocketpp::log::alevel::ALL); - // mEndpoint->elog().unset_level(websocketpp::log::elevel::ALL); + // mEndpoint->alog().unset_level(websocketpp::log::alevel::ALL); + // mEndpoint->elog().unset_level(websocketpp::log::elevel::ALL); - // Call the main-event-loop of the websocket server. - mEndpoint->listen( - boost::asio::ip::tcp::endpoint( - boost::asio::ip::address().from_string(mIp), mPort)); + // Call the main-event-loop of the websocket server. + mSEndpoint->listen( + boost::asio::ip::tcp::endpoint( + boost::asio::ip::address().from_string(mIp), mPort)); - delete mEndpoint; + delete mSEndpoint; + }else + { + // Construct a single handler for all requests. + websocketpp::server::handler::ptr handler(new WSServerHandler(mCtx, mPublic)); + + // Construct a websocket server. + mEndpoint = new websocketpp::server(handler); + + // mEndpoint->alog().unset_level(websocketpp::log::alevel::ALL); + // mEndpoint->elog().unset_level(websocketpp::log::elevel::ALL); + + // Call the main-event-loop of the websocket server. + mEndpoint->listen( + boost::asio::ip::tcp::endpoint( + boost::asio::ip::address().from_string(mIp), mPort)); + + delete mEndpoint; + } + } WSDoor* WSDoor::createWSDoor(const std::string& strIp, const int iPort, bool bPublic) diff --git a/src/cpp/ripple/WSDoor.h b/src/cpp/ripple/WSDoor.h index fe41d1bc5a..40c37815d1 100644 --- a/src/cpp/ripple/WSDoor.h +++ b/src/cpp/ripple/WSDoor.h @@ -10,16 +10,12 @@ #include #include -#if 1 -#define WSDOOR_SERVER server -#else -#define WSDOOR_SERVER server_tls -#endif - class WSDoor { private: - websocketpp::WSDOOR_SERVER* mEndpoint; + websocketpp::server* mEndpoint; + websocketpp::server_tls* mSEndpoint; + boost::thread* mThread; bool mPublic; std::string mIp; @@ -29,7 +25,7 @@ private: public: - WSDoor(const std::string& strIp, int iPort, bool bPublic) : mEndpoint(0), mThread(0), mPublic(bPublic), mIp(strIp), mPort(iPort) { ; } + WSDoor(const std::string& strIp, int iPort, bool bPublic) : mEndpoint(0), mSEndpoint(0), mThread(0), mPublic(bPublic), mIp(strIp), mPort(iPort) { ; } void stop(); diff --git a/src/cpp/ripple/WSHandler.h b/src/cpp/ripple/WSHandler.h index 9f4b23d5e6..6e2b40cf2c 100644 --- a/src/cpp/ripple/WSHandler.h +++ b/src/cpp/ripple/WSHandler.h @@ -2,7 +2,9 @@ #define __WSHANDLER__ #include "Application.h" +#include "Config.h" +template class WSConnection; // A single instance of this object is made. @@ -25,7 +27,7 @@ private: protected: boost::mutex mMapLock; // For each connection maintain an associated object to track subscriptions. - boost::unordered_map > mMap; + boost::unordered_map > > mMap; bool mPublic; public: @@ -33,10 +35,7 @@ public: bool getPublic() { return mPublic; }; - boost::shared_ptr on_tls_init() - { - return mCtx; - } + void send(connection_ptr cpClient, message_ptr mpMessage) { @@ -127,6 +126,31 @@ public: } } + boost::shared_ptr on_tls_init() + { + if(theConfig.WEBSOCKET_SECURE) + { + // create a tls context, init, and return. + boost::shared_ptr context(new boost::asio::ssl::context(boost::asio::ssl::context::tlsv1)); + try { + context->set_options(boost::asio::ssl::context::default_workarounds | + boost::asio::ssl::context::no_sslv2 | + boost::asio::ssl::context::single_dh_use); + context->set_password_callback(boost::bind(&type::get_password, this)); + context->use_certificate_chain_file(theConfig.WEBSOCKET_SSL_CERT); + context->use_private_key_file(theConfig.WEBSOCKET_SSL_CERT, boost::asio::ssl::context::pem); + //context->use_tmp_dh_file("../../src/ssl/dh512.pem"); + } catch (std::exception& e) { + std::cout << e.what() << std::endl; + } + return context; + }else + { + return mCtx; + } + + } + // Respond to http requests. void http(connection_ptr cpClient) {