aboutsummaryrefslogtreecommitdiff
path: root/src/feature/rend/rendservice.h
blob: 012afc0f9f4b2d6d3e55924759cd1cdb276cba6b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/* Copyright (c) 2001 Matej Pfajfar.
 * Copyright (c) 2001-2004, Roger Dingledine.
 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
 * Copyright (c) 2007-2020, The Tor Project, Inc. */
/* See LICENSE for licensing information */

/**
 * \file rendservice.h
 * \brief Header file for rendservice.c.
 **/

#ifndef TOR_RENDSERVICE_H
#define TOR_RENDSERVICE_H

#include "core/or/or.h"
#include "feature/hs/hs_service.h"

typedef struct rend_intro_cell_t rend_intro_cell_t;
struct config_line_t;

/* This can be used for both INTRODUCE1 and INTRODUCE2 */

struct rend_intro_cell_t {
  /* Is this an INTRODUCE1 or INTRODUCE2? (set to 1 or 2) */
  uint8_t type;
  /* Public key digest */
  uint8_t pk[DIGEST_LEN];
  /* Optionally, store ciphertext here */
  uint8_t *ciphertext;
  ssize_t ciphertext_len;
  /* Optionally, store plaintext */
  uint8_t *plaintext;
  ssize_t plaintext_len;
  /* Have we parsed the plaintext? */
  uint8_t parsed;
  /* intro protocol version (0, 1, 2 or 3) */
  uint8_t version;
  /* Version-specific parts */
  union {
    struct {
      /* Rendezvous point nickname or hex-encoded key digest */
      uint8_t rp[42];
    } v0_v1;
    struct {
      /* The extend_info_t struct has everything v2 uses */
      extend_info_t *extend_info;
    } v2;
    struct {
      /* Auth type used */
      uint8_t auth_type;
      /* Length of auth data */
      uint16_t auth_len;
      /* Auth data */
      uint8_t *auth_data;
      /* Rendezvous point's IP address/port, identity digest and onion key */
      extend_info_t *extend_info;
    } v3;
  } u;
  /* Rendezvous cookie */
  uint8_t rc[REND_COOKIE_LEN];
  /* Diffie-Hellman data */
  uint8_t dh[DH1024_KEY_LEN];
};

#ifdef RENDSERVICE_PRIVATE

/** Represents a single hidden service running at this OP. */
typedef struct rend_service_t {
  /* Fields specified in config file */
  char *directory; /**< where in the filesystem it stores it. Will be NULL if
                    * this service is ephemeral. */
  int dir_group_readable; /**< if 1, allow group read
                             permissions on directory */
  smartlist_t *ports; /**< List of rend_service_port_config_t */
  rend_auth_type_t auth_type; /**< Client authorization type or 0 if no client
                               * authorization is performed. */
  smartlist_t *clients; /**< List of rend_authorized_client_t's of
                         * clients that may access our service. Can be NULL
                         * if no client authorization is performed. */
  /* Other fields */
  crypto_pk_t *private_key; /**< Permanent hidden-service key. */
  char service_id[REND_SERVICE_ID_LEN_BASE32+1]; /**< Onion address without
                                                  * '.onion' */
  char pk_digest[DIGEST_LEN]; /**< Hash of permanent hidden-service key. */
  smartlist_t *intro_nodes; /**< List of rend_intro_point_t's we have,
                             * or are trying to establish. */
  /** List of rend_intro_point_t that are expiring. They are removed once
   * the new descriptor is successfully uploaded. A node in this list CAN
   * NOT appear in the intro_nodes list. */
  smartlist_t *expiring_nodes;
  time_t intro_period_started; /**< Start of the current period to build
                                * introduction points. */
  int n_intro_circuits_launched; /**< Count of intro circuits we have
                                  * established in this period. */
  unsigned int n_intro_points_wanted; /**< Number of intro points this
                                       * service wants to have open. */
  rend_service_descriptor_t *desc; /**< Current hidden service descriptor. */
  time_t desc_is_dirty; /**< Time at which changes to the hidden service
                         * descriptor content occurred, or 0 if it's
                         * up-to-date. */
  time_t next_upload_time; /**< Scheduled next hidden service descriptor
                            * upload time. */
  /** Replay cache for Diffie-Hellman values of INTRODUCE2 cells, to
   * detect repeats.  Clients may send INTRODUCE1 cells for the same
   * rendezvous point through two or more different introduction points;
   * when they do, this keeps us from launching multiple simultaneous attempts
   * to connect to the same rend point. */
  replaycache_t *accepted_intro_dh_parts;
  /** If true, we don't close circuits for making requests to unsupported
   * ports. */
  int allow_unknown_ports;
  /** The maximum number of simultaneous streams-per-circuit that are allowed
   * to be established, or 0 if no limit is set.
   */
  int max_streams_per_circuit;
  /** If true, we close circuits that exceed the max_streams_per_circuit
   * limit.  */
  int max_streams_close_circuit;
} rend_service_t;

STATIC void rend_service_free_(rend_service_t *service);
#define rend_service_free(s) \
  FREE_AND_NULL(rend_service_t, rend_service_free_, (s))
STATIC char *rend_service_sos_poison_path(const rend_service_t *service);
STATIC int rend_service_verify_single_onion_poison(
                                                  const rend_service_t *s,
                                                  const or_options_t *options);
STATIC int rend_service_poison_new_single_onion_dir(
                                                  const rend_service_t *s,
                                                  const or_options_t* options);
#ifdef TOR_UNIT_TESTS

STATIC void set_rend_service_list(smartlist_t *new_list);
STATIC void set_rend_rend_service_staging_list(smartlist_t *new_list);
STATIC void rend_service_prune_list_impl_(void);

#endif /* defined(TOR_UNIT_TESTS) */

#endif /* defined(RENDSERVICE_PRIVATE) */

int rend_num_services(void);
struct hs_opts_t;
int rend_config_service(const struct hs_opts_t *hs_opts,
                        const or_options_t *options,
                        hs_service_config_t *config);
void rend_service_prune_list(void);
void rend_service_free_staging_list(void);
int rend_service_load_all_keys(const smartlist_t *service_list);
int rend_service_key_on_disk(const char *directory_path);
void rend_services_add_filenames_to_lists(smartlist_t *open_lst,
                                          smartlist_t *stat_lst);
void rend_consider_services_intro_points(time_t now);
void rend_consider_services_upload(time_t now);
void rend_hsdir_routers_changed(void);
void rend_consider_descriptor_republication(void);

void rend_service_intro_has_opened(origin_circuit_t *circuit);
int rend_service_intro_established(origin_circuit_t *circuit,
                                   const uint8_t *request,
                                   size_t request_len);
void rend_service_rendezvous_has_opened(origin_circuit_t *circuit);
int rend_service_receive_introduction(origin_circuit_t *circuit,
                                      const uint8_t *request,
                                      size_t request_len);
int rend_service_decrypt_intro(rend_intro_cell_t *request,
                               crypto_pk_t *key,
                               char **err_msg_out);
void rend_service_free_intro_(rend_intro_cell_t *request);
#define rend_service_free_intro(req) do {       \
    rend_service_free_intro_(req);              \
    (req) = NULL;                               \
  } while (0)
rend_intro_cell_t * rend_service_begin_parse_intro(const uint8_t *request,
                                                   size_t request_len,
                                                   uint8_t type,
                                                   char **err_msg_out);
int rend_service_parse_intro_plaintext(rend_intro_cell_t *intro,
                                       char **err_msg_out);
ssize_t rend_service_encode_establish_intro_cell(char *cell_body_out,
                                                 size_t cell_body_out_len,
                                                 crypto_pk_t *intro_key,
                                                 const char *rend_circ_nonce);
int rend_service_validate_intro_late(const rend_intro_cell_t *intro,
                                     char **err_msg_out);
void rend_service_relaunch_rendezvous(origin_circuit_t *oldcirc);
int rend_service_set_connection_addr_port(edge_connection_t *conn,
                                          origin_circuit_t *circ);
void rend_service_dump_stats(int severity);
void rend_service_free_all(void);
void rend_service_init(void);

rend_service_port_config_t *rend_service_parse_port_config(const char *string,
                                                           const char *sep,
                                                           char **err_msg_out);
void rend_service_port_config_free_(rend_service_port_config_t *p);
#define rend_service_port_config_free(p) \
  FREE_AND_NULL(rend_service_port_config_t, rend_service_port_config_free_, \
                (p))

void rend_authorized_client_free_(rend_authorized_client_t *client);
#define rend_authorized_client_free(client) \
  FREE_AND_NULL(rend_authorized_client_t, rend_authorized_client_free_, \
                (client))

hs_service_add_ephemeral_status_t rend_service_add_ephemeral(crypto_pk_t *pk,
                               smartlist_t *ports,
                               int max_streams_per_circuit,
                               int max_streams_close_circuit,
                               rend_auth_type_t auth_type,
                               smartlist_t *auth_clients,
                               char **service_id_out);
int rend_service_del_ephemeral(const char *service_id);

void directory_post_to_hs_dir(rend_service_descriptor_t *renddesc,
                              smartlist_t *descs, smartlist_t *hs_dirs,
                              const char *service_id, int seconds_valid);
void rend_service_desc_has_uploaded(const rend_data_t *rend_data);

int rend_service_allow_non_anonymous_connection(const or_options_t *options);
int rend_service_reveal_startup_time(const or_options_t *options);
int rend_service_non_anonymous_mode_enabled(const or_options_t *options);

#endif /* !defined(TOR_RENDSERVICE_H) */