fuzz coverage

Coverage Report

Created: 2025-06-01 19:34

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