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 4.0KB

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