You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
3.7 KiB

// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or
#include "rpc/protocol.h"
#include "random.h"
#include "tinyformat.h"
#include "util.h"
#include "utilstrencodings.h"
#include "utiltime.h"
#include "version.h"
#include <stdint.h>
#include <fstream>
* JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility,
* but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were
* unspecified (HTTP errors and contents of 'error').
* 1.0 spec:
* 1.2 spec:
UniValue JSONRPCRequestObj(const std::string& strMethod, const UniValue& params, const UniValue& id)
UniValue request(UniValue::VOBJ);
request.push_back(Pair("method", strMethod));
request.push_back(Pair("params", params));
request.push_back(Pair("id", id));
return request;
UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id)
UniValue reply(UniValue::VOBJ);
if (!error.isNull())
reply.push_back(Pair("result", NullUniValue));
reply.push_back(Pair("result", result));
reply.push_back(Pair("error", error));
reply.push_back(Pair("id", id));
return reply;
std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id)
UniValue reply = JSONRPCReplyObj(result, error, id);
return reply.write() + "\n";
UniValue JSONRPCError(int code, const std::string& message)
UniValue error(UniValue::VOBJ);
error.push_back(Pair("code", code));
error.push_back(Pair("message", message));
return error;
/** Username used when cookie authentication is in use (arbitrary, only for
* recognizability in debugging/logging purposes)
static const std::string COOKIEAUTH_USER = "__cookie__";
/** Default name for auth cookie file */
static const std::string COOKIEAUTH_FILE = ".cookie";
boost::filesystem::path GetAuthCookieFile()
boost::filesystem::path path(GetArg("-rpccookiefile", COOKIEAUTH_FILE));
if (!path.is_complete()) path = GetDataDir() / path;
return path;
bool GenerateAuthCookie(std::string *cookie_out)
const size_t COOKIE_SIZE = 32;
unsigned char rand_pwd[COOKIE_SIZE];
GetRandBytes(rand_pwd, COOKIE_SIZE);
std::string cookie = COOKIEAUTH_USER + ":" + HexStr(rand_pwd, rand_pwd+COOKIE_SIZE);
/** the umask determines what permissions are used to create this file -
* these are set to 077 in init.cpp unless overridden with -sysperms.
std::ofstream file;
boost::filesystem::path filepath = GetAuthCookieFile();;
if (!file.is_open()) {
LogPrintf("Unable to open cookie authentication file %s for writing\n", filepath.string());
return false;
file << cookie;
LogPrintf("Generated RPC authentication cookie %s\n", filepath.string());
if (cookie_out)
*cookie_out = cookie;
return true;
bool GetAuthCookie(std::string *cookie_out)
std::ifstream file;
std::string cookie;
boost::filesystem::path filepath = GetAuthCookieFile();;
if (!file.is_open())
return false;
std::getline(file, cookie);
if (cookie_out)
*cookie_out = cookie;
return true;
void DeleteAuthCookie()
try {
} catch (const boost::filesystem::filesystem_error& e) {
LogPrintf("%s: Unable to remove random auth cookie file: %s\n", __func__, e.what());