| 443 | } |
| 444 | |
| 445 | void TorController::authchallenge_cb(TorControlConnection& _conn, const TorControlReply& reply) |
| 446 | { |
| 447 | if (reply.code == 250) { |
| 448 | LogPrint(BCLog::TOR, "tor: SAFECOOKIE authentication challenge successful\n"); |
| 449 | std::pair<std::string,std::string> l = SplitTorReplyLine(reply.lines[0]); |
| 450 | if (l.first == "AUTHCHALLENGE") { |
| 451 | std::map<std::string,std::string> m = ParseTorReplyMapping(l.second); |
| 452 | if (m.empty()) { |
| 453 | LogPrintf("tor: Error parsing AUTHCHALLENGE parameters: %s\n", SanitizeString(l.second)); |
| 454 | return; |
| 455 | } |
| 456 | std::vector<uint8_t> serverHash = ParseHex(m["SERVERHASH"]); |
| 457 | std::vector<uint8_t> serverNonce = ParseHex(m["SERVERNONCE"]); |
| 458 | LogPrint(BCLog::TOR, "tor: AUTHCHALLENGE ServerHash %s ServerNonce %s\n", HexStr(serverHash), HexStr(serverNonce)); |
| 459 | if (serverNonce.size() != 32) { |
| 460 | LogPrintf("tor: ServerNonce is not 32 bytes, as required by spec\n"); |
| 461 | return; |
| 462 | } |
| 463 | |
| 464 | std::vector<uint8_t> computedServerHash = ComputeResponse(TOR_SAFE_SERVERKEY, cookie, clientNonce, serverNonce); |
| 465 | if (computedServerHash != serverHash) { |
| 466 | LogPrintf("tor: ServerHash %s does not match expected ServerHash %s\n", HexStr(serverHash), HexStr(computedServerHash)); |
| 467 | return; |
| 468 | } |
| 469 | |
| 470 | std::vector<uint8_t> computedClientHash = ComputeResponse(TOR_SAFE_CLIENTKEY, cookie, clientNonce, serverNonce); |
| 471 | _conn.Command("AUTHENTICATE " + HexStr(computedClientHash), std::bind(&TorController::auth_cb, this, std::placeholders::_1, std::placeholders::_2)); |
| 472 | } else { |
| 473 | LogPrintf("tor: Invalid reply to AUTHCHALLENGE\n"); |
| 474 | } |
| 475 | } else { |
| 476 | LogPrintf("tor: SAFECOOKIE authentication challenge failed\n"); |
| 477 | } |
| 478 | } |
| 479 | |
| 480 | void TorController::protocolinfo_cb(TorControlConnection& _conn, const TorControlReply& reply) |
| 481 | { |