|
1 |
| -use ipnetwork::Ipv4Network; |
| 1 | +use ipnetwork::IpNetwork; |
2 | 2 |
|
3 | 3 | use crate::publish_rate_limit::PublishRateLimit;
|
4 | 4 | use crate::{env, env_optional, uploaders::Uploader, Env};
|
@@ -27,7 +27,7 @@ pub struct Server {
|
27 | 27 | pub blocked_traffic: Vec<(String, Vec<String>)>,
|
28 | 28 | pub max_allowed_page_offset: u32,
|
29 | 29 | pub page_offset_ua_blocklist: Vec<String>,
|
30 |
| - pub page_offset_cidr_blocklist: Vec<Ipv4Network>, |
| 30 | + pub page_offset_cidr_blocklist: Vec<IpNetwork>, |
31 | 31 | pub excluded_crate_names: Vec<String>,
|
32 | 32 | pub domain_name: String,
|
33 | 33 | pub allowed_origins: Vec<String>,
|
@@ -166,21 +166,28 @@ pub(crate) fn domain_name() -> String {
|
166 | 166 | /// * Only IPv4 blocks are currently supported.
|
167 | 167 | /// * The minimum number of host prefix bits must be at least 16.
|
168 | 168 | ///
|
169 |
| -fn parse_cidr_blocks(blocks: &[String]) -> Vec<Ipv4Network> { |
| 169 | +fn parse_cidr_blocks(blocks: &[String]) -> Vec<IpNetwork> { |
170 | 170 | blocks
|
171 | 171 | .iter()
|
172 |
| - .map(|block| match block.parse::<Ipv4Network>() { |
173 |
| - Ok(cidr) => { |
174 |
| - if cidr.prefix() < 16 { |
175 |
| - panic!( |
176 |
| - "WEB_PAGE_OFFSET_CIDR_BLOCKLIST must only contain CIDR blocks with \ |
177 |
| - a host prefix of at least 16 bits." |
178 |
| - ) |
179 |
| - } else { |
180 |
| - cidr |
181 |
| - } |
| 172 | + .map(|block| { |
| 173 | + let network = block.parse::<IpNetwork>(); |
| 174 | + match network { |
| 175 | + Ok(cidr) => { |
| 176 | + let host_prefix = match cidr { |
| 177 | + IpNetwork::V4(_) => 16, |
| 178 | + IpNetwork::V6(_) => 64, |
| 179 | + }; |
| 180 | + if cidr.prefix() < host_prefix { |
| 181 | + panic!( |
| 182 | + "WEB_PAGE_OFFSET_CIDR_BLOCKLIST only allows CIDR blocks with a host prefix \ |
| 183 | + of at least 16 bits (IPv4) or 64 bits (IPv6)." |
| 184 | + ); |
| 185 | + } else { |
| 186 | + cidr |
| 187 | + } |
| 188 | + }, |
| 189 | + Err(_) => panic!("WEB_PAGE_OFFSET_CIDR_BLOCKLIST must contain IPv4 or IPv6 CIDR blocks."), |
182 | 190 | }
|
183 |
| - Err(_) => panic!("WEB_PAGE_OFFSET_CIDR_BLOCKLIST only allows IPv4 CIDR blocks"), |
184 | 191 | })
|
185 | 192 | .collect::<Vec<_>>()
|
186 | 193 | }
|
@@ -232,23 +239,32 @@ fn parse_cidr_block_list_successfully() {
|
232 | 239 | let blocks = parse_cidr_blocks(&cidr_blocks);
|
233 | 240 | assert_eq!(
|
234 | 241 | vec![
|
235 |
| - "127.0.0.1/24".parse::<Ipv4Network>().unwrap(), |
236 |
| - "192.168.0.1/31".parse::<Ipv4Network>().unwrap(), |
| 242 | + "127.0.0.1/24".parse::<IpNetwork>().unwrap(), |
| 243 | + "192.168.0.1/31".parse::<IpNetwork>().unwrap(), |
237 | 244 | ],
|
238 | 245 | blocks,
|
239 | 246 | );
|
240 | 247 | }
|
241 | 248 |
|
242 | 249 | #[test]
|
243 | 250 | #[should_panic]
|
244 |
| -fn parse_cidr_blocks_panics_when_host_prefix_is_too_low() { |
245 |
| - let input = vec!["127.0.0.1/8".to_string()]; |
246 |
| - parse_cidr_blocks(&input); |
| 251 | +fn parse_cidr_blocks_panics_when_host_ipv4_prefix_is_too_low() { |
| 252 | + parse_cidr_blocks(&vec!["127.0.0.1/8".to_string()]); |
247 | 253 | }
|
248 | 254 |
|
249 | 255 | #[test]
|
250 | 256 | #[should_panic]
|
251 |
| -fn parse_cidr_blocks_panics_when_ipv6_is_given() { |
252 |
| - let input = vec!["2002::1234:abcd:ffff:c0a8:101/64".to_string()]; |
253 |
| - parse_cidr_blocks(&input); |
| 257 | +fn parse_cidr_blocks_panics_when_host_ipv6_prefix_is_too_low() { |
| 258 | + parse_cidr_blocks(&vec![ |
| 259 | + "2001:0db8:0123:4567:89ab:cdef:1234:5678/56".to_string() |
| 260 | + ]); |
| 261 | +} |
| 262 | + |
| 263 | +#[test] |
| 264 | +fn parse_ipv6_based_cidr_blocks() { |
| 265 | + let input = vec![ |
| 266 | + "2002::1234:abcd:ffff:c0a8:101/64".to_string(), |
| 267 | + "2001:0db8:0123:4567:89ab:cdef:1234:5678/92".to_string(), |
| 268 | + ]; |
| 269 | + assert_eq!(2, parse_cidr_blocks(&input).len()); |
254 | 270 | }
|
0 commit comments