Line data Source code
1 : // Copyright (c) 2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2014 The Bitcoin Core developers
3 : // Distributed under the MIT software license, see the accompanying
4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 :
6 : #include "rpcprotocol.h"
7 :
8 : #include "random.h"
9 : #include "tinyformat.h"
10 : #include "util.h"
11 : #include "utilstrencodings.h"
12 : #include "utiltime.h"
13 : #include "version.h"
14 :
15 : #include <stdint.h>
16 : #include <fstream>
17 :
18 : using namespace std;
19 :
20 : /**
21 : * JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility,
22 : * but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were
23 : * unspecified (HTTP errors and contents of 'error').
24 : *
25 : * 1.0 spec: http://json-rpc.org/wiki/specification
26 : * 1.2 spec: http://jsonrpc.org/historical/json-rpc-over-http.html
27 : */
28 :
29 186 : string JSONRPCRequest(const string& strMethod, const UniValue& params, const UniValue& id)
30 : {
31 558 : UniValue request(UniValue::VOBJ);
32 558 : request.push_back(Pair("method", strMethod));
33 372 : request.push_back(Pair("params", params));
34 372 : request.push_back(Pair("id", id));
35 372 : return request.write() + "\n";
36 : }
37 :
38 3519 : UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id)
39 : {
40 10557 : UniValue reply(UniValue::VOBJ);
41 3519 : if (!error.isNull())
42 24 : reply.push_back(Pair("result", NullUniValue));
43 : else
44 7014 : reply.push_back(Pair("result", result));
45 7038 : reply.push_back(Pair("error", error));
46 7038 : reply.push_back(Pair("id", id));
47 3519 : return reply;
48 : }
49 :
50 3519 : string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id)
51 : {
52 3519 : UniValue reply = JSONRPCReplyObj(result, error, id);
53 7038 : return reply.write() + "\n";
54 : }
55 :
56 43 : UniValue JSONRPCError(int code, const string& message)
57 : {
58 129 : UniValue error(UniValue::VOBJ);
59 86 : error.push_back(Pair("code", code));
60 129 : error.push_back(Pair("message", message));
61 43 : return error;
62 : }
63 :
64 : /** Username used when cookie authentication is in use (arbitrary, only for
65 : * recognizability in debugging/logging purposes)
66 : */
67 378 : static const std::string COOKIEAUTH_USER = "__cookie__";
68 : /** Default name for auth cookie file */
69 378 : static const std::string COOKIEAUTH_FILE = ".cookie";
70 :
71 0 : boost::filesystem::path GetAuthCookieFile()
72 : {
73 0 : boost::filesystem::path path(GetArg("-rpccookiefile", COOKIEAUTH_FILE));
74 0 : if (!path.is_complete()) path = GetDataDir() / path;
75 0 : return path;
76 : }
77 :
78 0 : bool GenerateAuthCookie(std::string *cookie_out)
79 : {
80 : unsigned char rand_pwd[32];
81 0 : GetRandBytes(rand_pwd, 32);
82 0 : std::string cookie = COOKIEAUTH_USER + ":" + EncodeBase64(&rand_pwd[0],32);
83 :
84 : /** the umask determines what permissions are used to create this file -
85 : * these are set to 077 in init.cpp unless overridden with -sysperms.
86 : */
87 0 : std::ofstream file;
88 0 : boost::filesystem::path filepath = GetAuthCookieFile();
89 0 : file.open(filepath.string().c_str());
90 0 : if (!file.is_open()) {
91 0 : LogPrintf("Unable to open cookie authentication file %s for writing\n", filepath.string());
92 : return false;
93 : }
94 : file << cookie;
95 0 : file.close();
96 0 : LogPrintf("Generated RPC authentication cookie %s\n", filepath.string());
97 :
98 0 : if (cookie_out)
99 : *cookie_out = cookie;
100 : return true;
101 : }
102 :
103 0 : bool GetAuthCookie(std::string *cookie_out)
104 : {
105 0 : std::ifstream file;
106 : std::string cookie;
107 0 : boost::filesystem::path filepath = GetAuthCookieFile();
108 0 : file.open(filepath.string().c_str());
109 0 : if (!file.is_open())
110 : return false;
111 0 : std::getline(file, cookie);
112 0 : file.close();
113 :
114 0 : if (cookie_out)
115 : *cookie_out = cookie;
116 0 : return true;
117 : }
118 :
119 0 : void DeleteAuthCookie()
120 : {
121 : try {
122 0 : boost::filesystem::remove(GetAuthCookieFile());
123 0 : } catch (const boost::filesystem::filesystem_error& e) {
124 0 : LogPrintf("%s: Unable to remove random auth cookie file: %s\n", __func__, e.what());
125 : }
126 567 : }
127 :
|