Branch data Line data Source code
1 : : // Copyright (c) 2015-present The Bitcoin Core developers
2 : : // Distributed under the MIT software license, see the accompanying
3 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 : :
5 : : /**
6 : : * Functionality for communicating with Tor.
7 : : */
8 : : #ifndef BITCOIN_TORCONTROL_H
9 : : #define BITCOIN_TORCONTROL_H
10 : :
11 : : #include <netaddress.h>
12 : : #include <util/fs.h>
13 : :
14 : : #include <event2/util.h>
15 : :
16 : : #include <cstdint>
17 : : #include <deque>
18 : : #include <functional>
19 : : #include <string>
20 : : #include <vector>
21 : :
22 : : constexpr uint16_t DEFAULT_TOR_SOCKS_PORT{9050};
23 : : constexpr int DEFAULT_TOR_CONTROL_PORT = 9051;
24 : : extern const std::string DEFAULT_TOR_CONTROL;
25 : : static const bool DEFAULT_LISTEN_ONION = true;
26 : :
27 : : /** Tor control reply code. Ref: https://spec.torproject.org/control-spec/replies.html */
28 : : constexpr int TOR_REPLY_OK{250};
29 : : constexpr int TOR_REPLY_UNRECOGNIZED{510};
30 : : constexpr int TOR_REPLY_SYNTAX_ERROR{512}; //!< Syntax error in command argument
31 : :
32 : : void StartTorControl(CService onion_service_target);
33 : : void InterruptTorControl();
34 : : void StopTorControl();
35 : :
36 : : CService DefaultOnionServiceTarget(uint16_t port);
37 : :
38 : : /** Reply from Tor, can be single or multi-line */
39 : 101729 : class TorControlReply
40 : : {
41 : : public:
42 : 101729 : TorControlReply() { Clear(); }
43 : :
44 : : int code;
45 : : std::vector<std::string> lines;
46 : :
47 : 101729 : void Clear()
48 : : {
49 : 101729 : code = 0;
50 [ + - ]: 101729 : lines.clear();
51 : 0 : }
52 : : };
53 : :
54 : : /** Low-level handling for Tor control connection.
55 : : * Speaks the SMTP-like protocol as defined in torspec/control-spec.txt
56 : : */
57 : : class TorControlConnection
58 : : {
59 : : public:
60 : : typedef std::function<void(TorControlConnection&)> ConnectionCB;
61 : : typedef std::function<void(TorControlConnection &,const TorControlReply &)> ReplyHandlerCB;
62 : :
63 : : /** Create a new TorControlConnection.
64 : : */
65 : : explicit TorControlConnection(struct event_base *base);
66 : : ~TorControlConnection();
67 : :
68 : : /**
69 : : * Connect to a Tor control port.
70 : : * tor_control_center is address of the form host:port.
71 : : * connected is the handler that is called when connection is successfully established.
72 : : * disconnected is a handler that is called when the connection is broken.
73 : : * Return true on success.
74 : : */
75 : : bool Connect(const std::string& tor_control_center, const ConnectionCB& connected, const ConnectionCB& disconnected);
76 : :
77 : : /**
78 : : * Disconnect from Tor control port.
79 : : */
80 : : void Disconnect();
81 : :
82 : : /** Send a command, register a handler for the reply.
83 : : * A trailing CRLF is automatically added.
84 : : * Return true on success.
85 : : */
86 : : bool Command(const std::string &cmd, const ReplyHandlerCB& reply_handler);
87 : :
88 : : private:
89 : : /** Callback when ready for use */
90 : : std::function<void(TorControlConnection&)> connected;
91 : : /** Callback when connection lost */
92 : : std::function<void(TorControlConnection&)> disconnected;
93 : : /** Libevent event base */
94 : : struct event_base *base;
95 : : /** Connection to control socket */
96 : : struct bufferevent* b_conn{nullptr};
97 : : /** Message being received */
98 : : TorControlReply message;
99 : : /** Response handlers */
100 : : std::deque<ReplyHandlerCB> reply_handlers;
101 : :
102 : : /** Libevent handlers: internal */
103 : : static void readcb(struct bufferevent *bev, void *ctx);
104 : : static void eventcb(struct bufferevent *bev, short what, void *ctx);
105 : : };
106 : :
107 : : /****** Bitcoin specific TorController implementation ********/
108 : :
109 : : /** Controller that connects to Tor control socket, authenticate, then create
110 : : * and maintain an ephemeral onion service.
111 : : */
112 : : class TorController
113 : : {
114 : : public:
115 : : TorController(struct event_base* base, const std::string& tor_control_center, const CService& target);
116 [ + - + - : 243 : TorController() : conn{nullptr} {
+ - ]
117 : : // Used for testing only.
118 : 243 : }
119 : : ~TorController();
120 : :
121 : : /** Get name of file to store private key in */
122 : : fs::path GetPrivateKeyFile();
123 : :
124 : : /** Reconnect, after getting disconnected */
125 : : void Reconnect();
126 : : private:
127 : : struct event_base* base;
128 : : const std::string m_tor_control_center;
129 : : TorControlConnection conn;
130 : : std::string private_key;
131 : : std::string service_id;
132 : : bool reconnect;
133 : : struct event *reconnect_ev = nullptr;
134 : : float reconnect_timeout;
135 : : CService service;
136 : : const CService m_target;
137 : : /** Cookie for SAFECOOKIE auth */
138 : : std::vector<uint8_t> cookie;
139 : : /** ClientNonce for SAFECOOKIE auth */
140 : : std::vector<uint8_t> clientNonce;
141 : :
142 : : public:
143 : : /** Callback for GETINFO net/listeners/socks result */
144 : : void get_socks_cb(TorControlConnection& conn, const TorControlReply& reply);
145 : : /** Callback for ADD_ONION result */
146 : : void add_onion_cb(TorControlConnection& conn, const TorControlReply& reply, bool pow_was_enabled);
147 : : /** Callback for AUTHENTICATE result */
148 : : void auth_cb(TorControlConnection& conn, const TorControlReply& reply);
149 : : /** Callback for AUTHCHALLENGE result */
150 : : void authchallenge_cb(TorControlConnection& conn, const TorControlReply& reply);
151 : : /** Callback for PROTOCOLINFO result */
152 : : void protocolinfo_cb(TorControlConnection& conn, const TorControlReply& reply);
153 : : /** Callback after successful connection */
154 : : void connected_cb(TorControlConnection& conn);
155 : : /** Callback after connection lost or failed connection attempt */
156 : : void disconnected_cb(TorControlConnection& conn);
157 : :
158 : : /** Callback for reconnect timer */
159 : : static void reconnect_cb(evutil_socket_t fd, short what, void *arg);
160 : : };
161 : :
162 : : #endif // BITCOIN_TORCONTROL_H
|