diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index 6224869405..41ba8a749b 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -505,6 +505,16 @@ Json::Value RPCParser::parseSignSubmit(const Json::Value& jvParams) return rpcError(rpcINVALID_PARAMS); } +// sms +Json::Value RPCParser::parseSMS(const Json::Value& jvParams) +{ + Json::Value jvRequest; + + jvRequest["text"] = jvParams[0u].asString(); + + return jvRequest; +} + // tx Json::Value RPCParser::parseTx(const Json::Value& jvParams) { @@ -669,6 +679,7 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) { "random", &RPCParser::parseAsIs, 0, 0 }, { "ripple_path_find", &RPCParser::parseRipplePathFind, 1, 2 }, { "sign", &RPCParser::parseSignSubmit, 2, 2 }, + { "sms", &RPCParser::parseSMS, 1, 1 }, { "submit", &RPCParser::parseSignSubmit, 1, 2 }, { "server_info", &RPCParser::parseAsIs, 0, 0 }, { "server_state", &RPCParser::parseAsIs, 0, 0 }, diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index 4bc3e8439d..5860069418 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -33,6 +33,7 @@ protected: Json::Value parseOwnerInfo(const Json::Value& jvParams); Json::Value parseRandom(const Json::Value& jvParams); Json::Value parseRipplePathFind(const Json::Value& jvParams); + Json::Value parseSMS(const Json::Value& jvParams); Json::Value parseSignSubmit(const Json::Value& jvParams); Json::Value parseTx(const Json::Value& jvParams); Json::Value parseTxHistory(const Json::Value& jvParams); diff --git a/src/cpp/ripple/Config.cpp b/src/cpp/ripple/Config.cpp index eb904eb594..d1e166cee5 100644 --- a/src/cpp/ripple/Config.cpp +++ b/src/cpp/ripple/Config.cpp @@ -45,6 +45,11 @@ #define SECTION_RPC_USER "rpc_user" #define SECTION_RPC_PASSWORD "rpc_password" #define SECTION_RPC_STARTUP "rpc_startup" +#define SECTION_SMS_FROM "sms_from" +#define SECTION_SMS_KEY "sms_key" +#define SECTION_SMS_SECRET "sms_secret" +#define SECTION_SMS_TO "sms_to" +#define SECTION_SMS_URL "sms_url" #define SECTION_SNTP "sntp_servers" #define SECTION_SSL_VERIFY "ssl_verify" #define SECTION_SSL_VERIFY_FILE "ssl_verify_file" @@ -473,6 +478,12 @@ void Config::load() if (sectionSingleB(secConfig, SECTION_ACCOUNT_PROBE_MAX, strTemp)) ACCOUNT_PROBE_MAX = boost::lexical_cast(strTemp); + (void) sectionSingleB(secConfig, SECTION_SMS_FROM, SMS_FROM); + (void) sectionSingleB(secConfig, SECTION_SMS_KEY, SMS_KEY); + (void) sectionSingleB(secConfig, SECTION_SMS_SECRET, SMS_SECRET); + (void) sectionSingleB(secConfig, SECTION_SMS_TO, SMS_TO); + (void) sectionSingleB(secConfig, SECTION_SMS_URL, SMS_URL); + if (sectionSingleB(secConfig, SECTION_VALIDATORS_FILE, strTemp)) VALIDATORS_FILE = strTemp; diff --git a/src/cpp/ripple/Config.h b/src/cpp/ripple/Config.h index f6e65856f5..2f31731e61 100644 --- a/src/cpp/ripple/Config.h +++ b/src/cpp/ripple/Config.h @@ -185,6 +185,12 @@ public: std::string SSL_VERIFY_FILE; std::string SSL_VERIFY_DIR; + std::string SMS_FROM; + std::string SMS_KEY; + std::string SMS_SECRET; + std::string SMS_TO; + std::string SMS_URL; + Config(); int getSize(SizedItemName); diff --git a/src/cpp/ripple/HttpsClient.cpp b/src/cpp/ripple/HttpsClient.cpp index 1144d98596..a2c5bb385b 100644 --- a/src/cpp/ripple/HttpsClient.cpp +++ b/src/cpp/ripple/HttpsClient.cpp @@ -443,4 +443,48 @@ void HttpsClient::httpsRequest( client->httpsRequest(bSSL, deqSites, setRequest, timeout, complete); } +#define SMS_TIMEOUT 30 + +bool responseSMS(const boost::system::error_code& ecResult, int iStatus, const std::string& strData) { + cLog(lsINFO) << "SMS: Response:" << iStatus << " :" << strData; + + return true; +} + +void HttpsClient::sendSMS(boost::asio::io_service& io_service, const std::string& strText) { + std::string strScheme; + std::string strDomain; + int iPort; + std::string strPath; + + if (theConfig.SMS_URL == "" || !parseUrl(theConfig.SMS_URL, strScheme, strDomain, iPort, strPath)) + { + cLog(lsWARNING) << "SMSRequest: Bad URL:" << theConfig.SMS_URL; + } + else + { + bool bSSL = strScheme == "https"; + + std::deque deqSites(1, strDomain); + std::string strURI = + boost::str(boost::format("%s?from=%s&to=%s&api_key=%s&api_secret=%s&text=%s") + % (strPath.empty() ? "/" : strPath) + % theConfig.SMS_FROM + % theConfig.SMS_TO + % theConfig.SMS_KEY + % theConfig.SMS_SECRET + % strText); + + // cLog(lsINFO) << "SMS: Request:" << strURI; + cLog(lsINFO) << "SMS: Request: '" << strText << "'"; + + if (iPort < 0) + iPort = bSSL ? 443 : 80; + + boost::shared_ptr client(new HttpsClient(io_service, iPort, CLIENT_MAX_HEADER)); + + client->httpsGet(bSSL, deqSites, strURI, boost::posix_time::seconds(SMS_TIMEOUT), + BIND_TYPE(&responseSMS, P_1, P_2, P_3)); + } +} // vim:ts=4 diff --git a/src/cpp/ripple/HttpsClient.h b/src/cpp/ripple/HttpsClient.h index 909594efe1..a433c0a9d2 100644 --- a/src/cpp/ripple/HttpsClient.h +++ b/src/cpp/ripple/HttpsClient.h @@ -116,6 +116,8 @@ public: std::size_t responseMax, boost::posix_time::time_duration timeout, FUNCTION_TYPE complete); + + static void sendSMS(boost::asio::io_service& io_service, const std::string& strText); }; #endif // vim:ts=4 diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index dc798aefa3..617ac3bc82 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -2235,6 +2235,15 @@ Json::Value RPCHandler::doUnlScore(Json::Value, int& cost) return "scoring requested"; } +Json::Value RPCHandler::doSMS(Json::Value jvRequest, int& cost) +{ + if (!jvRequest.isMember("text")) + return rpcError(rpcINVALID_PARAMS); + + HttpsClient::sendSMS(theApp->getIOService(), jvRequest["text"].asString()); + + return "sms dispatched"; +} Json::Value RPCHandler::doStop(Json::Value, int& cost) { theApp->stop(); @@ -3250,6 +3259,7 @@ Json::Value RPCHandler::doCommand(const Json::Value& jvRequest, int iRole, int & { "submit", &RPCHandler::doSubmit, false, optCurrent }, { "server_info", &RPCHandler::doServerInfo, false, optNone }, { "server_state", &RPCHandler::doServerState, false, optNone }, + { "sms", &RPCHandler::doSMS, true, optNone }, { "stop", &RPCHandler::doStop, true, optNone }, { "transaction_entry", &RPCHandler::doTransactionEntry, false, optCurrent }, { "tx", &RPCHandler::doTx, false, optNetwork }, diff --git a/src/cpp/ripple/RPCHandler.h b/src/cpp/ripple/RPCHandler.h index b716ebc55f..5ce16c45fd 100644 --- a/src/cpp/ripple/RPCHandler.h +++ b/src/cpp/ripple/RPCHandler.h @@ -76,6 +76,7 @@ class RPCHandler Json::Value doServerState(Json::Value params, int& cost); // for machines Json::Value doSessionClose(Json::Value params, int& cost); Json::Value doSessionOpen(Json::Value params, int& cost); + Json::Value doSMS(Json::Value params, int& cost); Json::Value doStop(Json::Value params, int& cost); Json::Value doSign(Json::Value params, int& cost); Json::Value doSubmit(Json::Value params, int& cost);