aboutsummaryrefslogtreecommitdiff
path: root/src/core/or/policies.h
blob: 72a37d62b04b784f73b0cd0143ea57461d619699 (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
/* 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 policies.h
 * \brief Header file for policies.c.
 **/

#ifndef TOR_POLICIES_H
#define TOR_POLICIES_H

/* (length of
 * "accept6 [ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]/128:65535-65535\n"
 * plus a terminating NUL, rounded up to a nice number.)
 */
#define POLICY_BUF_LEN 72

#define EXIT_POLICY_IPV6_ENABLED             (1 << 0)
#define EXIT_POLICY_REJECT_PRIVATE           (1 << 1)
#define EXIT_POLICY_ADD_DEFAULT              (1 << 2)
#define EXIT_POLICY_REJECT_LOCAL_INTERFACES  (1 << 3)
#define EXIT_POLICY_ADD_REDUCED              (1 << 4)
#define EXIT_POLICY_OPTION_MAX             EXIT_POLICY_ADD_REDUCED
/* All options set: used for unit testing */
#define EXIT_POLICY_OPTION_ALL             ((EXIT_POLICY_OPTION_MAX << 1) - 1)

typedef enum firewall_connection_t {
  FIREWALL_OR_CONNECTION      = 0,
  FIREWALL_DIR_CONNECTION     = 1
} firewall_connection_t;

typedef int exit_policy_parser_cfg_t;

/** Outcome of applying an address policy to an address. */
typedef enum {
  /** The address was accepted */
  ADDR_POLICY_ACCEPTED=0,
  /** The address was rejected */
  ADDR_POLICY_REJECTED=-1,
  /** Part of the address was unknown, but as far as we can tell, it was
   * accepted. */
  ADDR_POLICY_PROBABLY_ACCEPTED=1,
  /** Part of the address was unknown, but as far as we can tell, it was
   * rejected. */
  ADDR_POLICY_PROBABLY_REJECTED=2,
} addr_policy_result_t;

/** A single entry in a parsed policy summary, describing a range of ports. */
typedef struct short_policy_entry_t {
  uint16_t min_port, max_port;
} short_policy_entry_t;

/** A short_poliy_t is the parsed version of a policy summary. */
typedef struct short_policy_t {
  /** True if the members of 'entries' are port ranges to accept; false if
   * they are port ranges to reject */
  unsigned int is_accept : 1;
  /** The actual number of values in 'entries'. */
  unsigned int n_entries : 31;
  /** An array of 0 or more short_policy_entry_t values, each describing a
   * range of ports that this policy accepts or rejects (depending on the
   * value of is_accept).
   */
  short_policy_entry_t entries[FLEXIBLE_ARRAY_MEMBER];
} short_policy_t;

int firewall_is_fascist_or(void);
int firewall_is_fascist_dir(void);
int fascist_firewall_use_ipv6(const or_options_t *options);
int fascist_firewall_prefer_ipv6_orport(const or_options_t *options);
int fascist_firewall_prefer_ipv6_dirport(const or_options_t *options);

int fascist_firewall_allows_address_addr(const tor_addr_t *addr,
                                         uint16_t port,
                                         firewall_connection_t fw_connection,
                                         int pref_only, int pref_ipv6);

int fascist_firewall_allows_rs(const routerstatus_t *rs,
                               firewall_connection_t fw_connection,
                               int pref_only);
int fascist_firewall_allows_node(const node_t *node,
                                 firewall_connection_t fw_connection,
                                 int pref_only);
int fascist_firewall_allows_dir_server(const dir_server_t *ds,
                                       firewall_connection_t fw_connection,
                                       int pref_only);

void fascist_firewall_choose_address_rs(const routerstatus_t *rs,
                                        firewall_connection_t fw_connection,
                                        int pref_only, tor_addr_port_t* ap);
void fascist_firewall_choose_address_ls(const smartlist_t *lspecs,
                                        int pref_only, tor_addr_port_t* ap);
void fascist_firewall_choose_address_node(const node_t *node,
                                          firewall_connection_t fw_connection,
                                          int pref_only, tor_addr_port_t* ap);
void fascist_firewall_choose_address_dir_server(const dir_server_t *ds,
                                          firewall_connection_t fw_connection,
                                          int pref_only, tor_addr_port_t* ap);

int dir_policy_permits_address(const tor_addr_t *addr);
int socks_policy_permits_address(const tor_addr_t *addr);
int authdir_policy_permits_address(uint32_t addr, uint16_t port);
int authdir_policy_valid_address(uint32_t addr, uint16_t port);
int authdir_policy_badexit_address(uint32_t addr, uint16_t port);

int validate_addr_policies(const or_options_t *options, char **msg);
void policy_expand_private(smartlist_t **policy);
void policy_expand_unspec(smartlist_t **policy);
int policies_parse_from_options(const or_options_t *options);

addr_policy_t *addr_policy_get_canonical_entry(addr_policy_t *ent);
int addr_policies_eq(const smartlist_t *a, const smartlist_t *b);
MOCK_DECL(addr_policy_result_t, compare_tor_addr_to_addr_policy,
    (const tor_addr_t *addr, uint16_t port, const smartlist_t *policy));
addr_policy_result_t compare_tor_addr_to_node_policy(const tor_addr_t *addr,
                              uint16_t port, const node_t *node);

int policies_parse_exit_policy_from_options(
                                          const or_options_t *or_options,
                                          uint32_t local_address,
                                          const tor_addr_t *ipv6_local_address,
                                          smartlist_t **result);
struct config_line_t;
int policies_parse_exit_policy(struct config_line_t *cfg, smartlist_t **dest,
                               exit_policy_parser_cfg_t options,
                               const smartlist_t *configured_addresses);
void policies_parse_exit_policy_reject_private(
                                      smartlist_t **dest,
                                      int ipv6_exit,
                                      const smartlist_t *configured_addresses,
                                      int reject_interface_addresses,
                                      int reject_configured_port_addresses);
void policies_exit_policy_append_reject_star(smartlist_t **dest);
void addr_policy_append_reject_addr(smartlist_t **dest,
                                    const tor_addr_t *addr);
void addr_policy_append_reject_addr_list(smartlist_t **dest,
                                         const smartlist_t *addrs);
void policies_set_node_exitpolicy_to_reject_all(node_t *exitrouter);
int exit_policy_is_general_exit(smartlist_t *policy);
int policy_is_reject_star(const smartlist_t *policy, sa_family_t family,
                          int reject_by_default);
char * policy_dump_to_string(const smartlist_t *policy_list,
                             int include_ipv4,
                             int include_ipv6);
int getinfo_helper_policies(control_connection_t *conn,
                            const char *question, char **answer,
                            const char **errmsg);
int policy_write_item(char *buf, size_t buflen, const addr_policy_t *item,
                      int format_for_desc);

void addr_policy_list_free_(smartlist_t *p);
#define addr_policy_list_free(lst) \
  FREE_AND_NULL(smartlist_t, addr_policy_list_free_, (lst))
void addr_policy_free_(addr_policy_t *p);
#define addr_policy_free(p) \
  FREE_AND_NULL(addr_policy_t, addr_policy_free_, (p))
void policies_free_all(void);

char *policy_summarize(smartlist_t *policy, sa_family_t family);

short_policy_t *parse_short_policy(const char *summary);
char *write_short_policy(const short_policy_t *policy);
void short_policy_free_(short_policy_t *policy);
#define short_policy_free(p) \
  FREE_AND_NULL(short_policy_t, short_policy_free_, (p))
int short_policy_is_reject_star(const short_policy_t *policy);
addr_policy_result_t compare_tor_addr_to_short_policy(
                          const tor_addr_t *addr, uint16_t port,
                          const short_policy_t *policy);

#ifdef POLICIES_PRIVATE
STATIC void append_exit_policy_string(smartlist_t **policy, const char *more);
STATIC int fascist_firewall_allows_address(const tor_addr_t *addr,
                                           uint16_t port,
                                           smartlist_t *firewall_policy,
                                           int pref_only, int pref_ipv6);
STATIC const tor_addr_port_t * fascist_firewall_choose_address(
                                          const tor_addr_port_t *a,
                                          const tor_addr_port_t *b,
                                          int want_a,
                                          firewall_connection_t fw_connection,
                                          int pref_only, int pref_ipv6);

#endif /* defined(POLICIES_PRIVATE) */

#endif /* !defined(TOR_POLICIES_H) */