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.

protocol.cpp 3.8KB

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