#include "init.h"
#include "util.h"
#include "sync.h"
-#include "ui_interface.h"
+#include "interface.h"
#include "base58.h"
#include "bitcoinrpc.h"
#include "db.h"
{ "submitblock", &submitblock, false, false },
{ "listsinceblock", &listsinceblock, false, false },
{ "dumpprivkey", &dumpprivkey, false, false },
- { "dumppem", &dumppem, true, false },
{ "dumpwallet", &dumpwallet, true, false },
{ "importwallet", &importwallet, false, false },
{ "importprivkey", &importprivkey, false, false },
{ "listmalleableviews", &listmalleableviews, false, false},
{ "dumpmalleablekey", &dumpmalleablekey, false, false},
{ "importmalleablekey", &importmalleablekey, true, false },
- { "encryptdata", &encryptdata, false, false },
- { "decryptdata", &decryptdata, false, false },
- { "encryptmessage", &encryptmessage, false, false },
- { "decryptmessage", &decryptmessage, false, false },
{ "sendalert", &sendalert, false, false},
};
return (*it).second;
}
-string rfc1123Time()
-{
- return DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", GetTime());
-}
-
-static string HTTPReply(int nStatus, const string& strMsg, bool keepalive)
-{
- if (nStatus == HTTP_UNAUTHORIZED)
- return strprintf("HTTP/1.0 401 Authorization Required\r\n"
- "Date: %s\r\n"
- "Server: novacoin-json-rpc/%s\r\n"
- "WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n"
- "Content-Type: text/html\r\n"
- "Content-Length: 296\r\n"
- "\r\n"
- "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n"
- "\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">\r\n"
- "<HTML>\r\n"
- "<HEAD>\r\n"
- "<TITLE>Error</TITLE>\r\n"
- "<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=ISO-8859-1'>\r\n"
- "</HEAD>\r\n"
- "<BODY><H1>401 Unauthorized.</H1></BODY>\r\n"
- "</HTML>\r\n", rfc1123Time().c_str(), FormatFullVersion().c_str());
- const char *cStatus;
- if (nStatus == HTTP_OK) cStatus = "OK";
- else if (nStatus == HTTP_BAD_REQUEST) cStatus = "Bad Request";
- else if (nStatus == HTTP_FORBIDDEN) cStatus = "Forbidden";
- else if (nStatus == HTTP_NOT_FOUND) cStatus = "Not Found";
- else if (nStatus == HTTP_INTERNAL_SERVER_ERROR) cStatus = "Internal Server Error";
- else cStatus = "";
- return strprintf(
- "HTTP/1.1 %d %s\r\n"
- "Date: %s\r\n"
- "Connection: %s\r\n"
- "Content-Length: %" PRIszu "\r\n"
- "Content-Type: application/json\r\n"
- "Server: novacoin-json-rpc/%s\r\n"
- "\r\n"
- "%s",
- nStatus,
- cStatus,
- rfc1123Time().c_str(),
- keepalive ? "keep-alive" : "close",
- strMsg.size(),
- FormatFullVersion().c_str(),
- strMsg.c_str());
-}
-
-int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto)
-{
- string str;
- getline(stream, str);
- vector<string> vWords;
- istringstream iss(str);
- copy(istream_iterator<string>(iss), istream_iterator<string>(), back_inserter(vWords));
- if (vWords.size() < 2)
- return HTTP_INTERNAL_SERVER_ERROR;
- proto = 0;
- const char *ver = strstr(str.c_str(), "HTTP/1.");
- if (ver != NULL)
- proto = atoi(ver+7);
- return atoi(vWords[1].c_str());
-}
-
-int ReadHTTPHeader(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet)
-{
- int nLen = 0;
- for ( ; ; )
- {
- string str;
- std::getline(stream, str);
- if (str.empty() || str == "\r")
- break;
- string::size_type nColon = str.find(":");
- if (nColon != string::npos)
- {
- string strHeader = str.substr(0, nColon);
- boost::trim(strHeader);
- boost::to_lower(strHeader);
- string strValue = str.substr(nColon+1);
- boost::trim(strValue);
- mapHeadersRet[strHeader] = strValue;
- if (strHeader == "content-length")
- nLen = atoi(strValue.c_str());
- }
- }
- return nLen;
-}
-
-int ReadHTTP(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet, string& strMessageRet)
-{
- mapHeadersRet.clear();
- strMessageRet.clear();
-
- // Read status
- int nProto = 0;
- int nStatus = ReadHTTPStatus(stream, nProto);
-
- // Read header
- int nLen = ReadHTTPHeader(stream, mapHeadersRet);
- if (nLen < 0 || nLen > (int)MAX_SIZE)
- return HTTP_INTERNAL_SERVER_ERROR;
-
- // Read message
- if (nLen > 0)
- {
- vector<char> vch(nLen);
- stream.read(&vch[0], nLen);
- strMessageRet = string(vch.begin(), vch.end());
- }
-
- string sConHdr = mapHeadersRet["connection"];
-
- if ((sConHdr != "close") && (sConHdr != "keep-alive"))
- {
- if (nProto >= 1)
- mapHeadersRet["connection"] = "keep-alive";
- else
- mapHeadersRet["connection"] = "close";
- }
-
- return nStatus;
-}
-
-bool HTTPAuthorized(map<string, string>& mapHeaders)
+bool HTTPAuthorized(ix::WebSocketHttpHeaders& mapHeaders)
{
string strAuth = mapHeaders["authorization"];
if (strAuth.substr(0,6) != "Basic ")
void StartRPCServer()
{
+ strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
+ if (mapArgs["-rpcpassword"].empty())
+ {
+ unsigned char rand_pwd[32];
+ RAND_bytes(rand_pwd, 32);
+ string strWhatAmI = "To use novacoind";
+ if (mapArgs.count("-server"))
+ strWhatAmI = strprintf(_("To use the %s option"), "\"-server\"");
+ else if (mapArgs.count("-daemon"))
+ strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\"");
+ uiInterface.ThreadSafeMessageBox(strprintf(
+ _("%s, you must set a rpcpassword in the configuration file:\n %s\n"
+ "It is recommended you use the following random password:\n"
+ "rpcuser=novacoinrpc\n"
+ "rpcpassword=%s\n"
+ "(you do not need to remember this password)\n"
+ "If the file does not exist, create it with owner-readable-only file permissions.\n"),
+ strWhatAmI.c_str(),
+ GetConfigFile().string().c_str(),
+ EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str()),
+ _("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL);
+ StartShutdown();
+ return;
+ }
+
string host = GetArg("-rpchost", "127.0.0.1");
int port = GetArg("-rpcport", GetDefaultRPCPort());
g_server->setOnConnectionCallback([](ix::HttpRequestPtr request, std::shared_ptr<ix::ConnectionState> connectionState) -> ix::HttpResponsePtr {
ix::WebSocketHttpHeaders headers;
+ headers["Server"] = string("novacoin-json-rpc/") + FormatFullVersion();
+ headers["WWW-Authenticate"] = "Basic realm=\"jsonrpc\"";
+
+ if (!HTTPAuthorized(request->headers))
+ {
+ printf("ThreadRPCServer incorrect password attempt from %s\n", connectionState->getRemoteIp().c_str());
+ connectionState->setTerminated();
+ return std::make_shared<ix::HttpResponse>(401, "Unauthorized", ix::HttpErrorCode::Ok, headers, "Not authorized");
+ }
if (request->method != "POST") {
+ connectionState->setTerminated();
return std::make_shared<ix::HttpResponse>(400, "Bad request", ix::HttpErrorCode::Ok, headers, "Bad request");
}
return StartShutdown();
}
+ // Run listening thread
+ g_server->start();
+
// We're listening now
vnThreadsRunning[THREAD_RPCLISTENER]++;
}
"If the file does not exist, create it with owner-readable-only file permissions."),
GetConfigFile().string().c_str()));
+ // Init net subsystem
+ ix::initNetSystem();
+
// Create HTTP client
ix::HttpClient httpClient;
ix::HttpRequestArgsPtr args = httpClient.createRequest();