aboutsummaryrefslogtreecommitdiff
path: root/src/or/or.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/or.h')
-rw-r--r--src/or/or.h293
1 files changed, 262 insertions, 31 deletions
diff --git a/src/or/or.h b/src/or/or.h
index bf404df7e..46fead405 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -174,7 +174,9 @@
/** How often do we rotate onion keys? */
#define MIN_ONION_KEY_LIFETIME (7*24*60*60)
/** How often do we rotate TLS contexts? */
-#define MAX_SSL_KEY_LIFETIME (2*60*60)
+#define MAX_SSL_KEY_LIFETIME_INTERNAL (2*60*60)
+/** What expiry time shall we place on our SSL certs? */
+#define MAX_SSL_KEY_LIFETIME_ADVERTISED (365*24*60*60)
/** How old do we allow a router to get before removing it
* from the router list? In seconds. */
@@ -281,22 +283,27 @@ typedef enum {
#define OR_CONN_STATE_CONNECTING 1
/** State for a connection to an OR: waiting for proxy handshake to complete */
#define OR_CONN_STATE_PROXY_HANDSHAKING 2
-/** State for a connection to an OR or client: SSL is handshaking, not done
+/** State for an OR connection client: SSL is handshaking, not done
* yet. */
#define OR_CONN_STATE_TLS_HANDSHAKING 3
/** State for a connection to an OR: We're doing a second SSL handshake for
- * renegotiation purposes. */
+ * renegotiation purposes. (V2 handshake only.) */
#define OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING 4
/** State for a connection at an OR: We're waiting for the client to
- * renegotiate. */
+ * renegotiate (to indicate a v2 handshake) or send a versions cell (to
+ * indicate a v3 handshake) */
#define OR_CONN_STATE_TLS_SERVER_RENEGOTIATING 5
-/** State for a connection to an OR: We're done with our SSL handshake, but we
- * haven't yet negotiated link protocol versions and sent a netinfo cell.
- */
-#define OR_CONN_STATE_OR_HANDSHAKING 6
-/** State for a connection to an OR: Ready to send/receive cells. */
-#define OR_CONN_STATE_OPEN 7
-#define _OR_CONN_STATE_MAX 7
+/** State for an OR connection: We're done with our SSL handshake, we've done
+ * renegotiation, but we haven't yet negotiated link protocol versions and
+ * sent a netinfo cell. */
+#define OR_CONN_STATE_OR_HANDSHAKING_V2 6
+/** State for an OR connection: We're done with our SSL handshake, but we
+ * haven't yet negotiated link protocol versions, done a V3 handshake, and
+ * sent a netinfo cell. */
+#define OR_CONN_STATE_OR_HANDSHAKING_V3 7
+/** State for an OR connection: Ready to send/receive cells. */
+#define OR_CONN_STATE_OPEN 8
+#define _OR_CONN_STATE_MAX 8
#define _EXIT_CONN_STATE_MIN 1
/** State for an exit connection: waiting for response from DNS farm. */
@@ -782,10 +789,10 @@ typedef struct rend_data_t {
char rend_cookie[REND_COOKIE_LEN];
} rend_data_t;
-/** Time interval for tracking possible replays of INTRODUCE2 cells.
- * Incoming cells with timestamps half of this interval in the past or
- * future are dropped immediately. */
-#define REND_REPLAY_TIME_INTERVAL (60 * 60)
+/** Time interval for tracking replays of DH public keys received in
+ * INTRODUCE2 cells. Used only to avoid launching multiple
+ * simultaneous attempts to connect to the same rendezvous point. */
+#define REND_REPLAY_TIME_INTERVAL (5 * 60)
/** Used to indicate which way a cell is going on a circuit. */
typedef enum {
@@ -818,9 +825,10 @@ typedef enum {
#define CELL_NETINFO 8
#define CELL_RELAY_EARLY 9
-/** True iff the cell command <b>x</b> is one that implies a variable-length
- * cell. */
-#define CELL_COMMAND_IS_VAR_LENGTH(x) ((x) == CELL_VERSIONS)
+#define CELL_VPADDING 128
+#define CELL_CERTS 129
+#define CELL_AUTH_CHALLENGE 130
+#define CELL_AUTHENTICATE 131
/** How long to test reachability before complaining to the user. */
#define TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT (20*60)
@@ -1076,7 +1084,47 @@ typedef struct listener_connection_t {
} listener_connection_t;
-/** Stores flags and information related to the portion of a v2 Tor OR
+/** Minimum length of the random part of an AUTH_CHALLENGE cell. */
+#define OR_AUTH_CHALLENGE_LEN 32
+
+/**
+ * @name Certificate types for CERTS cells.
+ *
+ * These values are defined by the protocol, and affect how an X509
+ * certificate in a CERTS cell is interpreted and used.
+ *
+ * @{ */
+/** A certificate that authenticates a TLS link key. The subject key
+ * must match the key used in the TLS handshake; it must be signed by
+ * the identity key. */
+#define OR_CERT_TYPE_TLS_LINK 1
+/** A self-signed identity certificate. The subject key must be a
+ * 1024-bit RSA key. */
+#define OR_CERT_TYPE_ID_1024 2
+/** A certificate that authenticates a key used in an AUTHENTICATE cell
+ * in the v3 handshake. The subject key must be a 1024-bit RSA key; it
+ * must be signed by the identity key */
+#define OR_CERT_TYPE_AUTH_1024 3
+/**@}*/
+
+/** The one currently supported type of AUTHENTICATE cell. It contains
+ * a bunch of structures signed with an RSA1024 key. The signed
+ * structures include a HMAC using negotiated TLS secrets, and a digest
+ * of all cells sent or received before the AUTHENTICATE cell (including
+ * the random server-generated AUTH_CHALLENGE cell).
+ */
+#define AUTHTYPE_RSA_SHA256_TLSSECRET 1
+
+/** The length of the part of the AUTHENTICATE cell body that the client and
+ * server can generate independently (when using RSA_SHA256_TLSSECRET). It
+ * contains everything except the client's timestamp, the client's randomly
+ * generated nonce, and the signature. */
+#define V3_AUTH_FIXED_PART_LEN (8+(32*6))
+/** The length of the part of the AUTHENTICATE cell body that the client
+ * signs. */
+#define V3_AUTH_BODY_LEN (V3_AUTH_FIXED_PART_LEN + 8 + 16)
+
+/** Stores flags and information related to the portion of a v2/v3 Tor OR
* connection handshake that happens after the TLS handshake is finished.
*/
typedef struct or_handshake_state_t {
@@ -1087,6 +1135,52 @@ typedef struct or_handshake_state_t {
unsigned int started_here : 1;
/** True iff we have received and processed a VERSIONS cell. */
unsigned int received_versions : 1;
+ /** True iff we have received and processed an AUTH_CHALLENGE cell */
+ unsigned int received_auth_challenge : 1;
+ /** True iff we have received and processed a CERTS cell. */
+ unsigned int received_certs_cell : 1;
+ /** True iff we have received and processed an AUTHENTICATE cell */
+ unsigned int received_authenticate : 1;
+
+ /* True iff we've received valid authentication to some identity. */
+ unsigned int authenticated : 1;
+
+ /** True iff we should feed outgoing cells into digest_sent and
+ * digest_received respectively.
+ *
+ * From the server's side of the v3 handshake, we want to capture everything
+ * from the VERSIONS cell through and including the AUTH_CHALLENGE cell.
+ * From the client's, we want to capture everything from the VERSIONS cell
+ * through but *not* including the AUTHENTICATE cell.
+ *
+ * @{ */
+ unsigned int digest_sent_data : 1;
+ unsigned int digest_received_data : 1;
+ /**@}*/
+
+ /** Identity digest that we have received and authenticated for our peer
+ * on this connection. */
+ uint8_t authenticated_peer_id[DIGEST_LEN];
+
+ /** Digests of the cells that we have sent or received as part of a V3
+ * handshake. Used for making and checking AUTHENTICATE cells.
+ *
+ * @{
+ */
+ crypto_digest_env_t *digest_sent;
+ crypto_digest_env_t *digest_received;
+ /** @} */
+
+ /** Certificates that a connection initiator sent us in a CERTS cell; we're
+ * holding on to them until we get an AUTHENTICATE cell.
+ *
+ * @{
+ */
+ /** The cert for the key that's supposed to sign the AUTHENTICATE cell */
+ tor_cert_t *auth_cert;
+ /** A self-signed identity certificate */
+ tor_cert_t *id_cert;
+ /**@}*/
} or_handshake_state_t;
/** Subtype of connection_t for an "OR connection" -- that is, one that speaks
@@ -1126,6 +1220,12 @@ typedef struct or_connection_t {
* router itself has a problem.
*/
unsigned int is_bad_for_new_circs:1;
+ /** True iff we have decided that the other end of this connection
+ * is a client. Connections with this flag set should never be used
+ * to satisfy an EXTEND request. */
+ unsigned int is_connection_with_client:1;
+ /** True iff this is an outgoing connection. */
+ unsigned int is_outgoing:1;
unsigned int proxy_type:2; /**< One of PROXY_NONE...PROXY_SOCKS5 */
uint8_t link_proto; /**< What protocol version are we using? 0 for
* "none negotiated yet." */
@@ -1172,6 +1272,8 @@ typedef struct or_connection_t {
unsigned active_circuit_pqueue_last_recalibrated;
struct or_connection_t *next_with_same_id; /**< Next connection with same
* identity digest as this one. */
+
+ tor_libevent_action_t *pending_action;
} or_connection_t;
/** Subtype of connection_t for an "edge connection" -- that is, an entry (ap)
@@ -1596,11 +1698,6 @@ typedef struct signed_descriptor_t {
* networkstatus that listed it. 0 for "never listed in a consensus or
* status, so far as we know." */
time_t last_listed_as_valid_until;
-#ifdef TRACK_SERVED_TIME
- /** The last time we served anybody this descriptor. Used for internal
- * testing to see whether we're holding on to descriptors too long. */
- time_t last_served_at; /*XXXX remove if not useful. */
-#endif
/* If true, we do not ever try to save this object in the cache. */
unsigned int do_not_cache : 1;
/* If true, this item is meant to represent an extrainfo. */
@@ -1625,6 +1722,13 @@ typedef struct {
uint16_t or_port; /**< Port for TLS connections. */
uint16_t dir_port; /**< Port for HTTP directory connections. */
+ /* DOCDOC */
+ /* XXXXX187 Actually these should probably be part of a list of addresses,
+ * not just a special case. Use abstractions to access these; don't do it
+ * directly. */
+ tor_addr_t ipv6_addr;
+ uint16_t ipv6_orport;
+
crypto_pk_env_t *onion_pkey; /**< Public RSA key for onions. */
crypto_pk_env_t *identity_pkey; /**< Public RSA key for signing. */
@@ -1656,6 +1760,8 @@ typedef struct {
/** True if, after we have added this router, we should re-launch
* tests for it. */
unsigned int needs_retest_if_added:1;
+ /** True if ipv6_addr:ipv6_orport is preferred. */
+ unsigned int ipv6_preferred:1;
/** Tor can use this router for general positions in circuits; we got it
* from a directory server as usual, or we're an authority and a server
@@ -1828,10 +1934,10 @@ typedef struct microdesc_t {
saved_location_t saved_location : 3;
/** If true, do not attempt to cache this microdescriptor on disk. */
unsigned int no_save : 1;
- /** If true, this microdesc is attached to a node_t. */
- unsigned int held_by_node : 1;
/** If true, this microdesc has an entry in the microdesc_map */
unsigned int held_in_map : 1;
+ /** Reference count: how many node_ts have a reference to this microdesc? */
+ unsigned int held_by_nodes;
/** If saved_location == SAVED_IN_CACHE, this field holds the offset of the
* microdescriptor in the cache. */
@@ -2736,16 +2842,37 @@ typedef struct port_cfg_t {
int session_group; /**< A session group, or -1 if this port is not in a
* session group. */
+ /* Server port types (or, dir) only: */
+ unsigned int no_advertise : 1;
+ unsigned int no_listen : 1;
+ unsigned int all_addrs : 1;
+ unsigned int ipv4_only : 1;
+ unsigned int ipv6_only : 1;
+
/* Unix sockets only: */
/** Path for an AF_UNIX address */
char unix_addr[FLEXIBLE_ARRAY_MEMBER];
} port_cfg_t;
+/** Ordinary configuration line. */
+#define CONFIG_LINE_NORMAL 0
+/** Appends to previous configuration for the same option, even if we
+ * would ordinary replace it. */
+#define CONFIG_LINE_APPEND 1
+/* Removes all previous configuration for an option. */
+#define CONFIG_LINE_CLEAR 2
+
/** A linked list of lines in a config file. */
typedef struct config_line_t {
char *key;
char *value;
struct config_line_t *next;
+ /** What special treatment (if any) does this line require? */
+ unsigned int command:2;
+ /** If true, subsequent assignments to this linelist should replace
+ * it, not extend it. Set only on the first item in a linelist in an
+ * or_options_t. */
+ unsigned int fragile:1;
} config_line_t;
typedef struct routerset_t routerset_t;
@@ -2778,6 +2905,8 @@ typedef struct {
char *Address; /**< OR only: configured address for this onion router. */
char *PidFile; /**< Where to store PID of Tor process. */
+ int DynamicDHGroups; /**< Dynamic generation of prime moduli for use in DH.*/
+
routerset_t *ExitNodes; /**< Structure containing nicknames, digests,
* country codes and IP address patterns of ORs to
* consider as exits. */
@@ -2835,17 +2964,18 @@ typedef struct {
int DirAllowPrivateAddresses;
char *User; /**< Name of user to run Tor as. */
char *Group; /**< Name of group to run Tor as. */
- int ORPort; /**< Port to listen on for OR connections. */
+ config_line_t *ORPort; /**< Ports to listen on for OR connections. */
config_line_t *SocksPort; /**< Ports to listen on for SOCKS connections. */
/** Ports to listen on for transparent pf/netfilter connections. */
config_line_t *TransPort;
config_line_t *NATDPort; /**< Ports to listen on for transparent natd
* connections. */
- int ControlPort; /**< Port to listen on for control connections. */
+ config_line_t *ControlPort; /**< Port to listen on for control
+ * connections. */
config_line_t *ControlSocket; /**< List of Unix Domain Sockets to listen on
* for control connections. */
int ControlSocketsGroupWritable; /**< Boolean: Are control sockets g+rw? */
- int DirPort; /**< Port to listen on for directory connections. */
+ config_line_t *DirPort; /**< Port to listen on for directory connections. */
config_line_t *DNSPort; /**< Port to listen on for DNS requests. */
int AssumeReachable; /**< Whether to publish our descriptor regardless. */
int AuthoritativeDir; /**< Boolean: is this an authoritative directory? */
@@ -2877,6 +3007,9 @@ typedef struct {
config_line_t *ClientTransportPlugin; /**< List of client
transport plugins. */
+ config_line_t *ServerTransportPlugin; /**< List of client
+ transport plugins. */
+
int BridgeRelay; /**< Boolean: are we acting as a bridge relay? We make
* this explicit so we can change how we behave in the
* future. */
@@ -3060,6 +3193,18 @@ typedef struct {
* number of servers per IP address shared
* with an authority. */
+ /** Should we assign the Guard flag to relays which would allow
+ * exploitation of CVE-2011-2768 against their clients? */
+ int GiveGuardFlagTo_CVE_2011_2768_VulnerableRelays;
+
+ /** If non-zero, always vote the Fast flag for any relay advertising
+ * this amount of capacity or more. */
+ uint64_t AuthDirFastGuarantee;
+
+ /** If non-zero, this advertised capacity or more is always sufficient
+ * to satisfy the bandwidth requirement for the Guard flag. */
+ uint64_t AuthDirGuardBWGuarantee;
+
char *AccountingStart; /**< How long is the accounting interval, and when
* does it start? */
uint64_t AccountingMax; /**< How many bytes do we allow per accounting
@@ -3105,6 +3250,8 @@ typedef struct {
* log whether it was DNS-leaking or not? */
int HardwareAccel; /**< Boolean: Should we enable OpenSSL hardware
* acceleration where available? */
+ /** Token Bucket Refill resolution in milliseconds. */
+ int TokenBucketRefillInterval;
char *AccelName; /**< Optional hardware acceleration engine name. */
char *AccelDir; /**< Optional hardware acceleration engine search dir. */
int UseEntryGuards; /**< Boolean: Do we try to enter from a smallish number
@@ -3136,6 +3283,8 @@ typedef struct {
disclaimer. This allows a server administrator to show
that they're running Tor and anyone visiting their server
will know this without any specialized knowledge. */
+ int DisableDebuggerAttachment; /**< Currently Linux only specific attempt to
+ disable ptrace; needs BSD testing. */
/** Boolean: if set, we start even if our resolv.conf file is missing
* or broken. */
int ServerDNSAllowBrokenConfig;
@@ -3320,6 +3469,15 @@ typedef struct {
* never use it. If -1, we do what the consensus says. */
int OptimisticData;
+ /** If 1, and we are using IOCP, we set the kernel socket SNDBUF and RCVBUF
+ * to 0 to try to save kernel memory and avoid the dread "Out of buffers"
+ * issue. */
+ int UserspaceIOCPBuffers;
+
+ /** If 1, we accept and launch no external network connections, except on
+ * control ports. */
+ int DisableNetwork;
+
} or_options_t;
/** Persistent state for an onion router, as saved to disk. */
@@ -3346,6 +3504,8 @@ typedef struct {
/** A list of Entry Guard-related configuration lines. */
config_line_t *EntryGuards;
+ config_line_t *TransportProxies;
+
/** These fields hold information on the history of bandwidth usage for
* servers. The "Ends" fields hold the time when we last updated the
* bandwidth usage. The "Interval" fields hold the granularity, in seconds,
@@ -3898,14 +4058,85 @@ typedef struct rend_encoded_v2_service_descriptor_t {
char *desc_str; /**< Descriptor string. */
} rend_encoded_v2_service_descriptor_t;
-/** Introduction point information. */
+/** The maximum number of non-circuit-build-timeout failures a hidden
+ * service client will tolerate while trying to build a circuit to an
+ * introduction point. See also rend_intro_point_t.unreachable_count. */
+#define MAX_INTRO_POINT_REACHABILITY_FAILURES 5
+
+/** The maximum number of distinct INTRODUCE2 cells which a hidden
+ * service's introduction point will receive before it begins to
+ * expire.
+ *
+ * XXX023 Is this number at all sane? */
+#define INTRO_POINT_LIFETIME_INTRODUCTIONS 16384
+
+/** The minimum number of seconds that an introduction point will last
+ * before expiring due to old age. (If it receives
+ * INTRO_POINT_LIFETIME_INTRODUCTIONS INTRODUCE2 cells, it may expire
+ * sooner.)
+ *
+ * XXX023 Should this be configurable? */
+#define INTRO_POINT_LIFETIME_MIN_SECONDS 18*60*60
+/** The maximum number of seconds that an introduction point will last
+ * before expiring due to old age.
+ *
+ * XXX023 Should this be configurable? */
+#define INTRO_POINT_LIFETIME_MAX_SECONDS 24*60*60
+
+/** Introduction point information. Used both in rend_service_t (on
+ * the service side) and in rend_service_descriptor_t (on both the
+ * client and service side). */
typedef struct rend_intro_point_t {
extend_info_t *extend_info; /**< Extend info of this introduction point. */
crypto_pk_env_t *intro_key; /**< Introduction key that replaces the service
* key, if this descriptor is V2. */
+
+ /** (Client side only) Flag indicating that a timeout has occurred
+ * after sending an INTRODUCE cell to this intro point. After a
+ * timeout, an intro point should not be tried again during the same
+ * hidden service connection attempt, but it may be tried again
+ * during a future connection attempt. */
+ unsigned int timed_out : 1;
+
+ /** (Client side only) The number of times we have failed to build a
+ * circuit to this intro point for some reason other than our
+ * circuit-build timeout. See also MAX_INTRO_POINT_REACHABILITY_FAILURES. */
+ unsigned int unreachable_count : 3;
+
+ /** (Service side only) Flag indicating that this intro point was
+ * included in the last HS descriptor we generated. */
+ unsigned int listed_in_last_desc : 1;
+
+ /** (Service side only) A digestmap recording the INTRODUCE2 cells
+ * this intro point's circuit has received. Each key is the digest
+ * of the RSA-encrypted part of a received INTRODUCE2 cell; each
+ * value is a pointer to the time_t at which the cell was received.
+ * This digestmap is used to prevent replay attacks. */
+ digestmap_t *accepted_intro_rsa_parts;
+
+ /** (Service side only) The time at which this intro point was first
+ * published, or -1 if this intro point has not yet been
+ * published. */
+ time_t time_published;
+
+ /** (Service side only) The time at which this intro point should
+ * (start to) expire, or -1 if we haven't decided when this intro
+ * point should expire. */
+ time_t time_to_expire;
+
+ /** (Service side only) The time at which we decided that this intro
+ * point should start expiring, or -1 if this intro point is not yet
+ * expiring.
+ *
+ * This field also serves as a flag to indicate that we have decided
+ * to expire this intro point, in case intro_point_should_expire_now
+ * flaps (perhaps due to a clock jump; perhaps due to other
+ * weirdness, or even a (present or future) bug). */
+ time_t time_expiring;
} rend_intro_point_t;
-/** Information used to connect to a hidden service. */
+/** Information used to connect to a hidden service. Used on both the
+ * service side and the client side. */
typedef struct rend_service_descriptor_t {
crypto_pk_env_t *pk; /**< This service's public key. */
int version; /**< Version of the descriptor format: 0 or 2. */