26 #include <boost/signals2/signal.hpp>
27 #include <boost/algorithm/string/split.hpp>
28 #include <boost/algorithm/string/classification.hpp>
29 #include <boost/algorithm/string/replace.hpp>
31 #include <event2/bufferevent.h>
32 #include <event2/buffer.h>
33 #include <event2/util.h>
34 #include <event2/event.h>
35 #include <event2/thread.h>
44 static const std::string
TOR_SAFE_SERVERKEY =
"Tor safe cookie authentication server-to-controller hash";
46 static const std::string
TOR_SAFE_CLIENTKEY =
"Tor safe cookie authentication controller-to-server hash";
60 base(_base), b_conn(nullptr)
73 struct evbuffer *input = bufferevent_get_input(bev);
74 size_t n_read_out = 0;
78 while((line = evbuffer_readln(input, &n_read_out, EVBUFFER_EOL_CRLF)) !=
nullptr)
80 std::string s(line, n_read_out);
85 self->message.code =
atoi(s.substr(0,3));
86 self->message.lines.push_back(s.substr(4));
90 if (self->message.code >= 600) {
93 self->async_handler(*
self, self->message);
95 if (!self->reply_handlers.empty()) {
97 self->reply_handlers.front()(*
self,
self->message);
98 self->reply_handlers.pop_front();
103 self->message.Clear();
110 LogPrintf(
"tor: Disconnecting because MAX_LINE_LENGTH exceeded\n");
118 if (what & BEV_EVENT_CONNECTED) {
120 self->connected(*
self);
121 }
else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
122 if (what & BEV_EVENT_ERROR) {
128 self->disconnected(*
self);
137 struct sockaddr_storage connect_to_addr;
138 int connect_to_addrlen =
sizeof(connect_to_addr);
139 if (evutil_parse_sockaddr_port(tor_control_center.c_str(),
140 (
struct sockaddr*)&connect_to_addr, &connect_to_addrlen)<0) {
141 LogPrintf(
"tor: Error parsing socket address %s\n", tor_control_center);
146 b_conn = bufferevent_socket_new(
base, -1, BEV_OPT_CLOSE_ON_FREE);
150 bufferevent_enable(
b_conn, EV_READ|EV_WRITE);
155 if (bufferevent_socket_connect(
b_conn, (
struct sockaddr*)&connect_to_addr, connect_to_addrlen) < 0) {
156 LogPrintf(
"tor: Error connecting to address %s\n", tor_control_center);
173 struct evbuffer *buf = bufferevent_get_output(
b_conn);
176 evbuffer_add(buf, cmd.data(), cmd.size());
177 evbuffer_add(buf,
"\r\n", 2);
193 while (ptr < s.size() && s[ptr] !=
' ') {
194 type.push_back(s[ptr]);
199 return make_pair(type, s.substr(ptr));
210 std::map<std::string,std::string> mapping;
212 while (ptr < s.size()) {
213 std::string key, value;
214 while (ptr < s.size() && s[ptr] !=
'=' && s[ptr] !=
' ') {
215 key.push_back(s[ptr]);
219 return std::map<std::string,std::string>();
223 if (ptr < s.size() && s[ptr] ==
'"') {
225 bool escape_next =
false;
226 while (ptr < s.size() && (escape_next || s[ptr] !=
'"')) {
228 escape_next = (s[ptr] ==
'\\' && !escape_next);
229 value.push_back(s[ptr]);
233 return std::map<std::string,std::string>();
245 std::string escaped_value;
246 for (
size_t i = 0; i < value.size(); ++i) {
247 if (value[i] ==
'\\') {
253 if (value[i] ==
'n') {
254 escaped_value.push_back(
'\n');
255 }
else if (value[i] ==
't') {
256 escaped_value.push_back(
'\t');
257 }
else if (value[i] ==
'r') {
258 escaped_value.push_back(
'\r');
259 }
else if (
'0' <= value[i] && value[i] <=
'7') {
264 for (j = 1; j < 3 && (i+j) < value.size() &&
'0' <= value[i+j] && value[i+j] <=
'7'; ++j) {}
268 if (j == 3 && value[i] >
'3') {
271 escaped_value.push_back(strtol(value.substr(i, j).c_str(),
nullptr, 8));
275 escaped_value.push_back(value[i]);
278 escaped_value.push_back(value[i]);
281 value = escaped_value;
283 while (ptr < s.size() && s[ptr] !=
' ') {
284 value.push_back(s[ptr]);
288 if (ptr < s.size() && s[ptr] ==
' ')
290 mapping[key] = value;
297 m_tor_control_center(tor_control_center), conn(base), reconnect(true), reconnect_ev(0),
303 LogPrintf(
"tor: Failed to create event for reconnection: out of memory?\n");
330 if (reply.
code == 250) {
332 for (
const std::string &s : reply.
lines) {
334 std::map<std::string,std::string>::iterator i;
335 if ((i = m.find(
"ServiceID")) != m.end())
337 if ((i = m.find(
"PrivateKey")) != m.end())
341 LogPrintf(
"tor: Error parsing ADD_ONION parameters:\n");
342 for (
const std::string &s : reply.
lines) {
356 }
else if (reply.
code == 510) {
357 LogPrintf(
"tor: Add onion failed with unrecognized command (You probably need to upgrade Tor)\n");
359 LogPrintf(
"tor: Add onion failed; error code %d\n", reply.
code);
365 if (reply.
code == 250) {
386 LogPrintf(
"tor: Authentication failed\n");
406 static std::vector<uint8_t>
ComputeResponse(
const std::string &key,
const std::vector<uint8_t> &cookie,
const std::vector<uint8_t> &clientNonce,
const std::vector<uint8_t> &serverNonce)
408 CHMAC_SHA256 computeHash((
const uint8_t*)key.data(), key.size());
410 computeHash.
Write(cookie.data(), cookie.size());
411 computeHash.
Write(clientNonce.data(), clientNonce.size());
412 computeHash.
Write(serverNonce.data(), serverNonce.size());
413 computeHash.
Finalize(computedHash.data());
419 if (reply.
code == 250) {
422 if (l.first ==
"AUTHCHALLENGE") {
428 std::vector<uint8_t> serverHash =
ParseHex(m[
"SERVERHASH"]);
429 std::vector<uint8_t> serverNonce =
ParseHex(m[
"SERVERNONCE"]);
431 if (serverNonce.size() != 32) {
432 LogPrintf(
"tor: ServerNonce is not 32 bytes, as required by spec\n");
437 if (computedServerHash != serverHash) {
438 LogPrintf(
"tor: ServerHash %s does not match expected ServerHash %s\n",
HexStr(serverHash),
HexStr(computedServerHash));
445 LogPrintf(
"tor: Invalid reply to AUTHCHALLENGE\n");
448 LogPrintf(
"tor: SAFECOOKIE authentication challenge failed\n");
454 if (reply.
code == 250) {
455 std::set<std::string> methods;
456 std::string cookiefile;
462 for (
const std::string &s : reply.
lines) {
464 if (l.first ==
"AUTH") {
466 std::map<std::string,std::string>::iterator i;
467 if ((i = m.find(
"METHODS")) != m.end())
468 boost::split(methods, i->second, boost::is_any_of(
","));
469 if ((i = m.find(
"COOKIEFILE")) != m.end())
470 cookiefile = i->second;
471 }
else if (l.first ==
"VERSION") {
473 std::map<std::string,std::string>::iterator i;
474 if ((i = m.find(
"Tor")) != m.end()) {
479 for (
const std::string &s : methods) {
487 std::string torpassword =
gArgs.
GetArg(
"-torpassword",
"");
488 if (!torpassword.empty()) {
489 if (methods.count(
"HASHEDPASSWORD")) {
491 boost::replace_all(torpassword,
"\"",
"\\\"");
492 _conn.
Command(
"AUTHENTICATE \"" + torpassword +
"\"", std::bind(&
TorController::auth_cb,
this, std::placeholders::_1, std::placeholders::_2));
494 LogPrintf(
"tor: Password provided with -torpassword, but HASHEDPASSWORD authentication is not available\n");
496 }
else if (methods.count(
"NULL")) {
499 }
else if (methods.count(
"SAFECOOKIE")) {
501 LogPrint(
BCLog::TOR,
"tor: Using SAFECOOKIE authentication, reading cookie authentication from %s\n", cookiefile);
503 if (status_cookie.first && status_cookie.second.size() ==
TOR_COOKIE_SIZE) {
505 cookie = std::vector<uint8_t>(status_cookie.second.begin(), status_cookie.second.end());
510 if (status_cookie.first) {
511 LogPrintf(
"tor: Authentication cookie %s is not exactly %i bytes, as is required by the spec\n", cookiefile,
TOR_COOKIE_SIZE);
513 LogPrintf(
"tor: Authentication cookie %s could not be opened (check permissions)\n", cookiefile);
516 }
else if (methods.count(
"HASHEDPASSWORD")) {
517 LogPrintf(
"tor: The only supported authentication mechanism left is password, but no password provided with -torpassword\n");
519 LogPrintf(
"tor: No supported authentication method\n");
522 LogPrintf(
"tor: Requesting protocol info failed\n");
531 LogPrintf(
"tor: Error sending initial protocolinfo command\n");
582 event_base_dispatch(
gBase);
589 evthread_use_windows_threads();
591 evthread_use_pthreads();
593 gBase = event_base_new();
595 LogPrintf(
"tor: Unable to create event_base\n");
608 event_base_once(
gBase, -1, EV_TIMEOUT, [](evutil_socket_t,
short,
void*) {
609 event_base_loopbreak(
gBase);
610 },
nullptr,
nullptr);
618 event_base_free(
gBase);
625 struct in_addr onion_service_target;
626 onion_service_target.s_addr = htonl(INADDR_LOOPBACK);