1
//! Information about directory authorities
2
//!
3
//! From a client's point of view, an authority's role is to sign the
4
//! consensus directory.
5

            
6
use std::net::SocketAddr;
7

            
8
use derive_deftly::Deftly;
9
use getset::Getters;
10
use tor_config::define_list_builder_accessors;
11
use tor_config::derive::prelude::*;
12
use tor_llcrypto::pk::rsa::RsaIdentity;
13

            
14
/// The contact information for all directory authorities this implementation is
15
/// aware of.
16
///
17
/// This data structure makes use of proposal 330 in order to distinguish
18
/// authorities by their responsibilities, hence why the fields are divided.
19
#[derive(Debug, Clone, Deftly, Eq, PartialEq, Getters)]
20
#[derive_deftly(TorConfig)]
21
pub struct AuthorityContacts {
22
    // NOTE: We aren't using list builders here, since these never actually used sub-builders,
23
    // and therefore has a slightly different API.
24
    // We might later decide to change these to proper list-builders;
25
    // if so, it will be an API break.
26
    //
27
    /// The [`RsaIdentity`] keys that may be used to sign valid consensus documents.
28
    #[deftly(tor_config(no_magic, setter(skip), default = "default_v3idents()"))]
29
    #[getset(get = "pub")]
30
    v3idents: Vec<RsaIdentity>,
31

            
32
    /// The endpoints of authorities where upload of router descriptors and other
33
    /// documents is possible.
34
    ///
35
    /// This section is primarily of interest for relays.
36
    ///
37
    /// The use of nested a [`Vec`] serves the purpose to assign multiple IPs to
38
    /// a single logical authority, such as having an IPv4 and IPv6 address.
39
    #[deftly(tor_config(no_magic, setter(skip), default = "default_uploads()"))]
40
    #[getset(get = "pub")]
41
    uploads: Vec<Vec<SocketAddr>>,
42

            
43
    /// The endpoints of authorities where download of network documents is possible.
44
    ///
45
    /// This section is primarily of interest for directory mirrors.
46
    ///
47
    /// The use of nested a [`Vec`] serves the purpose to assign multiple IPs to
48
    /// a single logical authority, such as having an IPv4 and IPv6 address.
49
    #[deftly(tor_config(no_magic, setter(skip), default = "default_downloads()"))]
50
    #[getset(get = "pub")]
51
    downloads: Vec<Vec<SocketAddr>>,
52

            
53
    /// The endpoints of authorities where voting for consensus documents is possible.
54
    ///
55
    /// This section is primarily of interest for other directory authorities.
56
    ///
57
    /// The use of nested a [`Vec`] serves the purpose to assign multiple IPs to
58
    /// a single logical authority, such as having an IPv4 and IPv6 address.
59
    #[deftly(tor_config(no_magic, setter(skip), default = "default_votes()"))]
60
    #[getset(get = "pub")]
61
    votes: Vec<Vec<SocketAddr>>,
62
}
63

            
64
define_list_builder_accessors! {
65
    struct AuthorityContactsBuilder {
66
        pub v3idents: [RsaIdentity],
67
        pub uploads: [Vec<SocketAddr>],
68
        pub downloads: [Vec<SocketAddr>],
69
        pub votes: [Vec<SocketAddr>],
70
    }
71
}
72

            
73
/// Returns a list of the default [`RsaIdentity`]s for the directory authorities.
74
7846
fn default_v3idents() -> Vec<RsaIdentity> {
75
70614
    fn rsa(hex: &str) -> RsaIdentity {
76
70614
        RsaIdentity::from_hex(hex).expect("invalid hex?!?")
77
70614
    }
78

            
79
7846
    vec![
80
7846
        rsa("27102BC123E7AF1D4741AE047E160C91ADC76B21"), // bastet
81
7846
        rsa("0232AF901C31A04EE9848595AF9BB7620D4C5B2E"), // dannenberg
82
7846
        rsa("E8A9C45EDE6D711294FADF8E7951F4DE6CA56B58"), // dizum
83
7846
        rsa("70849B868D606BAECFB6128C5E3D782029AA394F"), // faravahar
84
7846
        rsa("ED03BB616EB2F60BEC80151114BB25CEF515B226"), // gabelmoo
85
7846
        rsa("23D15D965BC35114467363C165C4F724B64B4F66"), // longclaw
86
7846
        rsa("49015F787433103580E3B66A1707A00E60F2D15B"), // maatuska
87
7846
        rsa("F533C81CEF0BC0267857C99B2F471ADF249FA232"), // moria1
88
7846
        rsa("2F3DF9CA0E5D36F2685A2DA67184EB8DCB8CBA8C"), // tor26
89
    ]
90
7846
}
91

            
92
/// Returns a list of the [`SocketAddr`] for the directory authorities.
93
///
94
/// The nested [`Vec`] serves dual-stack purposes
95
/// (i.e. many IPs mapping to one logical authority).
96
24489
fn default_uploads() -> Vec<Vec<SocketAddr>> {
97
    /// Converts a [`str`] to a [`SocketAddr`].
98
391824
    fn sa(s: &str) -> SocketAddr {
99
391824
        s.parse().expect("invalid socket address?!?")
100
391824
    }
101

            
102
24489
    vec![
103
        // bastet
104
24489
        vec![
105
24489
            sa("204.13.164.118:80"),
106
24489
            sa("[2620:13:4000:6000::1000:118]:80"),
107
        ],
108
        // dannenberg
109
24489
        vec![sa("193.23.244.244:80"), sa("[2001:678:558:1000::244]:80")],
110
        // dizum
111
24489
        vec![sa("45.66.35.11:80"), sa("[2a09:61c0::1337]:80")],
112
        // faravahar
113
24489
        vec![sa("216.218.219.41:80"), sa("[2001:470:164:2::2]:80")],
114
        // gabelmoo
115
24489
        vec![
116
24489
            sa("131.188.40.189:80"),
117
24489
            sa("[2001:638:a000:4140::ffff:189]:80"),
118
        ],
119
        // longclaw
120
24489
        vec![sa("199.58.81.140:80")],
121
        // maatuska
122
24489
        vec![sa("171.25.193.9:443"), sa("[2001:67c:289c::9]:443")],
123
        // moria1
124
24489
        vec![sa("128.31.0.39:9231")],
125
        // tor26
126
24489
        vec![sa("217.196.147.77:80"), sa("[2a02:16a8:662:2203::1]:80")],
127
    ]
128
24489
}
129

            
130
/// For now, an alias to [`default_uploads()`].
131
8163
fn default_downloads() -> Vec<Vec<SocketAddr>> {
132
8163
    default_uploads()
133
8163
}
134

            
135
/// For now, an alias to [`default_uploads()`].
136
8208
fn default_votes() -> Vec<Vec<SocketAddr>> {
137
8208
    default_uploads()
138
8208
}
139

            
140
#[cfg(test)]
141
mod test {
142
    // @@ begin test lint list maintained by maint/add_warning @@
143
    #![allow(clippy::bool_assert_comparison)]
144
    #![allow(clippy::clone_on_copy)]
145
    #![allow(clippy::dbg_macro)]
146
    #![allow(clippy::mixed_attributes_style)]
147
    #![allow(clippy::print_stderr)]
148
    #![allow(clippy::print_stdout)]
149
    #![allow(clippy::single_char_pattern)]
150
    #![allow(clippy::unwrap_used)]
151
    #![allow(clippy::unchecked_time_subtraction)]
152
    #![allow(clippy::useless_vec)]
153
    #![allow(clippy::needless_pass_by_value)]
154
    //! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
155
    #![allow(clippy::unnecessary_wraps)]
156

            
157
    use super::*;
158

            
159
    #[test]
160
    fn default_auths() {
161
        let dflt = AuthorityContacts::builder().build().unwrap();
162
        assert_eq!(dflt.v3idents, default_v3idents());
163
        assert_eq!(dflt.uploads, default_uploads());
164
        assert_eq!(dflt.downloads, default_downloads());
165
        assert_eq!(dflt.votes, default_votes());
166

            
167
        assert_eq!(
168
            dflt.v3idents[8],
169
            RsaIdentity::from_hex("2F3DF9CA0E5D36F2685A2DA67184EB8DCB8CBA8C").unwrap()
170
        );
171
        assert_eq!(
172
            dflt.uploads[8],
173
            vec![
174
                "217.196.147.77:80".parse().unwrap(),
175
                "[2a02:16a8:662:2203::1]:80".parse().unwrap()
176
            ]
177
        );
178
        assert_eq!(dflt.uploads[8], dflt.downloads[8]);
179
        assert_eq!(dflt.uploads[8], dflt.votes[8]);
180
    }
181
}