fuzz coverage

Coverage Report

Created: 2025-09-17 22:41

/Users/eugenesiegel/btc/bitcoin/src/torcontrol.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2015-2021 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
void StartTorControl(CService onion_service_target);
28
void InterruptTorControl();
29
void StopTorControl();
30
31
CService DefaultOnionServiceTarget(uint16_t port);
32
33
/** Reply from Tor, can be single or multi-line */
34
class TorControlReply
35
{
36
public:
37
0
    TorControlReply() { Clear(); }
38
39
    int code;
40
    std::vector<std::string> lines;
41
42
    void Clear()
43
0
    {
44
0
        code = 0;
45
0
        lines.clear();
46
0
    }
47
};
48
49
/** Low-level handling for Tor control connection.
50
 * Speaks the SMTP-like protocol as defined in torspec/control-spec.txt
51
 */
52
class TorControlConnection
53
{
54
public:
55
    typedef std::function<void(TorControlConnection&)> ConnectionCB;
56
    typedef std::function<void(TorControlConnection &,const TorControlReply &)> ReplyHandlerCB;
57
58
    /** Create a new TorControlConnection.
59
     */
60
    explicit TorControlConnection(struct event_base *base);
61
    ~TorControlConnection();
62
63
    /**
64
     * Connect to a Tor control port.
65
     * tor_control_center is address of the form host:port.
66
     * connected is the handler that is called when connection is successfully established.
67
     * disconnected is a handler that is called when the connection is broken.
68
     * Return true on success.
69
     */
70
    bool Connect(const std::string& tor_control_center, const ConnectionCB& connected, const ConnectionCB& disconnected);
71
72
    /**
73
     * Disconnect from Tor control port.
74
     */
75
    void Disconnect();
76
77
    /** Send a command, register a handler for the reply.
78
     * A trailing CRLF is automatically added.
79
     * Return true on success.
80
     */
81
    bool Command(const std::string &cmd, const ReplyHandlerCB& reply_handler);
82
83
private:
84
    /** Callback when ready for use */
85
    std::function<void(TorControlConnection&)> connected;
86
    /** Callback when connection lost */
87
    std::function<void(TorControlConnection&)> disconnected;
88
    /** Libevent event base */
89
    struct event_base *base;
90
    /** Connection to control socket */
91
    struct bufferevent* b_conn{nullptr};
92
    /** Message being received */
93
    TorControlReply message;
94
    /** Response handlers */
95
    std::deque<ReplyHandlerCB> reply_handlers;
96
97
    /** Libevent handlers: internal */
98
    static void readcb(struct bufferevent *bev, void *ctx);
99
    static void eventcb(struct bufferevent *bev, short what, void *ctx);
100
};
101
102
/****** Bitcoin specific TorController implementation ********/
103
104
/** Controller that connects to Tor control socket, authenticate, then create
105
 * and maintain an ephemeral onion service.
106
 */
107
class TorController
108
{
109
public:
110
    TorController(struct event_base* base, const std::string& tor_control_center, const CService& target);
111
0
    TorController() : conn{nullptr} {
112
        // Used for testing only.
113
0
    }
114
    ~TorController();
115
116
    /** Get name of file to store private key in */
117
    fs::path GetPrivateKeyFile();
118
119
    /** Reconnect, after getting disconnected */
120
    void Reconnect();
121
private:
122
    struct event_base* base;
123
    const std::string m_tor_control_center;
124
    TorControlConnection conn;
125
    std::string private_key;
126
    std::string service_id;
127
    bool reconnect;
128
    struct event *reconnect_ev = nullptr;
129
    float reconnect_timeout;
130
    CService service;
131
    const CService m_target;
132
    /** Cookie for SAFECOOKIE auth */
133
    std::vector<uint8_t> cookie;
134
    /** ClientNonce for SAFECOOKIE auth */
135
    std::vector<uint8_t> clientNonce;
136
137
public:
138
    /** Callback for GETINFO net/listeners/socks result */
139
    void get_socks_cb(TorControlConnection& conn, const TorControlReply& reply);
140
    /** Callback for ADD_ONION result */
141
    void add_onion_cb(TorControlConnection& conn, const TorControlReply& reply);
142
    /** Callback for AUTHENTICATE result */
143
    void auth_cb(TorControlConnection& conn, const TorControlReply& reply);
144
    /** Callback for AUTHCHALLENGE result */
145
    void authchallenge_cb(TorControlConnection& conn, const TorControlReply& reply);
146
    /** Callback for PROTOCOLINFO result */
147
    void protocolinfo_cb(TorControlConnection& conn, const TorControlReply& reply);
148
    /** Callback after successful connection */
149
    void connected_cb(TorControlConnection& conn);
150
    /** Callback after connection lost or failed connection attempt */
151
    void disconnected_cb(TorControlConnection& conn);
152
153
    /** Callback for reconnect timer */
154
    static void reconnect_cb(evutil_socket_t fd, short what, void *arg);
155
};
156
157
#endif // BITCOIN_TORCONTROL_H