#include "httprpc.h"
-#include "base58.h"
#include "chainparams.h"
#include "httpserver.h"
-#include "rpcprotocol.h"
-#include "rpcserver.h"
+#include "key_io.h"
+#include "rpc/protocol.h"
+#include "rpc/server.h"
#include "random.h"
#include "sync.h"
#include "util.h"
#include <boost/algorithm/string.hpp> // boost::trim
+// WWW-Authenticate to present with 401 Unauthorized response
+static const char *WWW_AUTH_HEADER_DATA = "Basic realm=\"jsonrpc\"";
+
/** Simple one-shot callback timer to be used by the RPC mechanism to e.g.
- * re-lock the wellet.
+ * re-lock the wallet.
*/
class HTTPRPCTimer : public RPCTimerBase
{
public:
- HTTPRPCTimer(struct event_base* eventBase, boost::function<void(void)>& func, int64_t seconds) : ev(eventBase, false, new Handler(func))
+ HTTPRPCTimer(struct event_base* eventBase, boost::function<void(void)>& func, int64_t millis) :
+ ev(eventBase, false, func)
{
- struct timeval tv = {seconds, 0};
+ struct timeval tv;
+ tv.tv_sec = millis/1000;
+ tv.tv_usec = (millis%1000)*1000;
ev.trigger(&tv);
}
private:
HTTPEvent ev;
-
- class Handler : public HTTPClosure
- {
- public:
- Handler(const boost::function<void(void)>& func) : func(func)
- {
- }
- private:
- boost::function<void(void)> func;
- void operator()() { func(); }
- };
};
class HTTPRPCTimerInterface : public RPCTimerInterface
{
return "HTTP";
}
- RPCTimerBase* NewTimer(boost::function<void(void)>& func, int64_t seconds)
+ RPCTimerBase* NewTimer(boost::function<void(void)>& func, int64_t millis)
{
- return new HTTPRPCTimer(base, func, seconds);
+ return new HTTPRPCTimer(base, func, millis);
}
private:
struct event_base* base;
// Check authorization
std::pair<bool, std::string> authHeader = req->GetHeader("authorization");
if (!authHeader.first) {
+ req->WriteHeader("WWW-Authenticate", WWW_AUTH_HEADER_DATA);
req->WriteReply(HTTP_UNAUTHORIZED);
return false;
}
shouldn't have their RPC port exposed. */
MilliSleep(250);
+ req->WriteHeader("WWW-Authenticate", WWW_AUTH_HEADER_DATA);
req->WriteReply(HTTP_UNAUTHORIZED);
return false;
}
// singleton request
if (valRequest.isObject()) {
jreq.parse(valRequest);
+
+ if (!RPCAuthorized(authHeader.second)) {
+ LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", req->GetPeer().ToString());
+ MilliSleep(250);
+
+ req->WriteHeader("WWW-Authenticate", WWW_AUTH_HEADER_DATA);
+ req->WriteReply(HTTP_UNAUTHORIZED);
+ return false;
+ }
+
+ extern bool printoutAPI;
+ if (printoutAPI == true)
+ {
+ printf("%s %s\n", jreq.strMethod.c_str(), jreq.params.write().c_str());
+ }
UniValue result = tableRPC.execute(jreq.strMethod, jreq.params);