- 654419ECFD3EDD29C679D32B361468AF54D64AF0AFECD287EEFF7FDFF775ED6D69AA06CADDDF9C2D0ABFF4E90947630617284ECA374AC5A4AD9B0B807AFD050B
+ BE601828DA9D44E686E4FB5341373A1559642121A92080BD9DDB223C7DCB2BAC08BA6236653645EB5A458D5FE05DE7B4FD14F590975477E952F5D667AE049ADC
bitcoin/src/bitcoinrpc.cpp
(12 . 12)(12 . 6)
5 #include <boost/iostreams/concepts.hpp>
6 #include <boost/iostreams/stream.hpp>
7 #include <boost/algorithm/string.hpp>
8 #ifdef USE_SSL
9 #include <boost/asio/ssl.hpp>
10 #include <boost/filesystem.hpp>
11 #include <boost/filesystem/fstream.hpp>
12 typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream;
13 #endif
14 #include "json/json_spirit_reader_template.h"
15 #include "json/json_spirit_writer_template.h"
16 #include "json/json_spirit_utils.h"
(2078 . 60)(2072 . 6)
18 return false;
19 }
20
21 #ifdef USE_SSL
22 //
23 // IOStream device that speaks SSL but can also speak non-SSL
24 //
25 class SSLIOStreamDevice : public iostreams::device<iostreams::bidirectional> {
26 public:
27 SSLIOStreamDevice(SSLStream &streamIn, bool fUseSSLIn) : stream(streamIn)
28 {
29 fUseSSL = fUseSSLIn;
30 fNeedHandshake = fUseSSLIn;
31 }
32
33 void handshake(ssl::stream_base::handshake_type role)
34 {
35 if (!fNeedHandshake) return;
36 fNeedHandshake = false;
37 stream.handshake(role);
38 }
39 std::streamsize read(char* s, std::streamsize n)
40 {
41 handshake(ssl::stream_base::server); // HTTPS servers read first
42 if (fUseSSL) return stream.read_some(asio::buffer(s, n));
43 return stream.next_layer().read_some(asio::buffer(s, n));
44 }
45 std::streamsize write(const char* s, std::streamsize n)
46 {
47 handshake(ssl::stream_base::client); // HTTPS clients write first
48 if (fUseSSL) return asio::write(stream, asio::buffer(s, n));
49 return asio::write(stream.next_layer(), asio::buffer(s, n));
50 }
51 bool connect(const std::string& server, const std::string& port)
52 {
53 ip::tcp::resolver resolver(stream.get_io_service());
54 ip::tcp::resolver::query query(server.c_str(), port.c_str());
55 ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
56 ip::tcp::resolver::iterator end;
57 boost::system::error_code error = asio::error::host_not_found;
58 while (error && endpoint_iterator != end)
59 {
60 stream.lowest_layer().close();
61 stream.lowest_layer().connect(*endpoint_iterator++, error);
62 }
63 if (error)
64 return false;
65 return true;
66 }
67
68 private:
69 bool fNeedHandshake;
70 bool fUseSSL;
71 SSLStream& stream;
72 };
73 #endif
74
75 void ThreadRPCServer(void* parg)
76 {
77 IMPLEMENT_RANDOMIZE_STACK(ThreadRPCServer(parg));
(2179 . 7)(2119 . 6)
79 return;
80 }
81
82 bool fUseSSL = GetBoolArg("-rpcssl");
83 asio::ip::address bindAddress = mapArgs.count("-rpcallowip") ? asio::ip::address_v4::any() : asio::ip::address_v4::loopback();
84
85 asio::io_service io_service;
(2188 . 47)(2127 . 14)
87
88 acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
89
90 #ifdef USE_SSL
91 ssl::context context(io_service, ssl::context::sslv23);
92 if (fUseSSL)
93 {
94 context.set_options(ssl::context::no_sslv2);
95 filesystem::path certfile = GetArg("-rpcsslcertificatechainfile", "server.cert");
96 if (!certfile.is_complete()) certfile = filesystem::path(GetDataDir()) / certfile;
97 if (filesystem::exists(certfile)) context.use_certificate_chain_file(certfile.string().c_str());
98 else printf("ThreadRPCServer ERROR: missing server certificate file %s\n", certfile.string().c_str());
99 filesystem::path pkfile = GetArg("-rpcsslprivatekeyfile", "server.pem");
100 if (!pkfile.is_complete()) pkfile = filesystem::path(GetDataDir()) / pkfile;
101 if (filesystem::exists(pkfile)) context.use_private_key_file(pkfile.string().c_str(), ssl::context::pem);
102 else printf("ThreadRPCServer ERROR: missing server private key file %s\n", pkfile.string().c_str());
103
104 string ciphers = GetArg("-rpcsslciphers",
105 "TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH");
106 SSL_CTX_set_cipher_list(context.impl(), ciphers.c_str());
107 }
108 #else
109 if (fUseSSL)
110 throw runtime_error("-rpcssl=1, but bitcoin compiled without full openssl libraries.");
111 #endif
112
113 loop
114 {
115 // Accept connection
116 #ifdef USE_SSL
117 SSLStream sslStream(io_service, context);
118 SSLIOStreamDevice d(sslStream, fUseSSL);
119 iostreams::stream<SSLIOStreamDevice> stream(d);
120 #else
121 ip::tcp::iostream stream;
122 #endif
123
124 ip::tcp::endpoint peer;
125 vnThreadsRunning[4]--;
126 #ifdef USE_SSL
127 acceptor.accept(sslStream.lowest_layer(), peer);
128 #else
129 acceptor.accept(*stream.rdbuf(), peer);
130 #endif
131 vnThreadsRunning[4]++;
132 if (fShutdown)
133 return;
(2236 . 9)(2142 . 10)
135 // Restrict callers by IP
136 if (!ClientAllowed(peer.address().to_string()))
137 {
138 // snipsnipsnip
139 // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake.
140 if (!fUseSSL)
141 stream << HTTPReply(403, "") << std::flush;
142 //if (!fUseSSL)
143 stream << HTTPReply(403, "") << std::flush;
144 continue;
145 }
146
(2354 . 25)(2261 . 9)
148 GetConfigFile().c_str()));
149
150 // Connect to localhost
151 bool fUseSSL = GetBoolArg("-rpcssl");
152 #ifdef USE_SSL
153 asio::io_service io_service;
154 ssl::context context(io_service, ssl::context::sslv23);
155 context.set_options(ssl::context::no_sslv2);
156 SSLStream sslStream(io_service, context);
157 SSLIOStreamDevice d(sslStream, fUseSSL);
158 iostreams::stream<SSLIOStreamDevice> stream(d);
159 if (!d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", "8332")))
160 throw runtime_error("couldn't connect to server");
161 #else
162 if (fUseSSL)
163 throw runtime_error("-rpcssl=1, but bitcoin compiled without full openssl libraries.");
164
165 ip::tcp::iostream stream(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", "8332"));
166 if (stream.fail())
167 throw runtime_error("couldn't connect to server");
168 #endif
169
170
171 // HTTP basic authentication
172 string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]);