From b22beb3fa39edab7b0e01f5aee8e2ca9800319a6 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Thu, 20 Apr 2023 13:28:48 +0200 Subject: [PATCH] Remove Cypress based UI tests (#1035) --- .github/workflows/ci.yml | 9 +- .github/workflows/coverage.yml | 5 +- Cargo.lock | 49 - Cargo.toml | 8 +- doc/development/multi_user/authentication.md | 8 +- doc/development/multi_user/overview.md | 2 - doc/development/multi_user/testing.md | 47 +- tests/e2e/data.py | 17 - tests/e2e/simple_rp_roa_test.py | 294 ---- tests/multi_user_admin_token.rs | 8 - tests/multi_user_config_file.rs | 8 - tests/multi_user_config_file_with_ta.rs | 72 - tests/multi_user_openid_connect.rs | 14 - ...r_openid_connect_provider_not_available.rs | 14 - ...nid_connect_provider_with_custom_logout.rs | 14 - ...d_connect_provider_with_fallback_logout.rs | 14 - ...openid_connect_provider_with_revocation.rs | 14 - tests/multi_user_team_based_access.rs | 12 - tests/testbed_ui.rs | 8 - tests/ui/cypress/plugins/index.js | 25 - .../cypress/specs/multi_user_admin_token.js | 54 - .../cypress/specs/multi_user_config_file.js | 120 -- .../specs/multi_user_config_file_with_ta.js | 482 ------ .../specs/multi_user_openid_connect.js | 424 ------ ...r_openid_connect_provider_not_available.js | 61 - ...nid_connect_provider_with_custom_logout.js | 35 - ...d_connect_provider_with_fallback_logout.js | 40 - ...openid_connect_provider_with_revocation.js | 61 - .../specs/multi_user_team_based_access.js | 56 - tests/ui/cypress/specs/testbed_ui.js | 99 -- tests/ui/cypress/support/index.js | 58 - tests/ui/mod.rs | 175 --- tests/ui/openid_connect_mock.rs | 1354 ----------------- 33 files changed, 10 insertions(+), 3651 deletions(-) delete mode 100644 tests/e2e/data.py delete mode 100644 tests/e2e/simple_rp_roa_test.py delete mode 100644 tests/multi_user_admin_token.rs delete mode 100644 tests/multi_user_config_file.rs delete mode 100644 tests/multi_user_config_file_with_ta.rs delete mode 100644 tests/multi_user_openid_connect.rs delete mode 100644 tests/multi_user_openid_connect_provider_not_available.rs delete mode 100644 tests/multi_user_openid_connect_provider_with_custom_logout.rs delete mode 100644 tests/multi_user_openid_connect_provider_with_fallback_logout.rs delete mode 100644 tests/multi_user_openid_connect_provider_with_revocation.rs delete mode 100644 tests/multi_user_team_based_access.rs delete mode 100644 tests/testbed_ui.rs delete mode 100644 tests/ui/cypress/plugins/index.js delete mode 100644 tests/ui/cypress/specs/multi_user_admin_token.js delete mode 100644 tests/ui/cypress/specs/multi_user_config_file.js delete mode 100644 tests/ui/cypress/specs/multi_user_config_file_with_ta.js delete mode 100644 tests/ui/cypress/specs/multi_user_openid_connect.js delete mode 100644 tests/ui/cypress/specs/multi_user_openid_connect_provider_not_available.js delete mode 100644 tests/ui/cypress/specs/multi_user_openid_connect_provider_with_custom_logout.js delete mode 100644 tests/ui/cypress/specs/multi_user_openid_connect_provider_with_fallback_logout.js delete mode 100644 tests/ui/cypress/specs/multi_user_openid_connect_provider_with_revocation.js delete mode 100644 tests/ui/cypress/specs/multi_user_team_based_access.js delete mode 100644 tests/ui/cypress/specs/testbed_ui.js delete mode 100644 tests/ui/cypress/support/index.js delete mode 100644 tests/ui/mod.rs delete mode 100644 tests/ui/openid_connect_mock.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d354c7f1..6b87f9b1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,7 +50,7 @@ jobs: # Test with no features, default features ("") and all except UI tests. # Order: fewest features to most features. - args: ["--no-default-features", "", "--features all-except-ui-tests"] + args: ["--no-default-features", "", "--features all"] steps: - name: Checkout repository uses: actions/checkout@v2 @@ -60,13 +60,6 @@ jobs: rust-version: ${{ matrix.rust }} - run: cargo build --verbose ${{ matrix.args }} --locked - run: cargo test --verbose ${{ matrix.args }} -- --test-threads=1 2>&1 - - name: Archive Cypress UI test image & video captures - if: ${{ always() }} - uses: actions/upload-artifact@v2 - with: - name: cypress-ui-test-captures ${{ matrix.os }} ${{ matrix.rust }} - path: target/ui/ - if-no-files-found: ignore pykmip-test: name: pykmip-test diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 0153ea18..1e2409b9 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -28,10 +28,7 @@ jobs: with: rust-version: ${{ matrix.rust }} - run: cargo install cargo-tarpaulin - # use a long timeout with tarpaulin as UI tests have to docker pull the - # cypress.io image which can cause a test timeout with the default tarpaulin - # timeout of 1 minute. - - run: cargo tarpaulin --locked --verbose --out Html --timeout 900 ${{ matrix.args }} + - run: cargo tarpaulin --locked --verbose --out Html ${{ matrix.args }} - name: Archive code coverage results uses: actions/upload-artifact@v2 with: diff --git a/Cargo.lock b/Cargo.lock index fe638ebc..efd866f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -50,12 +50,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "ascii" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbf56136a5198c7b01a49e3afcbef6cf84597273d298f54432926024107b0109" - [[package]] name = "ascii-canvas" version = "3.0.0" @@ -214,12 +208,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "chunked_transfer" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e" - [[package]] name = "cipher" version = "0.2.5" @@ -336,16 +324,6 @@ dependencies = [ "target-lexicon", ] -[[package]] -name = "ctrlc" -version = "3.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b37feaa84e6861e00a1f5e5aa8da3ee56d605c9992d33e082786754828e20865" -dependencies = [ - "nix", - "winapi", -] - [[package]] name = "cxx" version = "1.0.79" @@ -975,7 +953,6 @@ dependencies = [ "chrono", "clap", "cryptoki", - "ctrlc", "fern", "fslock", "futures", @@ -1003,7 +980,6 @@ dependencies = [ "serde", "serde_json", "syslog", - "tiny_http", "tokio", "tokio-rustls", "toml", @@ -1203,17 +1179,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" -[[package]] -name = "nix" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "195cdbc1741b8134346d515b3a56a1c94b0912758009cfd53f99ea0f57b065fc" -dependencies = [ - "bitflags", - "cfg-if", - "libc", -] - [[package]] name = "num-bigint" version = "0.4.3" @@ -2168,20 +2133,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "tiny_http" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce51b50006056f590c9b7c3808c3bd70f0d1101666629713866c227d6e58d39" -dependencies = [ - "ascii", - "chrono", - "chunked_transfer", - "log", - "openssl", - "url", -] - [[package]] name = "tinyvec" version = "1.6.0" diff --git a/Cargo.toml b/Cargo.toml index 7b89cf20..27e6dfdc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -74,16 +74,15 @@ syslog = "^4.0" [features] default = [ "multi-user", "hsm" ] +hsm = ["backoff", "kmip", "once_cell", "cryptoki", "r2d2"] multi-user = [ "basic-cookies", "jmespatch/sync", "regex", "oso", "openidconnect", "rpassword", "scrypt", "unicode-normalization", "urlparse" ] static-openssl = [ "openssl/vendored" ] # Preview features - not ready for production use rta = [] -hsm = ["backoff", "kmip", "once_cell", "cryptoki", "r2d2"] # Internal features - not for external use -all-except-ui-tests = [ "multi-user", "rta", "static-openssl" ] -ui-tests = [] +all = [ "multi-user", "rta", "static-openssl" ] hsm-tests-kmip = [ "hsm" ] hsm-tests-pkcs11 = [ "hsm" ] @@ -95,9 +94,6 @@ panic = "abort" [dev-dependencies] regex = "1.5.5" urlparse = "^0.7" -# For user management -ctrlc = "^3.1" -tiny_http = { version = "^0.8", features = ["ssl"] } # ------------------------------------------------------------------------------ # START DEBIAN PACKAGING diff --git a/doc/development/multi_user/authentication.md b/doc/development/multi_user/authentication.md index 2ebd2ff8..d203951b 100644 --- a/doc/development/multi_user/authentication.md +++ b/doc/development/multi_user/authentication.md @@ -506,10 +506,10 @@ In no particular order: #### Testing -Testing the provider code in isolation cannot ensure that the chain of communication from Lagosta -via Krill to the OP and back again works as expected and yields an acceptable end user experience. Therefore the -majority of the tests use Cypress to drive Lagosta in a browser connected to an instance of Krill which in turn connects -to a locally deployed mock OP. +Testing of the UI interaction is handled by dedicated tests in the UI repository. Further tests are implemented +inline in the Oso rule files, with a few explicit Oso tests also invoked by Krill immediately after Oso is +initialized and rule files have been loaded. + #### Flow This implementation supports the [OpenID Connect Authorization Code Flow](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth) diff --git a/doc/development/multi_user/overview.md b/doc/development/multi_user/overview.md index 8b05aaa6..25c16e8e 100644 --- a/doc/development/multi_user/overview.md +++ b/doc/development/multi_user/overview.md @@ -24,8 +24,6 @@ The feature adds several related but distinct capabilities to Krill: - (De)Serialization - (En/De)cryption _(powered by [rust-openssl](https://crates.io/crates/openssl))_ - - Automated browser based testing _(powered by [Cypress](https://www.cypress.io/))_ - - Password hashing support in `krillc` - Propagation of the current identity all the way down to the event history diff --git a/doc/development/multi_user/testing.md b/doc/development/multi_user/testing.md index 3b14c867..05873b52 100644 --- a/doc/development/multi_user/testing.md +++ b/doc/development/multi_user/testing.md @@ -7,51 +7,8 @@ At the lowest level, any test that exercises Krill from the outside will exercis external and internal actions require an `Actor` instance, and all external requests must pass authentication and authorization checks. -However, not all tests will exercise login as that is only used by Lagosta. The existing Krill integration tests use a +However, not all tests will exercise login as that is only used by the UI. The existing Krill integration tests use a fixed admin API token without login because that was all Krill supported before, and must continue to work for the direct REST API clients and indirect REST API client via `krillc`. -Also, as the multi-user feature is aimed entirely (at present) at Lagosta users, it only works if it works from the UI -all the way down to the event log, testing at the Krill internal library boundary or the Krill REST API boundary is -not sufficient. - -As such most of the multi-user tests use [Cypress](https://cypress.io) to drive a headless browser connecting to a -locally launched instance of Krill, and for the OpenID Connect tests a homebrewed mock Rust OpenID Connect provider is -run in-process alongside Krill as well. - -For ease Cypress is invoked via Docker as it has an official Docker image which contains everything needed. However, -this has not yet been verified as working on Mac OS. Cypress in turn is driven by test suites defined in Javascript. - -As UI based tests can be quite slow they are gated behind their own `ui-tests` feature, which also has the benefit -that users without a working Docker setup are still able to run `cargo test`. - -To run the UI tests one must therefore do: - -``` -cargo test --features ui-tests -``` - -Cypress has a very useful interactive test run mode which can be launched like so: - -``` -$ xhost + -$ CYPRESS_INTERACTIVE=1 cargo test --features ui-tests -``` - -You want the `` because you want Krill to be setup correctly to run a particular test that you will then run interactively, you don't want Krill to run all tests and constantly be changing the backend state as a result while you try to use Cypress to run a single test suite that has expectations about the state that Krill is in. - -For example you might do: -``` -$ xhost + -$ CYPRESS_INTERACTIVE=1 cargo test --features ui-tests multi_user_config_file_with_ta -``` - -After a short delay a browser window should open with a Cypress welcome message something like this: - -![Cypress welcome popup](images/cypress-welcome-popup.png) - -Dismiss the message and then click on the `multi_user_config_file_with_ta.js` test in the tree of tests that is shown to you, i.e. run the same test as you invoked with `cargo test` so that Krill has the expected configuration and starting conditions. - -You should then see something like this: - -![Cypress test running](images/cypress-test-running.png) +Testing of the UI specific aspects of multi-user support is handled by dedicated tests in the UI repository. diff --git a/tests/e2e/data.py b/tests/e2e/data.py deleted file mode 100644 index a5c8b9f7..00000000 --- a/tests/e2e/data.py +++ /dev/null @@ -1,17 +0,0 @@ -from krill_ca_api.models.roa import ROA - - -TEST_ROAS = [ - ROA(prefix = '2001:12ff::/32', max_length=48, asn=22548), - ROA(prefix = '200.160.0.0/20', max_length=24, asn=22548), - ROA(prefix = '189.76.96.0/19', max_length=24, asn=11752), - ROA(prefix = '2001:12fe::/32', max_length=48, asn=11752), -] - - -KRILL_PARENT_ASNS = 'AS1251, AS1916, AS2715-AS2716, AS4230, AS5772, AS6125, AS6505, AS7048, AS7063, AS7162, AS7298, AS7313, AS7365, AS7465, AS7738, AS7890, AS8055, AS8141, AS8167, AS10285, AS10362, AS10412, AS10417, AS10429, AS10454, AS10495, AS10531, AS10600, AS10630, AS10670, AS10688, AS10704, AS10715, AS10733, AS10841, AS10875, AS10881, AS10897, AS10906, AS10938, AS10954, AS11097, AS11242, AS11271, AS11284, AS11295, AS11335, AS11338, AS11390, AS11415, AS11419, AS11431-AS11432, AS11497, AS11592, AS11644, AS11706, AS11751-AS11752, AS11801-AS11802, AS11835, AS11844, AS11896, AS11921, AS11993, AS12135-AS12136, AS12140, AS13353, AS13357, AS13459, AS13495, AS13522, AS13584, AS13761, AS13874, AS13878, AS13914, AS13935, AS14026, AS14030, AS14087, AS14204, AS14282, AS14346, AS14457, AS14463, AS14553, AS14571, AS14624, AS14650, AS14723, AS14840, AS14868, AS14886, AS15180, AS15201, AS15256, AS16397, AS16594, AS16685, AS16712, AS16735-AS16736, AS16885, AS16891, AS16911, AS17108, AS17208, AS17222, AS17379, AS18479, AS18547, AS18644, AS18739, AS18782, AS18836, AS18881, AS19089, AS19182, AS19200, AS19361, AS19611, AS19723, AS19763, AS19990, AS20044, AS20116, AS20121, AS20142, AS20266, AS21506, AS21571, AS21574, AS21612, AS21674, AS21741, AS21911, AS22055, AS22085, AS22092, AS22128-AS22129, AS22133, AS22148, AS22177, AS22250, AS22341, AS22356, AS22371, AS22381, AS22407, AS22431, AS22515, AS22548, AS22689, AS22706, AS22745, AS22819, AS22876, AS23002, AS23074, AS23105-AS23106, AS23128, AS23202, AS23289, AS25832, AS25933, AS26090, AS26104, AS26118, AS26162, AS26218, AS26592, AS26598-AS26599, AS26602, AS26606-AS26607, AS26609, AS26615-AS26616, AS26622, AS27652, AS27656, AS27684, AS27688, AS27693, AS27697, AS27699, AS27710, AS27712, AS27715, AS27720, AS28121-AS28122, AS28124-AS28146, AS28148-AS28154, AS28156-AS28178, AS28180-AS28184, AS28186-AS28213, AS28215-AS28216, AS28218-AS28220, AS28222-AS28258, AS28260-AS28267, AS28269-AS28280, AS28282-AS28288, AS28290-AS28301, AS28304-AS28311, AS28313, AS28315, AS28320-AS28324, AS28326-AS28353, AS28355-AS28362, AS28364, AS28366-AS28370, AS28571-AS28610, AS28612-AS28647, AS28649-AS28650, AS28652-AS28654, AS28656-AS28658, AS28660-AS28671, AS52516-AS52520, AS52522-AS52589, AS52591-AS52668, AS52670-AS52700, AS52702-AS52729, AS52731-AS52762, AS52764-AS52815, AS52817-AS52831, AS52833-AS52834, AS52836-AS52948, AS52950-AS53054, AS53057-AS53090, AS53093-AS53104, AS53106-AS53127, AS53129-AS53147, AS53149-AS53176, AS53178-AS53191, AS53193-AS53206, AS53208-AS53209, AS53211-AS53225, AS53227-AS53247, AS61568-AS61600, AS61632-AS61768, AS61770-AS61790, AS61792-AS61951, AS262268-AS262338, AS262340, AS262342-AS262409, AS262411-AS262617, AS262619-AS262625, AS262627-AS262630, AS262632-AS262657, AS262659-AS262677, AS262679-AS262696, AS262698-AS262702, AS262704-AS262717, AS262719-AS262770, AS262772-AS262787, AS262789-AS262815, AS262817-AS262848, AS262850-AS262858, AS262860-AS262911, AS262937-AS262940, AS262942-AS262943, AS262945-AS262968, AS262970, AS262972-AS262975, AS262977-AS262999, AS263002-AS263016, AS263018-AS263113, AS263116-AS263122, AS263124-AS263126, AS263128-AS263133, AS263135-AS263137, AS263139-AS263140, AS263142-AS263147, AS263151-AS263156, AS263159-AS263160, AS263162-AS263166, AS263250-AS263305, AS263307-AS263378, AS263380-AS263391, AS263393-AS263459, AS263461-AS263528, AS263530-AS263668, AS263670-AS263679, AS263837-AS263861, AS263863-AS263870, AS263872-AS264017, AS264019-AS264080, AS264082-AS264084, AS264086-AS264108, AS264110-AS264130, AS264132-AS264141, AS264143-AS264150, AS264152-AS264164, AS264166-AS264175, AS264177-AS264178, AS264180-AS264276, AS264278-AS264291, AS264293-AS264398, AS264400-AS264407, AS264409, AS264411-AS264418, AS264420-AS264430, AS264432-AS264534, AS264536-AS264571, AS264573-AS264592, AS264594-AS264604, AS264860-AS264921, AS264923-AS265109, AS265111-AS265114, AS265116-AS265119, AS265121-AS265195, AS265197-AS265315, AS265317-AS265351, AS265353-AS265443, AS265445-AS265500, AS265885-AS265899, AS265901-AS265907, AS265909-AS265920, AS265922-AS266006, AS266008-AS266224, AS266226-AS266256, AS266258-AS266584, AS266586-AS266652, AS266911-AS266912, AS266914-AS266979, AS266981-AS266993, AS266995-AS267074, AS267076-AS267098, AS267100-AS267153, AS267155-AS267643, AS267645-AS267676, AS267933-AS268723, AS268725-AS269643' -KRILL_PARENT_IPV4S = '45.4.4.0-45.4.83.255, 45.4.96.0/24, 45.4.104.0-45.4.127.255, 45.4.132.0/22, 45.4.140.0-45.4.159.255, 45.4.176.0-45.4.195.255, 45.4.208.0/21, 45.4.220.0-45.4.251.255, 45.5.4.0/22, 45.5.14.0/24, 45.5.16.0/22, 45.5.32.0-45.5.51.255, 45.5.72.0/22, 45.5.80.0-45.5.91.255, 45.5.96.0-45.5.115.255, 45.5.128.0-45.5.147.255, 45.5.156.0/22, 45.5.168.0/22, 45.5.176.0/22, 45.5.192.0-45.5.215.255, 45.5.220.0-45.6.3.255, 45.6.12.0-45.6.39.255, 45.6.52.0-45.6.59.255, 45.6.64.0/22, 45.6.72.0-45.6.103.255, 45.6.108.0-45.6.131.255, 45.6.136.0/22, 45.6.144.0-45.6.211.255, 45.6.216.0/21, 45.6.228.0-45.6.247.255, 45.7.0.0-45.7.27.255, 45.7.32.0-45.7.43.255, 45.7.48.0-45.7.83.255, 45.7.100.0-45.7.123.255, 45.7.128.0/22, 45.7.144.0-45.7.207.255, 45.7.212.0-45.7.227.255, 45.7.232.0/22, 45.65.128.0/21, 45.65.140.0-45.65.147.255, 45.65.156.0/22, 45.65.164.0-45.65.187.255, 45.65.192.0/21, 45.65.201.0/24, 45.65.204.0-45.65.223.255, 45.65.228.0/22, 45.65.236.0/22, 45.65.253.0/24, 45.70.0.0/21, 45.70.16.0-45.70.55.255, 45.70.60.0-45.70.87.255, 45.70.92.0-45.70.115.255, 45.70.120.0-45.70.151.255, 45.70.156.0-45.70.167.255, 45.70.172.0-45.70.179.255, 45.70.188.0-45.70.195.255, 45.70.204.0-45.70.219.255, 45.70.224.0/22, 45.70.232.0/22, 45.70.244.0-45.70.255.255, 45.71.4.0/24, 45.71.6.0/24, 45.71.12.0/22, 45.71.20.0-45.71.31.255, 45.71.40.0/22, 45.71.48.0/22, 45.71.60.0-45.71.105.255, 45.71.107.0-45.71.111.255, 45.71.116.0-45.71.151.255, 45.71.160.0-45.71.179.255, 45.71.188.0-45.71.195.255, 45.71.208.0-45.71.251.255, 45.160.0.0/22, 45.160.8.0/22, 45.160.16.0-45.160.27.255, 45.160.36.0-45.160.71.255, 45.160.76.0/23, 45.160.80.0-45.160.131.255, 45.160.136.0-45.160.155.255, 45.160.160.0-45.160.187.255, 45.160.192.0/22, 45.160.204.0-45.160.211.255, 45.160.216.0/21, 45.160.228.0-45.161.7.255, 45.161.12.0-45.161.23.255, 45.161.28.0/22, 45.161.36.0-45.161.43.255, 45.161.48.0-45.161.107.255, 45.161.120.0-45.161.131.255, 45.161.136.0-45.161.167.255, 45.161.176.0/22, 45.161.184.0/22, 45.161.192.0-45.161.235.255, 45.161.240.0/20, 45.162.4.0-45.162.19.255, 45.162.22.0-45.162.59.255, 45.162.64.0/21, 45.162.80.0/23, 45.162.92.0-45.162.99.255, 45.162.104.0/22, 45.162.112.0-45.162.124.255, 45.162.127.0-45.162.139.255, 45.162.144.0-45.162.167.255, 45.162.172.0-45.162.179.255, 45.162.188.0/22, 45.162.196.0-45.162.203.255, 45.162.212.0-45.162.255.255, 45.163.4.0-45.163.17.255, 45.163.24.0/22, 45.163.32.0/22, 45.163.40.0/21, 45.163.52.0-45.163.79.255, 45.163.84.0-45.163.119.255, 45.163.132.0/22, 45.163.144.0-45.163.187.255, 45.163.192.0-45.163.203.255, 45.163.208.0-45.163.247.255, 45.163.252.0-45.164.11.255, 45.164.24.0-45.164.63.255, 45.164.68.0-45.164.107.255, 45.164.112.0-45.164.135.255, 45.164.140.0-45.164.147.255, 45.164.152.0-45.164.167.255, 45.164.176.0-45.164.203.255, 45.164.208.0-45.164.227.255, 45.164.232.0/22, 45.164.240.0-45.165.35.255, 45.165.48.0/22, 45.165.54.0-45.165.111.255, 45.165.116.0-45.165.151.255, 45.165.153.0/24, 45.165.156.0-45.165.167.255, 45.165.172.0-45.166.15.255, 45.166.20.0-45.166.71.255, 45.166.79.0/24, 45.166.84.0-45.166.91.255, 45.166.96.0/22, 45.166.104.0/22, 45.166.112.0-45.166.143.255, 45.166.148.0-45.166.175.255, 45.166.180.0-45.166.215.255, 45.166.220.0/22, 45.166.226.0-45.166.251.255, 45.167.4.0-45.167.11.255, 45.167.16.0/24, 45.167.28.0-45.167.87.255, 45.167.96.0/20, 45.167.116.0/22, 45.167.122.0/23, 45.167.128.0-45.167.155.255, 45.167.160.0/21, 45.167.172.0/22, 45.167.178.0-45.167.191.255, 45.167.204.0-45.167.211.255, 45.167.216.0/22, 45.167.224.0/22, 45.167.232.0-45.167.247.255, 45.168.0.0-45.168.67.255, 45.168.72.0/21, 45.168.81.0-45.168.103.255, 45.168.108.0-45.168.171.255, 45.168.176.0/20, 45.168.200.0-45.168.211.255, 45.168.216.0-45.168.227.255, 45.168.240.0-45.169.35.255, 45.169.40.0-45.169.51.255, 45.169.56.0/22, 45.169.64.0-45.169.91.255, 45.169.97.0/24, 45.169.108.0/22, 45.169.116.0-45.169.139.255, 45.169.152.0-45.169.162.255, 45.169.172.0-45.169.191.255, 45.169.196.0-45.169.235.255, 45.169.240.0/22, 45.169.248.0/23, 45.169.252.0/24, 45.169.254.0-45.170.7.255, 45.170.16.0-45.170.27.255, 45.170.52.0-45.170.99.255, 45.170.112.0-45.170.123.255, 45.170.136.0-45.170.183.255, 45.170.192.0-45.170.211.255, 45.170.216.0/21, 45.170.228.0/22, 45.170.236.0/22, 45.171.0.0-45.171.35.255, 45.171.40.0/21, 45.171.50.0-45.171.63.255, 45.171.68.0-45.171.75.255, 45.171.78.0/23, 45.171.83.0-45.171.107.255, 45.171.116.0/23, 45.171.119.0/24, 45.171.122.0-45.171.131.255, 45.171.136.0-45.171.155.255, 45.171.164.0-45.171.179.255, 45.171.184.0-45.171.199.255, 45.171.204.0-45.171.219.255, 45.171.228.0-45.172.7.255, 45.172.12.0/22, 45.172.20.0/22, 45.172.32.0-45.172.87.255, 45.172.96.0-45.172.107.255, 45.172.112.0-45.172.135.255, 45.172.144.0/21, 45.172.156.0-45.172.175.255, 45.172.180.0/22, 45.172.192.0-45.172.217.255, 45.172.232.0-45.172.247.255, 45.172.252.0/22, 45.173.13.0/24, 45.173.20.0-45.173.39.255, 45.173.45.0-45.173.51.255, 45.173.64.0/22, 45.173.76.0-45.173.111.255, 45.173.116.0/22, 45.173.124.0/22, 45.173.132.0-45.173.167.255, 45.173.172.0-45.173.179.255, 45.173.184.0/21, 45.173.220.0-45.173.227.255, 45.173.232.0-45.173.243.255, 45.173.248.0-45.174.7.255, 45.174.9.0-45.174.19.255, 45.174.28.0-45.174.43.255, 45.174.64.0/22, 45.174.80.0/22, 45.174.96.0/23, 45.174.100.0/22, 45.174.112.0-45.174.123.255, 45.174.128.0/24, 45.174.132.0-45.174.147.255, 45.174.152.0-45.174.167.255, 45.174.176.0/23, 45.174.180.0-45.174.195.255, 45.174.208.0/20, 45.174.232.0/21, 45.175.0.0-45.175.19.255, 45.175.23.0-45.175.35.255, 45.175.44.0-45.175.63.255, 45.175.72.0-45.175.99.255, 45.175.104.0-45.175.135.255, 45.175.144.0/22, 45.175.168.0-45.175.211.255, 45.175.216.0-45.175.231.255, 45.175.240.0-45.175.251.255, 45.176.0.0/21, 45.176.12.0-45.176.19.255, 45.176.24.0/21, 45.176.36.0-45.176.69.255, 45.176.72.0-45.176.83.255, 45.176.100.0-45.176.107.255, 45.176.112.0/22, 45.176.120.0/21, 45.176.132.0-45.176.163.255, 45.176.168.0-45.176.187.255, 45.176.196.0-45.176.231.255, 45.176.240.0/20, 45.177.4.0-45.177.15.255, 45.177.24.0-45.177.39.255, 45.177.44.0-45.177.51.255, 45.177.56.0/21, 45.177.76.0/22, 45.177.84.0/22, 45.177.100.0-45.177.107.255, 45.177.112.0-45.177.123.255, 45.177.132.0-45.177.143.255, 45.177.148.0-45.177.175.255, 45.177.184.0-45.177.195.255, 45.177.199.0/24, 45.177.208.0-45.177.235.255, 45.177.240.0/20, 45.178.16.0-45.178.35.255, 45.178.40.0/21, 45.178.56.0/21, 45.178.76.0-45.178.83.255, 45.178.92.0/22, 45.178.100.0/22, 45.178.108.0-45.178.131.255, 45.178.136.0-45.178.163.255, 45.178.168.0-45.178.183.255, 45.178.188.0/22, 45.178.200.0-45.178.243.255, 45.178.248.0/22, 45.179.0.0-45.179.11.255, 45.179.16.0-45.179.53.255, 45.179.56.0/22, 45.179.61.0-45.179.71.255, 45.179.76.0-45.179.91.255, 45.179.96.0-45.179.139.255, 45.179.144.0/21, 45.179.156.0/22, 45.179.168.0-45.179.191.255, 45.179.199.0/24, 45.179.204.0-45.179.243.255, 45.179.248.0/22, 45.180.0.0/21, 45.180.16.0/22, 45.180.28.0-45.180.43.255, 45.180.48.0-45.180.59.255, 45.180.64.0/22, 45.180.72.0/22, 45.180.80.0/23, 45.180.84.0-45.180.111.255, 45.180.113.0/24, 45.180.116.0/22, 45.180.128.0-45.180.139.255, 45.180.144.0-45.180.171.255, 45.180.178.0/24, 45.180.184.0-45.180.231.255, 45.180.236.0/22, 45.180.248.0-45.181.5.255, 45.181.7.0-45.181.11.255, 45.181.16.0-45.181.39.255, 45.181.48.0-45.181.67.255, 45.181.72.0-45.181.76.255, 45.181.80.0/22, 45.181.88.0-45.181.119.255, 45.181.132.0-45.181.155.255, 45.181.160.0/22, 45.181.168.0-45.181.187.255, 45.181.192.0-45.181.203.255, 45.181.208.0/20, 45.181.228.0-45.181.243.255, 45.181.252.0-45.182.11.255, 45.182.16.0/22, 45.182.24.0/22, 45.182.32.0/22, 45.182.40.0/24, 45.182.42.0/24, 45.182.44.0-45.182.79.255, 45.182.84.0-45.182.111.255, 45.182.120.0/22, 45.182.132.0-45.182.139.255, 45.182.144.0-45.182.179.255, 45.182.184.0/23, 45.182.192.0-45.182.219.255, 45.182.224.0-45.182.235.255, 45.182.240.0-45.183.3.255, 45.183.8.0-45.183.39.255, 45.183.48.0/22, 45.183.56.0/22, 45.183.64.0-45.183.99.255, 45.183.104.0/23, 45.183.112.0-45.183.135.255, 45.183.144.0-45.183.155.255, 45.183.160.0-45.183.171.255, 45.183.180.0/22, 45.183.188.0-45.183.195.255, 45.183.200.0-45.183.219.255, 45.183.222.0-45.183.246.255, 45.183.248.0-45.184.19.255, 45.184.24.0-45.184.83.255, 45.184.88.0/22, 45.184.96.0/22, 45.184.112.0/22, 45.184.120.0/22, 45.184.128.0/22, 45.184.136.0-45.184.151.255, 45.184.160.0-45.184.223.255, 45.184.232.0-45.184.247.255, 45.184.252.0-45.185.15.255, 45.185.24.0-45.185.29.255, 45.185.32.0-45.185.42.255, 45.185.44.0-45.185.51.255, 45.185.56.0-45.185.115.255, 45.185.120.0/21, 45.185.132.0-45.185.147.255, 45.185.149.0-45.185.159.255, 45.185.164.0-45.185.183.255, 45.185.192.0-45.185.203.255, 45.185.208.0-45.185.219.255, 45.185.224.0/20, 45.186.0.0/22, 45.186.8.0/22, 45.186.16.0/22, 45.186.32.0-45.186.43.255, 45.186.48.0-45.186.103.255, 45.186.112.0-45.186.123.255, 45.186.132.0/22, 45.186.142.0/23, 45.186.156.0-45.186.199.255, 45.186.212.0-45.186.251.255, 45.187.8.0-45.187.35.255, 45.187.40.0/22, 45.187.52.0-45.187.75.255, 45.187.80.0/21, 45.187.96.0-45.187.131.255, 45.187.136.0-45.187.147.255, 45.187.152.0-45.187.207.255, 45.187.212.0-45.187.247.255, 45.187.249.0-45.187.255.255, 45.188.4.0-45.188.19.255, 45.188.24.0-45.188.47.255, 45.188.52.0/22, 45.188.59.0-45.188.75.255, 45.188.80.0-45.188.91.255, 45.188.96.0-45.188.107.255, 45.188.112.0-45.188.123.255, 45.188.132.0/24, 45.188.134.0/23, 45.188.140.0-45.188.159.255, 45.188.168.0/22, 45.188.176.0-45.188.187.255, 45.188.192.0/20, 45.188.218.0/24, 45.188.220.0-45.188.227.255, 45.188.236.0-45.188.247.255, 45.188.252.0/22, 45.189.4.0-45.189.19.255, 45.189.24.0-45.189.35.255, 45.189.40.0-45.189.55.255, 45.189.64.0-45.189.75.255, 45.189.80.0-45.189.107.255, 45.189.120.0-45.189.147.255, 45.189.176.0/21, 45.189.204.0-45.189.215.255, 45.189.220.0-45.189.231.255, 45.189.240.0-45.189.251.255, 45.190.0.0-45.190.12.255, 45.190.14.0/24, 45.190.20.0-45.190.63.255, 45.190.68.0/22, 45.190.80.0/22, 45.190.100.0-45.190.123.255, 45.190.132.0/22, 45.190.152.0/22, 45.190.172.0-45.190.179.255, 45.190.204.0-45.190.219.255, 45.224.0.0/21, 45.224.12.0-45.224.19.255, 45.224.24.0/22, 45.224.32.0-45.224.51.255, 45.224.56.0-45.224.95.255, 45.224.108.0-45.224.115.255, 45.224.128.0-45.224.139.255, 45.224.160.0-45.224.183.255, 45.224.185.0/24, 45.224.187.0/24, 45.224.192.0-45.224.201.255, 45.224.204.0-45.224.227.255, 45.224.232.0-45.224.251.255, 45.225.4.0-45.225.27.255, 45.225.32.0/21, 45.225.48.0-45.225.67.255, 45.225.72.0/23, 45.225.84.0/22, 45.225.100.0/22, 45.225.108.0/22, 45.225.116.0-45.225.131.255, 45.225.136.0-45.225.151.255, 45.225.154.0/23, 45.225.160.0-45.225.183.255, 45.225.188.0-45.225.203.255, 45.225.208.0/22, 45.225.228.0-45.226.7.255, 45.226.12.0-45.226.27.255, 45.226.36.0-45.226.57.255, 45.226.60.0/22, 45.226.72.0-45.226.99.255, 45.226.104.0/21, 45.226.116.0-45.226.143.255, 45.226.148.0-45.226.167.255, 45.226.188.0-45.226.203.255, 45.226.208.0/20, 45.226.232.0-45.227.4.255, 45.227.6.0/23, 45.227.20.0-45.227.31.255, 45.227.40.0/21, 45.227.52.0-45.227.59.255, 45.227.72.0-45.227.87.255, 45.227.96.0/22, 45.227.104.0-45.227.127.255, 45.227.136.0-45.227.151.255, 45.227.156.0/22, 45.227.168.0/22, 45.227.180.0-45.227.195.255, 45.227.204.0-45.227.215.255, 45.227.220.0/22, 45.227.228.0-45.227.243.255, 45.227.248.0/22, 45.228.0.0/20, 45.228.20.0-45.228.35.255, 45.228.40.0-45.228.51.255, 45.228.80.0-45.228.135.255, 45.228.140.0-45.228.151.255, 45.228.157.0-45.228.171.255, 45.228.184.0/22, 45.228.192.0-45.228.201.255, 45.228.203.0-45.228.207.255, 45.228.212.0-45.228.219.255, 45.228.224.0/21, 45.228.236.0-45.229.3.255, 45.229.8.0/21, 45.229.20.0-45.229.27.255, 45.229.52.0/22, 45.229.64.0/21, 45.229.75.0-45.229.83.255, 45.229.88.0-45.229.127.255, 45.229.132.0/22, 45.229.138.0-45.229.147.255, 45.229.150.0/24, 45.229.152.0-45.229.167.255, 45.229.172.0-45.229.179.255, 45.229.184.0/22, 45.229.194.0/24, 45.229.200.0/22, 45.229.208.0-45.229.243.255, 45.230.0.0/21, 45.230.16.0/22, 45.230.24.0-45.230.32.255, 45.230.40.0/22, 45.230.52.0-45.230.59.255, 45.230.68.0/22, 45.230.76.0/22, 45.230.84.0/23, 45.230.88.0-45.230.123.255, 45.230.128.0-45.230.167.255, 45.230.176.0-45.230.195.255, 45.230.200.0/22, 45.230.208.0/21, 45.230.220.0-45.230.239.255, 45.230.244.0/22, 45.230.252.0-45.231.31.255, 45.231.36.0/22, 45.231.56.0-45.231.71.255, 45.231.76.0/22, 45.231.84.0-45.231.103.255, 45.231.112.0-45.231.147.255, 45.231.152.0/22, 45.231.159.0-45.231.167.255, 45.231.172.0-45.231.183.255, 45.231.188.0-45.231.205.255, 45.231.208.0-45.231.213.255, 45.231.228.0-45.231.247.255, 45.231.252.0/22, 45.232.4.0-45.232.11.255, 45.232.20.0-45.232.31.255, 45.232.36.0-45.232.45.255, 45.232.48.0-45.232.91.255, 45.232.100.0/22, 45.232.108.0-45.232.115.255, 45.232.124.0-45.232.143.255, 45.232.156.0-45.232.163.255, 45.232.168.0/22, 45.232.180.0-45.232.191.255, 45.232.196.0-45.232.203.255, 45.232.208.0-45.232.251.255, 45.233.0.0/22, 45.233.8.0-45.233.63.255, 45.233.76.0-45.233.91.255, 45.233.96.0/22, 45.233.104.0-45.233.115.255, 45.233.120.0-45.233.139.255, 45.233.144.0-45.233.167.255, 45.233.172.0-45.233.233.255, 45.233.238.0-45.234.31.255, 45.234.36.0-45.234.59.255, 45.234.64.0-45.234.83.255, 45.234.92.0-45.234.111.255, 45.234.124.0-45.234.155.255, 45.234.162.0/23, 45.234.168.0/22, 45.234.176.0/22, 45.234.184.0-45.234.223.255, 45.234.236.0-45.235.11.255, 45.235.16.0-45.235.35.255, 45.235.44.0-45.235.87.255, 45.235.92.0/22, 45.235.100.0-45.235.119.255, 45.235.124.0/22, 45.235.132.0-45.235.139.255, 45.235.144.0-45.235.171.255, 45.235.176.0-45.235.211.255, 45.235.216.0/21, 45.235.226.0/24, 45.235.232.0-45.235.251.255, 45.236.0.0-45.236.23.255, 45.236.36.0/22, 45.236.48.0-45.236.79.255, 45.236.84.0/22, 45.236.96.0/22, 45.236.108.0-45.236.119.255, 45.236.121.0-45.236.123.255, 45.236.132.0-45.236.139.255, 45.236.144.0/22, 45.236.152.0-45.236.163.255, 45.236.176.0/21, 45.236.188.0/22, 45.236.196.0-45.236.227.255, 45.236.236.0-45.236.243.255, 45.236.248.0-45.237.35.255, 45.237.40.0/22, 45.237.56.0-45.237.83.255, 45.237.92.0-45.237.131.255, 45.237.140.0-45.237.167.255, 45.237.180.0/22, 45.237.188.0-45.237.219.255, 45.237.224.0-45.238.7.255, 45.238.24.0/22, 45.238.32.0/22, 45.238.40.0-45.238.51.255, 45.238.64.0-45.238.103.255, 45.238.108.0-45.238.139.255, 45.238.148.0/22, 45.238.160.0/20, 45.238.178.0/24, 45.238.184.0/22, 45.238.200.0-45.238.211.255, 45.238.224.0-45.238.247.255, 45.238.252.0-45.239.15.255, 45.239.20.0/23, 45.239.24.0/22, 45.239.40.0/22, 45.239.52.0-45.239.59.255, 45.239.72.0/22, 45.239.80.0/22, 45.239.100.0-45.239.106.255, 45.239.113.0/24, 45.239.132.0-45.239.159.255, 45.239.164.0-45.239.207.255, 45.239.212.0-45.239.255.255, 72.44.16.0/20, 128.201.0.0/22, 128.201.8.0-128.201.19.255, 128.201.24.0/21, 128.201.40.0-128.201.79.255, 128.201.84.0/22, 128.201.92.0-128.201.107.255, 128.201.120.0-128.201.131.255, 128.201.136.0/21, 128.201.148.0-128.201.159.255, 128.201.164.0/22, 128.201.172.0-128.201.223.255, 128.201.228.0-128.201.235.255, 128.201.240.0/20, 131.0.4.0-131.0.51.255, 131.0.56.0-131.0.71.255, 131.0.76.0-131.0.103.255, 131.0.112.0-131.0.123.255, 131.0.132.0/22, 131.0.140.0-131.0.167.255, 131.0.176.0-131.0.195.255, 131.0.200.0-131.0.211.255, 131.0.216.0-131.0.231.255, 131.0.240.0/20, 131.72.4.0-131.72.23.255, 131.72.32.0-131.72.71.255, 131.72.80.0-131.72.111.255, 131.72.116.0-131.72.131.255, 131.72.140.0-131.72.155.255, 131.72.160.0/21, 131.72.172.0-131.72.203.255, 131.72.216.0/21, 131.72.244.0-131.72.255.255, 131.100.4.0-131.100.27.255, 131.100.32.0/22, 131.100.40.0-131.100.63.255, 131.100.68.0-131.100.87.255, 131.100.92.0-131.100.99.255, 131.100.104.0/22, 131.100.112.0-131.100.139.255, 131.100.144.0/20, 131.100.164.0-131.100.179.255, 131.100.188.0-131.100.199.255, 131.100.204.0-131.100.255.255, 131.108.8.0/21, 131.108.24.0-131.108.35.255, 131.108.44.0-131.108.67.255, 131.108.72.0/21, 131.108.84.0-131.108.139.255, 131.108.144.0-131.108.167.255, 131.108.172.0-131.108.191.255, 131.108.196.0-131.108.207.255, 131.108.212.0-131.108.231.255, 131.108.236.0-131.108.255.255, 131.161.0.0-131.161.51.255, 131.161.60.0-131.161.79.255, 131.161.92.0-131.161.99.255, 131.161.104.0-131.161.147.255, 131.161.156.0-131.161.183.255, 131.161.188.0-131.161.199.255, 131.161.204.0-131.161.231.255, 131.161.240.0/22, 131.161.248.0/22, 131.196.4.0/22, 131.196.16.0-131.196.27.255, 131.196.40.0-131.196.51.255, 131.196.56.0/22, 131.196.64.0/21, 131.196.76.0/22, 131.196.84.0-131.196.111.255, 131.196.116.0-131.196.123.255, 131.196.128.0-131.196.139.255, 131.196.144.0-131.196.175.255, 131.196.184.0/22, 131.196.196.0-131.196.207.255, 131.196.216.0-131.196.243.255, 131.221.12.0/22, 131.221.20.0/22, 131.221.36.0/22, 131.221.44.0-131.221.63.255, 131.221.68.0-131.221.111.255, 131.221.116.0-131.221.143.255, 131.221.148.0/22, 131.221.156.0-131.221.163.255, 131.221.168.0-131.221.255.255, 131.255.0.0/22, 131.255.8.0/22, 131.255.16.0-131.255.39.255, 131.255.44.0-131.255.59.255, 131.255.64.0-131.255.103.255, 131.255.108.0-131.255.135.255, 131.255.140.0-131.255.179.255, 131.255.184.0/21, 131.255.196.0-131.255.247.255, 131.255.252.0/22, 132.255.12.0-132.255.19.255, 132.255.24.0-132.255.67.255, 132.255.72.0-132.255.111.255, 132.255.116.0-132.255.123.255, 132.255.128.0/22, 132.255.136.0-132.255.163.255, 132.255.168.0-132.255.199.255, 132.255.204.0/22, 132.255.212.0-132.255.223.255, 132.255.228.0-132.255.235.255, 132.255.240.0/20, 138.0.0.0/21, 138.0.16.0-138.0.39.255, 138.0.44.0-138.0.55.255, 138.0.60.0-138.0.87.255, 138.0.92.0-138.0.103.255, 138.0.108.0-138.0.115.255, 138.0.124.0-138.0.151.255, 138.0.160.0-138.0.183.255, 138.0.188.0-138.0.227.255, 138.0.232.0/21, 138.0.244.0-138.0.255.255, 138.36.0.0/20, 138.36.20.0/22, 138.36.28.0-138.36.51.255, 138.36.56.0/21, 138.36.68.0-138.36.75.255, 138.36.80.0-138.36.91.255, 138.36.100.0-138.36.135.255, 138.36.140.0/22, 138.36.156.0-138.36.219.255, 138.36.224.0-138.36.235.255, 138.36.240.0-138.36.251.255, 138.59.20.0/22, 138.59.28.0-138.59.63.255, 138.59.68.0-138.59.107.255, 138.59.112.0/22, 138.59.120.0-138.59.131.255, 138.59.136.0/22, 138.59.144.0-138.59.163.255, 138.59.180.0-138.59.203.255, 138.59.208.0-138.59.243.255, 138.59.248.0/21, 138.94.4.0-138.94.11.255, 138.94.16.0-138.94.55.255, 138.94.60.0-138.94.119.255, 138.94.124.0-138.94.139.255, 138.94.148.0-138.94.215.255, 138.94.220.0-138.94.239.255, 138.97.0.0-138.97.55.255, 138.97.60.0-138.97.79.255, 138.97.84.0-138.97.139.255, 138.97.144.0-138.97.155.255, 138.97.164.0/22, 138.97.172.0/22, 138.97.180.0-138.97.199.255, 138.97.204.0-138.97.235.255, 138.97.240.0/21, 138.97.252.0/22, 138.99.8.0-138.99.35.255, 138.99.40.0/22, 138.99.48.0-138.99.99.255, 138.99.104.0-138.99.119.255, 138.99.132.0/22, 138.99.140.0/22, 138.99.152.0-138.99.171.255, 138.99.188.0-138.99.207.255, 138.99.228.0-138.99.235.255, 138.99.240.0/20, 138.117.0.0/22, 138.117.24.0-138.117.39.255, 138.117.52.0-138.117.67.255, 138.117.72.0/22, 138.117.80.0/22, 138.117.88.0/21, 138.117.100.0-138.117.107.255, 138.117.116.0-138.117.127.255, 138.117.132.0/22, 138.117.144.0/22, 138.117.152.0/22, 138.117.164.0-138.117.199.255, 138.117.204.0-138.117.223.255, 138.118.0.0/21, 138.118.12.0-138.118.35.255, 138.118.40.0/21, 138.118.52.0-138.118.79.255, 138.118.84.0-138.118.103.255, 138.118.108.0/22, 138.118.116.0-138.118.123.255, 138.118.128.0/20, 138.118.148.0-138.118.155.255, 138.118.160.0-138.118.207.255, 138.118.220.0-138.118.255.255, 138.121.0.0/22, 138.121.8.0/22, 138.121.16.0-138.121.75.255, 138.121.92.0/22, 138.121.116.0-138.121.123.255, 138.121.128.0-138.121.139.255, 138.121.144.0-138.121.155.255, 138.121.164.0/22, 138.121.172.0/22, 138.121.180.0-138.121.199.255, 138.121.204.0-138.121.227.255, 138.121.232.0/21, 138.121.244.0-138.122.3.255, 138.122.8.0-138.122.23.255, 138.122.28.0-138.122.95.255, 138.122.100.0-138.122.107.255, 138.122.112.0/20, 138.122.132.0-138.122.143.255, 138.122.148.0-138.122.155.255, 138.122.164.0-138.122.183.255, 138.122.196.0/22, 138.122.204.0-138.122.223.255, 138.122.232.0-138.122.243.255, 138.122.248.0/22, 138.185.4.0-138.185.11.255, 138.185.16.0-138.185.27.255, 138.185.32.0/19, 138.185.72.0/22, 138.185.84.0-138.185.103.255, 138.185.108.0/22, 138.185.120.0-138.185.135.255, 138.185.144.0-138.185.203.255, 138.185.212.0-138.185.223.255, 138.185.228.0-138.185.247.255, 138.185.252.0-138.186.3.255, 138.186.16.0/22, 138.186.24.0/22, 138.186.32.0-138.186.59.255, 138.186.68.0-138.186.87.255, 138.186.92.0-138.186.99.255, 138.186.104.0-138.186.119.255, 138.186.124.0-138.186.135.255, 138.186.144.0/22, 138.186.156.0/22, 138.186.164.0-138.186.175.255, 138.186.180.0-138.186.187.255, 138.186.192.0/21, 138.186.204.0/22, 138.186.220.0-138.186.243.255, 138.204.8.0/22, 138.204.16.0-138.204.39.255, 138.204.44.0-138.204.107.255, 138.204.112.0-138.204.151.255, 138.204.164.0/22, 138.204.172.0-138.204.179.255, 138.204.184.0-138.204.203.255, 138.204.208.0/21, 138.204.220.0-138.204.227.255, 138.204.232.0/22, 138.204.240.0/22, 138.219.20.0-138.219.35.255, 138.219.44.0-138.219.55.255, 138.219.64.0/21, 138.219.76.0/22, 138.219.84.0-138.219.119.255, 138.219.124.0-138.219.139.255, 138.219.144.0-138.219.155.255, 138.219.164.0-138.219.171.255, 138.219.176.0-138.219.211.255, 138.219.220.0-138.219.227.255, 138.219.236.0-138.219.247.255, 138.219.252.0/22, 138.255.0.0-138.255.51.255, 138.255.56.0/22, 138.255.64.0/20, 138.255.84.0/22, 138.255.92.0/22, 138.255.104.0-138.255.115.255, 138.255.120.0-138.255.151.255, 138.255.156.0-138.255.167.255, 138.255.172.0-138.255.247.255, 139.82.0.0/16, 143.0.0.0/19, 143.0.36.0-143.0.63.255, 143.0.68.0-143.0.75.255, 143.0.84.0-143.0.91.255, 143.0.112.0-143.0.159.255, 143.0.164.0/22, 143.0.176.0-143.0.235.255, 143.0.252.0/22, 143.54.0.0/16, 143.106.0.0-143.108.255.255, 143.137.0.0-143.137.19.255, 143.137.28.0-143.137.79.255, 143.137.84.0-143.137.95.255, 143.137.100.0-143.137.107.255, 143.137.116.0-143.137.143.255, 143.137.152.0-143.137.163.255, 143.137.172.0-143.137.191.255, 143.137.196.0-143.137.227.255, 143.137.232.0-143.137.243.255, 143.137.248.0/21, 143.202.0.0-143.202.11.255, 143.202.28.0/22, 143.202.36.0-143.202.75.255, 143.202.80.0/21, 143.202.92.0/22, 143.202.100.0-143.202.135.255, 143.202.148.0/22, 143.202.164.0-143.202.191.255, 143.202.212.0-143.202.251.255, 143.208.0.0/20, 143.208.20.0-143.208.35.255, 143.208.40.0/22, 143.208.60.0/22, 143.208.68.0-143.208.131.255, 143.208.136.0-143.208.163.255, 143.208.172.0-143.208.179.255, 143.208.184.0-143.208.255.255, 143.255.0.0-143.255.23.255, 143.255.44.0-143.255.55.255, 143.255.60.0-143.255.83.255, 143.255.88.0-143.255.103.255, 143.255.108.0-143.255.135.255, 143.255.144.0/21, 143.255.160.0/20, 143.255.180.0-143.255.247.255, 143.255.252.0/22, 146.134.0.0/16, 146.164.0.0/16, 147.65.0.0/16, 150.161.0.0-150.165.255.255, 152.84.0.0/16, 152.92.0.0/16, 152.232.0.0-152.255.255.255, 155.211.0.0/16, 157.86.0.0/16, 160.19.44.0/22, 160.19.168.0/21, 160.19.240.0/20, 160.20.20.0/22, 160.20.32.0/22, 160.20.64.0/21, 160.20.84.0-160.20.91.255, 160.20.160.0/22, 160.20.168.0/22, 160.20.176.0-160.20.187.255, 160.20.192.0/20, 160.20.242.0/23, 160.238.24.0-160.238.29.255, 160.238.104.0/21, 160.238.128.0/21, 160.238.140.0-160.238.167.255, 160.238.172.0-160.238.183.255, 160.238.188.0-160.238.203.255, 160.238.208.0/22, 160.238.216.0-160.238.243.255, 160.238.248.0/22, 161.22.56.0/21, 161.24.0.0/16, 161.79.0.0/16, 161.148.0.0/16, 164.41.0.0/16, 164.85.0.0/16, 164.163.0.0/21, 164.163.12.0-164.163.39.255, 164.163.44.0/22, 164.163.52.0/22, 164.163.60.0-164.163.71.255, 164.163.76.0/22, 164.163.84.0/22, 164.163.92.0-164.163.119.255, 164.163.136.0-164.163.159.255, 164.163.164.0-164.163.183.255, 164.163.192.0-164.163.215.255, 164.163.220.0-164.163.239.255, 164.163.242.0/23, 164.163.248.0/21, 167.249.0.0/21, 167.249.12.0-167.249.19.255, 167.249.24.0/21, 167.249.36.0/22, 167.249.48.0/22, 167.249.56.0-167.249.115.255, 167.249.120.0-167.249.191.255, 167.249.204.0-167.249.215.255, 167.249.220.0-167.249.251.255, 167.250.0.0/22, 167.250.8.0-167.250.35.255, 167.250.40.0/21, 167.250.56.0-167.250.75.255, 167.250.80.0-167.250.107.255, 167.250.124.0-167.250.131.255, 167.250.136.0-167.250.167.255, 167.250.172.0-167.250.179.255, 167.250.184.0/21, 167.250.199.0-167.250.203.255, 167.250.216.0/22, 167.250.224.0/19, 168.0.0.0-168.0.11.255, 168.0.16.0-168.0.55.255, 168.0.60.0-168.0.83.255, 168.0.88.0-168.0.183.255, 168.0.188.0-168.0.199.255, 168.0.208.0/22, 168.0.216.0/22, 168.0.224.0-168.0.243.255, 168.0.248.0/21, 168.90.0.0/21, 168.90.16.0-168.90.67.255, 168.90.76.0-168.90.83.255, 168.90.88.0/22, 168.90.100.0-168.90.107.255, 168.90.112.0/20, 168.90.132.0-168.90.155.255, 168.90.164.0-168.90.175.255, 168.90.180.0-168.90.195.255, 168.90.200.0-168.90.219.255, 168.90.224.0/21, 168.90.236.0-168.90.243.255, 168.90.248.0/22, 168.121.0.0/19, 168.121.40.0/22, 168.121.52.0/22, 168.121.64.0/20, 168.121.88.0-168.121.115.255, 168.121.120.0/21, 168.121.132.0-168.121.183.255, 168.121.188.0-168.121.207.255, 168.121.216.0/22, 168.121.224.0-168.121.235.255, 168.121.248.0/21, 168.181.0.0/21, 168.181.12.0-168.181.23.255, 168.181.28.0-168.181.43.255, 168.181.48.0/22, 168.181.56.0-168.181.71.255, 168.181.80.0-168.181.91.255, 168.181.96.0/22, 168.181.104.0-168.181.119.255, 168.181.124.0-168.181.159.255, 168.181.164.0-168.181.175.255, 168.181.180.0/22, 168.181.188.0-168.181.203.255, 168.181.212.0-168.181.227.255, 168.181.232.0-168.181.255.255, 168.194.4.0-168.194.31.255, 168.194.36.0-168.194.51.255, 168.194.56.0-168.194.71.255, 168.194.76.0-168.194.87.255, 168.194.92.0-168.194.99.255, 168.194.104.0/22, 168.194.112.0-168.194.139.255, 168.194.144.0/22, 168.194.152.0-168.194.167.255, 168.194.172.0-168.194.179.255, 168.194.184.0-168.194.195.255, 168.194.200.0/22, 168.194.208.0/21, 168.194.220.0-168.194.231.255, 168.194.236.0/22, 168.194.244.0-168.195.35.255, 168.195.40.0-168.195.51.255, 168.195.64.0-168.195.75.255, 168.195.80.0-168.195.107.255, 168.195.112.0/22, 168.195.132.0-168.195.183.255, 168.195.188.0-168.195.199.255, 168.195.208.0/21, 168.195.220.0/22, 168.195.228.0-168.195.255.255, 168.196.4.0-168.196.23.255, 168.196.28.0/22, 168.196.36.0-168.196.111.255, 168.196.116.0-168.196.123.255, 168.196.128.0-168.196.139.255, 168.196.144.0-168.196.155.255, 168.196.160.0-168.196.183.255, 168.196.188.0-168.196.199.255, 168.196.204.0-168.196.223.255, 168.196.232.0/22, 168.196.248.0/22, 168.197.0.0-168.197.39.255, 168.197.52.0-168.197.67.255, 168.197.72.0-168.197.87.255, 168.197.92.0/22, 168.197.104.0/22, 168.197.112.0/21, 168.197.128.0/22, 168.197.136.0-168.197.163.255, 168.197.168.0/22, 168.197.176.0/22, 168.197.184.0/22, 168.197.192.0/22, 168.197.204.0/22, 168.197.212.0/22, 168.197.220.0-168.197.239.255, 168.197.244.0/22, 168.197.252.0/22, 168.205.4.0/22, 168.205.12.0-168.205.63.255, 168.205.68.0/22, 168.205.76.0-168.205.91.255, 168.205.100.0-168.205.115.255, 168.205.124.0-168.205.131.255, 168.205.136.0-168.205.159.255, 168.205.164.0-168.205.183.255, 168.205.188.0-168.205.203.255, 168.205.208.0-168.205.255.255, 168.227.8.0-168.227.19.255, 168.227.28.0-168.227.35.255, 168.227.40.0-168.227.67.255, 168.227.72.0-168.227.95.255, 168.227.100.0/22, 168.227.108.0-168.227.127.255, 168.227.132.0-168.227.139.255, 168.227.148.0-168.227.203.255, 168.227.208.0-168.227.243.255, 168.227.248.0/22, 168.228.0.0-168.228.43.255, 168.228.60.0-168.228.107.255, 168.228.112.0-168.228.123.255, 168.228.128.0/22, 168.228.136.0/22, 168.228.148.0-168.228.191.255, 168.228.196.0-168.228.223.255, 168.228.228.0/22, 168.228.236.0-168.228.247.255, 168.228.252.0/22, 168.232.0.0-168.232.27.255, 168.232.40.0/21, 168.232.52.0-168.232.75.255, 168.232.80.0/21, 168.232.92.0/22, 168.232.112.0-168.232.139.255, 168.232.148.0-168.232.163.255, 168.232.172.0-168.232.247.255, 168.232.252.0/22, 170.0.0.0/22, 170.0.20.0-170.0.79.255, 170.0.88.0/22, 170.0.96.0-170.0.175.255, 170.0.184.0-170.0.227.255, 170.0.236.0-170.0.243.255, 170.0.248.0/21, 170.66.0.0/16, 170.78.0.0-170.78.39.255, 170.78.48.0/21, 170.78.60.0-170.78.71.255, 170.78.76.0-170.78.87.255, 170.78.92.0-170.78.107.255, 170.78.116.0-170.78.123.255, 170.78.128.0/21, 170.78.140.0-170.78.183.255, 170.78.186.0/23, 170.78.196.0/22, 170.78.204.0-170.78.219.255, 170.78.224.0-170.78.251.255, 170.79.0.0/20, 170.79.20.0-170.79.35.255, 170.79.44.0-170.79.87.255, 170.79.92.0-170.79.99.255, 170.79.104.0/22, 170.79.112.0-170.79.123.255, 170.79.128.0/20, 170.79.148.0-170.79.179.255, 170.79.184.0-170.79.231.255, 170.79.236.0-170.79.251.255, 170.80.0.0/21, 170.80.12.0/22, 170.80.32.0-170.80.71.255, 170.80.76.0-170.80.87.255, 170.80.100.0-170.80.107.255, 170.80.112.0/22, 170.80.120.0-170.80.135.255, 170.80.144.0-170.80.167.255, 170.80.176.0-170.80.199.255, 170.80.204.0-170.80.227.255, 170.80.232.0/21, 170.80.244.0/22, 170.80.252.0-170.81.7.255, 170.81.12.0-170.81.23.255, 170.81.36.0-170.81.51.255, 170.81.56.0-170.81.123.255, 170.81.128.0-170.81.138.255, 170.81.148.0-170.81.195.255, 170.81.200.0-170.81.211.255, 170.81.216.0-170.81.227.255, 170.81.232.0/21, 170.81.244.0-170.81.251.255, 170.82.4.0-170.82.23.255, 170.82.28.0-170.82.35.255, 170.82.42.0-170.82.95.255, 170.82.100.0-170.82.111.255, 170.82.116.0-170.82.127.255, 170.82.132.0-170.82.143.255, 170.82.148.0-170.82.155.255, 170.82.160.0-170.82.187.255, 170.82.192.0/20, 170.82.212.0/22, 170.82.220.0/22, 170.82.228.0-170.82.243.255, 170.82.246.0/24, 170.82.248.0-170.83.3.255, 170.83.12.0-170.83.31.255, 170.83.36.0-170.83.51.255, 170.83.56.0/23, 170.83.60.0-170.83.75.255, 170.83.80.0-170.83.107.255, 170.83.112.0/22, 170.83.120.0/22, 170.83.128.0-170.83.175.255, 170.83.180.0-170.83.191.255, 170.83.196.0-170.83.215.255, 170.83.224.0/21, 170.83.244.0-170.84.7.255, 170.84.12.0-170.84.43.255, 170.84.48.0-170.84.107.255, 170.84.112.0-170.84.123.255, 170.84.140.0-170.84.167.255, 170.84.176.0-170.84.187.255, 170.84.192.0-170.84.203.255, 170.84.216.0-170.84.227.255, 170.84.236.0-170.84.251.255, 170.150.0.0/21, 170.150.16.0-170.150.27.255, 170.150.36.0-170.150.43.255, 170.150.48.0/21, 170.150.68.0-170.150.87.255, 170.150.92.0-170.150.115.255, 170.150.124.0-170.150.139.255, 170.150.144.0/21, 170.150.164.0-170.150.179.255, 170.150.184.0-170.150.195.255, 170.150.200.0-170.150.255.255, 170.231.0.0-170.231.35.255, 170.231.40.0-170.231.51.255, 170.231.56.0-170.231.67.255, 170.231.72.0/22, 170.231.84.0-170.231.123.255, 170.231.128.0/21, 170.231.140.0-170.231.159.255, 170.231.164.0/22, 170.231.172.0/22, 170.231.180.0-170.231.203.255, 170.231.208.0-170.231.227.255, 170.231.232.0/22, 170.231.240.0/21, 170.231.252.0/22, 170.233.0.0-170.233.27.255, 170.233.32.0-170.233.67.255, 170.233.76.0-170.233.91.255, 170.233.96.0-170.233.115.255, 170.233.120.0/22, 170.233.128.0/20, 170.233.148.0/22, 170.233.156.0-170.233.175.255, 170.233.180.0-170.233.191.255, 170.233.196.0-170.233.207.255, 170.233.212.0/22, 170.233.220.0-170.233.231.255, 170.233.236.0-170.233.255.255, 170.238.4.0/22, 170.238.12.0/22, 170.238.28.0/22, 170.238.36.0/22, 170.238.44.0-170.238.63.255, 170.238.68.0-170.238.107.255, 170.238.112.0-170.238.123.255, 170.238.128.0-170.238.167.255, 170.238.172.0-170.238.199.255, 170.238.208.0-170.238.219.255, 170.238.224.0/23, 170.238.228.0-170.238.235.255, 170.238.248.0/22, 170.239.0.0-170.239.11.255, 170.239.16.0-170.239.27.255, 170.239.36.0-170.239.47.255, 170.239.52.0/22, 170.239.60.0/22, 170.239.68.0-170.239.83.255, 170.239.92.0-170.239.99.255, 170.239.104.0-170.239.119.255, 170.239.124.0/22, 170.239.132.0-170.239.147.255, 170.239.156.0-170.239.163.255, 170.239.176.0/22, 170.239.184.0/22, 170.239.192.0-170.239.203.255, 170.239.208.0-170.239.235.255, 170.239.240.0/22, 170.239.248.0/21, 170.244.0.0-170.244.39.255, 170.244.44.0/22, 170.244.60.0-170.244.79.255, 170.244.84.0/22, 170.244.96.0-170.244.107.255, 170.244.112.0/21, 170.244.132.0-170.244.143.255, 170.244.148.0-170.244.155.255, 170.244.160.0/21, 170.244.172.0-170.244.183.255, 170.244.192.0/20, 170.244.212.0-170.244.239.255, 170.244.244.0-170.244.255.255, 170.245.4.0-170.245.33.255, 170.245.36.0/22, 170.245.44.0/22, 170.245.52.0/22, 170.245.60.0-170.245.87.255, 170.245.92.0-170.245.157.255, 170.245.160.0/22, 170.245.172.0-170.245.183.255, 170.245.192.0/20, 170.245.212.0-170.245.231.255, 170.245.236.0/22, 170.245.244.0-170.246.19.255, 170.246.24.0-170.246.35.255, 170.246.44.0/22, 170.246.60.0/22, 170.246.68.0-170.246.75.255, 170.246.80.0/22, 170.246.96.0/22, 170.246.104.0/21, 170.246.116.0-170.246.147.255, 170.246.164.0-170.246.171.255, 170.246.184.0-170.246.219.255, 170.246.224.0-170.246.243.255, 170.246.248.0/21, 170.247.4.0-170.247.55.255, 170.247.60.0-170.247.75.255, 170.247.80.0/22, 170.247.100.0-170.247.119.255, 170.247.124.0/22, 170.247.144.0/21, 170.247.156.0/22, 170.247.180.0/22, 170.247.192.0-170.247.203.255, 170.247.208.0/22, 170.247.232.0-170.247.255.255, 170.254.4.0-170.254.15.255, 170.254.20.0-170.254.27.255, 170.254.32.0/20, 170.254.52.0-170.254.59.255, 170.254.68.0-170.254.91.255, 170.254.96.0-170.254.119.255, 170.254.124.0/22, 170.254.132.0-170.254.155.255, 170.254.160.0/22, 170.254.168.0/22, 170.254.180.0-170.254.203.255, 170.254.208.0/21, 170.254.220.0-170.254.227.255, 170.254.240.0/20, 177.0.0.0-177.11.127.255, 177.11.136.0-177.37.31.255, 177.37.48.0-177.91.247.255, 177.92.0.0-177.222.31.255, 177.222.64.0-177.223.255.255, 177.234.132.0/22, 177.234.144.0-177.234.191.255, 177.235.0.0/16, 179.0.149.0/24, 179.0.206.0/23, 179.10.0.0/15, 179.16.0.0/15, 179.34.0.0/15, 179.51.248.0/22, 179.54.0.0/15, 179.64.0.0-179.255.255.255, 181.41.160.0/19, 181.76.0.0/15, 181.191.0.0-181.191.23.255, 181.191.32.0/22, 181.191.40.0-181.191.63.255, 181.191.72.0/21, 181.191.84.0-181.191.123.255, 181.191.128.0-181.191.139.255, 181.191.144.0-181.191.155.255, 181.191.160.0/20, 181.191.180.0-181.191.185.255, 181.191.192.0-181.191.219.255, 181.191.228.0/22, 181.191.236.0-181.191.243.255, 181.213.0.0/16, 181.216.0.0/13, 181.233.148.0/22, 186.2.248.0/22, 186.65.104.0/22, 186.192.0.0-186.194.139.255, 186.194.144.0-186.232.103.255, 186.232.108.0-186.250.143.255, 186.250.148.0/22, 186.250.156.0-187.49.143.255, 187.49.192.0-187.49.247.255, 187.50.0.0-187.73.175.255, 187.73.192.0-187.95.207.255, 187.95.224.0-187.103.191.255, 187.103.208.0-187.120.159.255, 187.120.176.0-187.127.255.255, 187.180.0.0/14, 187.191.96.0/19, 187.255.0.0/16, 189.0.0.0-189.45.175.255, 189.45.192.0-189.50.207.255, 189.50.224.0-189.84.31.255, 189.84.48.0-189.85.95.255, 189.85.128.0-189.113.175.255, 189.113.192.0-189.125.255.255, 189.126.16.0-189.127.255.255, 189.201.196.0-189.201.223.255, 189.201.232.0/21, 190.2.72.0/21, 190.7.176.0/20, 190.15.32.0/19, 190.15.96.0/19, 190.103.160.0/20, 190.107.192.0/20, 190.108.96.0/19, 190.109.64.0-190.109.91.255, 190.112.204.0/22, 190.123.192.0/20, 190.124.176.0/20, 190.180.128.0/20, 190.180.148.0/22, 190.180.160.0/19, 190.196.240.0/21, 191.0.0.0/10, 191.86.0.0/15, 191.120.0.0/14, 191.128.0.0/12, 191.160.0.0-191.255.255.255, 192.12.112.0/22, 192.80.209.0/24, 192.83.207.0/24, 192.91.254.0/24, 192.100.177.0/24, 192.100.198.0/24, 192.100.206.0/24, 192.100.214.0/23, 192.100.228.0/23, 192.100.247.0-192.100.248.255, 192.100.251.0-192.100.253.255, 192.111.229.0-192.111.230.255, 192.132.35.0/24, 192.135.185.0/24, 192.140.1.0/24, 192.140.8.0/21, 192.140.24.0-192.140.55.255, 192.140.64.0-192.140.91.255, 192.140.96.0-192.140.123.255, 192.140.127.0/24, 192.141.0.0/22, 192.141.12.0-192.141.19.255, 192.141.24.0-192.141.35.255, 192.141.52.0-192.141.63.255, 192.141.68.0-192.141.91.255, 192.141.96.0-192.141.123.255, 192.141.132.0-192.141.147.255, 192.141.152.0-192.141.163.255, 192.141.172.0/22, 192.141.184.0-192.141.207.255, 192.141.216.0-192.141.227.255, 192.141.232.0-192.141.243.255, 192.141.248.0/21, 192.144.64.0-192.144.73.255, 192.144.96.0/20, 192.144.116.0-192.144.127.255, 192.145.192.0-192.145.219.255, 192.146.157.0/24, 192.146.229.0/24, 192.147.210.0/24, 192.147.218.0/24, 192.153.12.0/24, 192.153.88.0/24, 192.153.120.0/24, 192.159.116.0/23, 192.160.45.0/24, 192.160.50.0/24, 192.160.111.0/24, 192.160.128.0/24, 192.160.188.0/24, 192.188.11.0/24, 192.195.237.0/24, 192.207.194.0/23, 192.207.200.0/22, 192.207.206.0/24, 192.231.114.0/23, 192.231.175.0-192.231.176.255, 192.245.30.0/24, 198.17.120.0/23, 198.17.231.0-198.17.232.255, 198.49.132.0/23, 198.58.8.0-198.58.12.255, 198.97.38.0/24, 198.184.161.0/24, 200.0.8.0/21, 200.0.32.0-200.0.59.255, 200.0.62.0/24, 200.0.67.0/24, 200.0.70.0-200.0.72.255, 200.0.81.0/24, 200.0.85.0/24, 200.0.89.0/24, 200.0.100.0-200.0.102.255, 200.0.114.0/24, 200.0.134.0/23, 200.1.112.0/24, 200.1.125.0/24, 200.1.216.0/21, 200.2.100.0/22, 200.3.16.0/20, 200.5.9.0/24, 200.5.32.0/21, 200.6.35.0-200.6.48.255, 200.6.128.0-200.6.133.255, 200.6.136.0/21, 200.7.0.0/22, 200.7.8.0-200.7.13.255, 200.7.112.0/20, 200.9.0.0-200.9.2.255, 200.9.16.0/20, 200.9.65.0-200.9.71.255, 200.9.76.0-200.9.78.255, 200.9.84.0-200.9.93.255, 200.9.95.0/24, 200.9.102.0-200.9.107.255, 200.9.112.0/23, 200.9.123.0-200.9.127.255, 200.9.129.0-200.9.140.255, 200.9.143.0-200.9.144.255, 200.9.148.0/23, 200.9.160.0-200.9.164.255, 200.9.174.0/23, 200.9.186.0/24, 200.9.199.0-200.9.200.255, 200.9.202.0/23, 200.9.206.0/23, 200.9.214.0/24, 200.9.220.0-200.9.224.255, 200.9.249.0/24, 200.9.252.0/24, 200.10.4.0/22, 200.10.48.0-200.10.59.255, 200.10.132.0/22, 200.10.138.0/24, 200.10.146.0/24, 200.10.159.0/24, 200.10.163.0/24, 200.10.178.0/23, 200.10.183.0/24, 200.10.185.0/24, 200.10.187.0/24, 200.10.189.0/24, 200.10.192.0/23, 200.10.206.0/24, 200.10.227.0/24, 200.10.239.0/24, 200.10.245.0/24, 200.11.0.0-200.11.28.255, 200.12.0.0/20, 200.12.131.0/24, 200.12.139.0/24, 200.12.157.0/24, 200.13.8.0/21, 200.14.32.0/23, 200.14.35.0/24, 200.17.0.0-200.20.255.255, 200.23.31.0/24, 200.23.68.0/22, 200.23.116.0/24, 200.23.118.0/23, 200.23.148.0/24, 200.23.152.0/23, 200.23.180.0/22, 200.23.189.0/24, 200.23.205.0/24, 200.23.224.0/20, 200.23.254.0/23, 200.24.10.0/23, 200.24.64.0/19, 200.33.81.0/24, 200.33.83.0/24, 200.33.88.0-200.33.96.255, 200.33.108.0/24, 200.33.115.0/24, 200.33.117.0/24, 200.33.126.0-200.33.135.255, 200.33.152.0/21, 200.33.164.0/22, 200.33.174.0/23, 200.33.253.0/24, 200.34.160.0/22, 200.34.216.0/22, 200.34.224.0/19, 200.39.64.0/19, 200.49.32.0/19, 200.52.16.0/20, 200.53.8.0-200.53.31.255, 200.53.192.0/19, 200.66.112.0/20, 200.71.64.0/20, 200.71.116.0-200.71.123.255, 200.75.176.0/21, 200.77.176.0/21, 200.79.184.0/21, 200.94.240.0/21, 200.94.252.0/22, 200.95.172.0-200.95.183.255, 200.95.188.0-200.95.223.255, 200.96.0.0/13, 200.106.144.0/21, 200.128.0.0-200.187.255.255, 200.188.160.0-200.189.43.255, 200.189.48.0-200.192.104.255, 200.192.107.0-200.192.235.255, 200.192.240.0-200.193.255.255, 200.194.64.0-200.224.255.255, 200.225.32.0-200.225.99.255, 200.225.104.0-200.229.143.255, 200.229.156.0-200.229.215.255, 200.229.220.0-200.229.251.255, 200.230.0.0-200.236.63.255, 200.236.128.0-200.238.255.255, 200.239.64.0-201.70.255.255, 201.71.32.0-201.71.191.255, 201.71.208.0-201.77.95.255, 201.77.112.0-201.77.143.255, 201.77.160.0-201.95.255.255, 201.130.20.0/22, 201.130.28.0/22, 201.130.84.0-201.130.95.255, 201.131.24.0/21, 201.131.68.0/22, 201.131.80.0/21, 201.131.92.0/22, 201.131.136.0-201.131.147.255, 201.131.152.0-201.131.187.255, 201.131.208.0/21, 201.131.224.0/21, 201.131.240.0/21, 201.139.84.0-201.139.95.255, 201.139.172.0/22, 201.139.184.0/21, 201.139.216.0/21, 201.140.208.0/20, 201.140.228.0-201.140.255.255, 201.148.96.0/21, 201.148.108.0-201.148.127.255, 201.148.160.0/21, 201.148.172.0-201.148.191.255, 201.148.208.0/22, 201.148.216.0-201.148.231.255, 201.148.236.0-201.148.255.255, 201.149.96.0/19, 201.150.12.0-201.150.27.255, 201.150.48.0-201.150.59.255, 201.150.80.0/22, 201.150.88.0/21, 201.150.100.0/22, 201.150.108.0-201.150.127.255, 201.150.144.0/20, 201.157.192.0/18, 201.158.8.0/21, 201.158.20.0-201.158.31.255, 201.158.40.0/21, 201.158.56.0/21, 201.158.108.0/22, 201.159.24.0/21, 201.159.44.0/22, 201.159.52.0/22, 201.159.72.0/21, 201.159.84.0-201.159.95.255, 201.159.116.0-201.159.123.255, 201.159.144.0/20, 201.159.180.0-201.159.191.255, 201.159.248.0/21, 201.162.64.0/18, 201.175.48.0/20, 201.182.4.0-201.182.15.255, 201.182.28.0-201.182.54.255, 201.182.56.0-201.182.75.255, 201.182.88.0-201.182.107.255, 201.182.116.0-201.182.127.255, 201.182.144.0/22, 201.182.152.0-201.182.187.255, 201.182.192.0-201.182.225.255, 201.182.228.0-201.182.239.255, 201.182.244.0/22, 201.182.252.0/22, 201.219.248.0/22, 201.222.20.0-201.222.31.255, 204.225.42.0/23, 207.248.87.0/24, 216.98.208.0/20' -KRILL_PARENT_IPV6S = '2001:1280::/32, 2001:1284::/32, 2001:1288::/32, 2001:128c::/32, 2001:1290::/31, 2001:1294::/32, 2001:1298::/32, 2001:129c::/32, 2001:12a0::/32, 2001:12a4::/32, 2001:12ac::/32, 2001:12b0::/32, 2001:12b4::/32, 2001:12b8::/32, 2001:12bc::/32, 2001:12c0::/32, 2001:12c4::/32, 2001:12c8::/32, 2001:12d0::/32, 2001:12d8::/32, 2001:12e0::/32, 2001:12e8::/32, 2001:12f0::/32, 2001:12f8::/48, 2001:12f8:2::-2001:12f8:d:ffff:ffff:ffff:ffff:ffff, 2001:12fe::/31, 2801:80::/48, 2801:80:10::/48, 2801:80:30::/48, 2801:80:50::/48, 2801:80:60::/48, 2801:80:70::/48, 2801:80:80::/48, 2801:80:90::/48, 2801:80:a0::/48, 2801:80:b0::/48, 2801:80:c0::/48, 2801:80:d0::/48, 2801:80:e0::/48, 2801:80:f0::/48, 2801:80:100::/48, 2801:80:110::/48, 2801:80:120::/48, 2801:80:130::/48, 2801:80:140::/48, 2801:80:150::/48, 2801:80:160::/48, 2801:80:170::/48, 2801:80:180::/48, 2801:80:190::/48, 2801:80:1a0::/48, 2801:80:1c0::/48, 2801:80:1d0::/48, 2801:80:1e0::/48, 2801:80:1f0::/48, 2801:80:200::/48, 2801:80:210::/48, 2801:80:220::/48, 2801:80:230::/48, 2801:80:240::/48, 2801:80:250::/48, 2801:80:260::/48, 2801:80:270::/48, 2801:80:280::/48, 2801:80:290::/48, 2801:80:2a0::/48, 2801:80:2b0::/48, 2801:80:2c0::/48, 2801:80:2d0::/48, 2801:80:2e0::/48, 2801:80:2f0::/48, 2801:80:300::/48, 2801:80:320::/48, 2801:80:330::/48, 2801:80:340::/48, 2801:80:350::/48, 2801:80:360::/48, 2801:80:370::/48, 2801:80:380::/48, 2801:80:390::/48, 2801:80:3a0::/48, 2801:80:3b0::/48, 2801:80:3c0::/48, 2801:80:3d0::/48, 2801:80:3e0::/48, 2801:80:3f0::/48, 2801:80:400::/48, 2801:80:410::/48, 2801:80:420::/48, 2801:80:430::/48, 2801:80:440::/48, 2801:80:450::/48, 2801:80:460::/48, 2801:80:470::/48, 2801:80:480::/48, 2801:80:490::/48, 2801:80:4a0::/48, 2801:80:4b0::/48, 2801:80:4c0::/48, 2801:80:4d0::/48, 2801:80:4e0::/48, 2801:80:4f0::/48, 2801:80:500::/48, 2801:80:510::/48, 2801:80:520::/48, 2801:80:540::/48, 2801:80:550::/48, 2801:80:560::/48, 2801:80:570::/48, 2801:80:580::/47, 2801:80:590::/48, 2801:80:5a0::/48, 2801:80:5b0::/48, 2801:80:5c0::/48, 2801:80:5d0::/48, 2801:80:5e0::/48, 2801:80:5f0::/48, 2801:80:600::/48, 2801:80:610::/48, 2801:80:620::/48, 2801:80:630::/48, 2801:80:640::/48, 2801:80:650::/47, 2801:80:660::/48, 2801:80:670::/48, 2801:80:680::/48, 2801:80:690::/48, 2801:80:6b0::/48, 2801:80:6c0::/48, 2801:80:6d0::/48, 2801:80:6e0::/44, 2801:80:700::/48, 2801:80:710::/48, 2801:80:720::/48, 2801:80:730::/48, 2801:80:740::/48, 2801:80:750::/48, 2801:80:760::/48, 2801:80:770::/48, 2801:80:780::/48, 2801:80:790::/48, 2801:80:7a0::/48, 2801:80:7b0::/48, 2801:80:7c0::/46, 2801:80:7d0::/48, 2801:80:7e0::/48, 2801:80:7f0::/48, 2801:80:800::/48, 2801:80:810::/48, 2801:80:820::/48, 2801:80:830::/48, 2801:80:840::/48, 2801:80:850::/48, 2801:80:860::/48, 2801:80:870::/48, 2801:80:880::/48, 2801:80:890::/48, 2801:80:8a0::/48, 2801:80:8b0::/48, 2801:80:8c0::/47, 2801:80:8d0::/48, 2801:80:8f0::/48, 2801:80:900::/48, 2801:80:910::/48, 2801:80:920::/48, 2801:80:930::/48, 2801:80:940::/48, 2801:80:950::/48, 2801:80:960::/48, 2801:80:970::/48, 2801:80:980::/48, 2801:80:990::/48, 2801:80:9a0::/48, 2801:80:9b0::/48, 2801:80:9c0::/48, 2801:80:9d0::/48, 2801:80:9e0::/48, 2801:80:9f0::/48, 2801:80:a00::/48, 2801:80:a10::/48, 2801:80:a20::/48, 2801:80:a30::/48, 2801:80:a40::/48, 2801:80:a50::/48, 2801:80:a60::/47, 2801:80:a70::/48, 2801:80:a80::/44, 2801:80:ab0::/48, 2801:80:ac0::/48, 2801:80:ad0::/48, 2801:80:ae0::/48, 2801:80:af0::/48, 2801:80:b00::/48, 2801:80:b10::/48, 2801:80:b20::/48, 2801:80:b30::/48, 2801:80:b50::/48, 2801:80:b60::/48, 2801:80:b70::/48, 2801:80:b80::/48, 2801:80:b90::/48, 2801:80:ba0::/44, 2801:80:bc0::/44, 2801:80:be0::/48, 2801:80:bf0::/48, 2801:80:c00::/48, 2801:80:c10::/48, 2801:80:c20::/48, 2801:80:c30::/48, 2801:80:c40::/48, 2801:80:c50::/48, 2801:80:c60::/48, 2801:80:c70::/48, 2801:80:c80::/48, 2801:80:c90::/48, 2801:80:ca0::/48, 2801:80:cb0::/48, 2801:80:cc0::/48, 2801:80:cd0::/48, 2801:80:ce0::/48, 2801:80:cf0::/48, 2801:80:d00::/48, 2801:80:d10::/48, 2801:80:d20::/44, 2801:80:d40::/48, 2801:80:d50::/48, 2801:80:d60::/44, 2801:80:d80::/48, 2801:80:d90::/48, 2801:80:da0::/44, 2801:80:dc0::/44, 2801:80:de0::/48, 2801:80:df0::/48, 2801:80:e00::/48, 2801:80:e10::/48, 2801:80:e20::/48, 2801:80:e30::/48, 2801:80:e40::/48, 2801:80:e50::/48, 2801:80:e60::/48, 2801:80:e80::/48, 2801:80:e90::/48, 2801:80:ea0::/48, 2801:80:eb0::/48, 2801:80:ec0::/48, 2801:80:ed0::/48, 2801:80:ee0::/48, 2801:80:ef0::/48, 2801:80:f00::/48, 2801:80:f10::/48, 2801:80:f20::/48, 2801:80:f30::/48, 2801:80:f60::/48, 2801:80:f70::/48, 2801:80:f80::/44, 2801:80:fa0::/44, 2801:80:fc0::/48, 2801:80:fd0::/48, 2801:80:fe0::/48, 2801:80:ff0::/48, 2801:80:1000::/40, 2801:80:1200::/48, 2801:80:1210::/48, 2801:80:1220::/48, 2801:80:1230::/48, 2801:80:1240::/48, 2801:80:1250::/48, 2801:80:1260::/44, 2801:80:1280::/48, 2801:80:1290::/48, 2801:80:12a0::/48, 2801:80:12b0::/48, 2801:80:12c0::/48, 2801:80:12d0::/48, 2801:80:12e0::/48, 2801:80:12f0::/48, 2801:80:1300::/48, 2801:80:1310::/48, 2801:80:1320::/48, 2801:80:1330::/48, 2801:80:1340::/48, 2801:80:1350::/48, 2801:80:1360::/48, 2801:80:1370::/48, 2801:80:1380::/48, 2801:80:1390::/48, 2801:80:13a0::/48, 2801:80:13b0::/48, 2801:80:13c0::/48, 2801:80:13d0::/48, 2801:80:13e0::/48, 2801:80:13f0::/48, 2801:80:1400::/40, 2801:80:1600::/48, 2801:80:1610::/48, 2801:80:1620::/44, 2801:80:1640::/48, 2801:80:1650::/48, 2801:80:1660::/48, 2801:80:1670::/48, 2801:80:1680::/48, 2801:80:1690::/48, 2801:80:16a0::/48, 2801:80:16b0::/48, 2801:80:16c0::/48, 2801:80:16d0::/48, 2801:80:16e0::/48, 2801:80:16f0::/48, 2801:80:1700::/40, 2801:80:1900::/48, 2801:80:1910::/48, 2801:80:1920::/48, 2801:80:1930::/48, 2801:80:1940::/47, 2801:80:1950::/48, 2801:80:1960::/48, 2801:80:1970::/48, 2801:80:1980::/47, 2801:80:1990::/48, 2801:80:19a0::/48, 2801:80:19b0::/48, 2801:80:19c0::/48, 2801:80:19d0::/48, 2801:80:19e0::/48, 2801:80:19f0::/48, 2801:80:1a00::/48, 2801:80:1a10::/48, 2801:80:1a20::/48, 2801:80:1a30::/48, 2801:80:1a40::/48, 2801:80:1a50::/48, 2801:80:1a60::/48, 2801:80:1a70::/48, 2801:80:1a80::/48, 2801:80:1a90::/48, 2801:80:1aa0::/48, 2801:80:1ab0::/48, 2801:80:1ac0::/48, 2801:80:1ad0::/47, 2801:80:1ae0::/48, 2801:80:1af0::/48, 2801:80:1b00::/48, 2801:80:1b10::/48, 2801:80:1b20::/48, 2801:80:1b30::/48, 2801:80:1b40::/48, 2801:80:1b50::/48, 2801:80:1b60::/48, 2801:80:1b70::/48, 2801:80:1b80::/48, 2801:80:1b90::/48, 2801:80:1ba0::/48, 2801:80:1bb0::/48, 2801:80:1bc0::/48, 2801:80:1bd0::/48, 2801:80:1be0::/48, 2801:80:1bf0::/48, 2801:80:1c00::/48, 2801:80:1c10::/48, 2801:80:1c20::/48, 2801:80:1c30::/48, 2801:80:1c40::/44, 2801:80:1c60::/48, 2801:80:1c70::/48, 2801:80:1c80::/48, 2801:80:1c90::/48, 2801:80:1ca0::/48, 2801:80:1cb0::/48, 2801:80:1cc0::/48, 2801:80:1cd0::/48, 2801:80:1ce0::/44, 2801:80:1d00::/47, 2801:80:1d10::/48, 2801:80:1d20::/47, 2801:80:1d30::/48, 2801:80:1d40::/48, 2801:80:1d50::/48, 2801:80:1d60::/48, 2801:80:1d70::/48, 2801:80:1d80::/48, 2801:80:1d90::/48, 2801:80:1da0::/48, 2801:80:1db0::/46, 2801:80:1dc0::/48, 2801:80:1dd0::/46, 2801:80:1de0::/48, 2801:80:1df0::/48, 2801:80:1e00::/40, 2801:80:2000::/40, 2801:80:2200::/48, 2801:80:2210::/48, 2801:80:2220::/48, 2801:80:2230::/48, 2801:80:2240::/48, 2801:80:2250::/47, 2801:80:2260::/48, 2801:80:2270::/48, 2801:80:2280::/47, 2801:80:2290::/48, 2801:80:22a0::/48, 2801:80:22b0::/48, 2801:80:22c0::/48, 2801:80:22d0::/48, 2801:80:22e0::/48, 2801:80:22f0::/48, 2801:80:2300::/48, 2801:80:2310::/48, 2801:80:2320::/48, 2801:80:2330::/48, 2801:80:2340::/48, 2801:80:2350::/48, 2801:80:2360::/47, 2801:80:2370::/48, 2801:80:2380::/48, 2801:80:2390::/48, 2801:80:23a0::/48, 2801:80:23b0::/48, 2801:80:23c0::/48, 2801:80:23d0::/48, 2801:80:23e0::/48, 2801:80:23f0::/48, 2801:80:2400::/48, 2801:80:2410::/48, 2801:80:2420::/48, 2801:80:2430::/48, 2801:80:2440::/46, 2801:80:2450::/48, 2801:80:2460::/44, 2801:80:2480::/48, 2801:80:2500::/48, 2801:80:2510::/48, 2801:80:2520::/48, 2801:80:2530::/48, 2801:80:2540::/48, 2801:80:2550::/48, 2801:80:2560::/48, 2801:80:2570::/48, 2801:80:2580::/45, 2801:80:2590::/46, 2801:80:25a0::/48, 2801:80:25b0::/48, 2801:80:25c0::/48, 2801:80:25d0::/48, 2801:80:25e0::/48, 2801:80:25f0::/48, 2801:80:2600::/40, 2801:80:2800::/40, 2801:80:2c00::/40, 2801:80:2e00::/40, 2801:80:3000::/40, 2801:80:3200::/40, 2801:80:3400::/48, 2801:80:3410::/48, 2801:80:3420::/48, 2801:80:3430::/48, 2801:80:3440::/48, 2801:80:3450::/48, 2801:80:3460::/44, 2801:80:3480::/48, 2801:80:3490::/48, 2801:80:34a0::/48, 2801:80:34b0::/48, 2801:80:34d0::/48, 2801:80:34e0::/44, 2801:80:3500::/47, 2801:80:3510::/48, 2801:80:3520::/48, 2801:80:3530::/48, 2801:80:3540::/48, 2801:80:3550::/48, 2801:80:3560::/44, 2801:80:3580::/48, 2801:80:3590::/48, 2801:80:35a0::/48, 2801:80:35b0::/47, 2801:80:35c0::/47, 2801:80:35d0::/48, 2801:80:35e0::/48, 2801:80:35f0::/48, 2801:80:3600::/42, 2801:80:3680::/48, 2801:80:3690::/48, 2801:80:36a0::/48, 2801:80:36b0::/48, 2801:80:36c0::/48, 2801:80:36d0::/48, 2801:80:36e0::/48, 2801:80:36f0::/48, 2801:80:3700::/48, 2801:80:3710::/47, 2801:80:3720::/48, 2801:80:3730::/48, 2801:80:3740::/47, 2801:80:3750::/48, 2801:80:3760::/48, 2801:80:3770::/46, 2801:80:3780::/48, 2801:80:3790::/48, 2801:80:37a0::/48, 2801:80:37b0::/48, 2801:80:37c0::/48, 2801:80:37d0::/48, 2801:80:37e0::/48, 2801:80:37f0::/48, 2801:80:3800::/48, 2801:80:3810::/48, 2801:80:3820::/48, 2801:80:3830::/46, 2801:82::/32, 2801:84::/32, 2801:86::/32, 2801:88::/32, 2801:8a::/32, 2801:8c::/32, 2801:8e::/32, 2801:90::/32, 2801:92::/32, 2801:94::/32, 2801:96::/32, 2801:98::/32, 2801:9a::/32, 2801:9c::/32, 2801:9e::/32, 2801:a0::/32, 2801:a2::/32, 2801:a4::/32, 2801:a6::/32, 2801:a8::/32, 2801:aa::/32, 2801:ac::/32, 2801:ae::/32, 2801:b0::/32, 2801:b2::/32, 2801:b4::/32, 2801:b6::/32, 2801:b8::/32, 2801:ba::/32, 2801:bc::/32, 2801:be::/32, 2804::/32, 2804:4::/32, 2804:8::-2804:c:ffff:ffff:ffff:ffff:ffff:ffff, 2804:10::/32, 2804:14::/32, 2804:18::/32, 2804:1c::/32, 2804:20::/32, 2804:24::/32, 2804:28::/32, 2804:2c::/32, 2804:30::/32, 2804:34::/32, 2804:38::/32, 2804:3c::/32, 2804:40::/32, 2804:44::/32, 2804:48::/32, 2804:4c::/32, 2804:50::/32, 2804:54::/32, 2804:58::/32, 2804:5c::/32, 2804:60::/32, 2804:64::/32, 2804:68::/32, 2804:6c::/32, 2804:74::/32, 2804:78::/32, 2804:7c::/32, 2804:80::/32, 2804:84::/32, 2804:88::/32, 2804:8c::/32, 2804:90::/32, 2804:94::/32, 2804:98::/32, 2804:9c::/32, 2804:a0::/32, 2804:a4::/32, 2804:a8::/32, 2804:ac::/32, 2804:b0::/32, 2804:b4::/32, 2804:b8::/32, 2804:c0::/32, 2804:c8::/32, 2804:cc::/32, 2804:d0::/32, 2804:d4::/32, 2804:d8::/32, 2804:dc::/32, 2804:e0::/32, 2804:e4::/32, 2804:e8::/32, 2804:ec::/32, 2804:f4::/32, 2804:f8::/32, 2804:fc::/32, 2804:100::/32, 2804:104::/32, 2804:108::/32, 2804:10c::/32, 2804:110::/32, 2804:114::/32, 2804:118::/32, 2804:11c::/32, 2804:120::/32, 2804:124::/32, 2804:128::/32, 2804:12c::/32, 2804:130::/32, 2804:134::/32, 2804:138::/32, 2804:13c::/32, 2804:140::/32, 2804:144::/32, 2804:148::/32, 2804:14c::/31, 2804:150::-2804:154:ffff:ffff:ffff:ffff:ffff:ffff, 2804:158::/32, 2804:15c::/32, 2804:160::/32, 2804:164::/32, 2804:168::/32, 2804:16c::/32, 2804:170::/32, 2804:174::/32, 2804:178::/32, 2804:17c::/32, 2804:180::/32, 2804:184::/32, 2804:188::/32, 2804:18c::/32, 2804:190::/32, 2804:194::/32, 2804:198::/32, 2804:19c::/32, 2804:1a0::/32, 2804:1a4::/32, 2804:1a8::/32, 2804:1ac::/32, 2804:1b0::-2804:1b8:ffff:ffff:ffff:ffff:ffff:ffff, 2804:1bc::/32, 2804:1c0::/32, 2804:1c4::/32, 2804:1c8::/32, 2804:1cc::/32, 2804:1d0::/32, 2804:1d4::/32, 2804:1dc::/32, 2804:1e0::/32, 2804:1e4::/32, 2804:1e8::/32, 2804:1ec::/32, 2804:1f0::/32, 2804:1f4::/32, 2804:1f8::/32, 2804:200::/32, 2804:204::/32, 2804:208::/32, 2804:20c::/32, 2804:210::/32, 2804:214::/32, 2804:218::/32, 2804:220::/32, 2804:224::/32, 2804:22c::/32, 2804:230::/32, 2804:234::/32, 2804:238::/32, 2804:23c::/32, 2804:240::/32, 2804:244::/32, 2804:248::/32, 2804:24c::/32, 2804:250::/32, 2804:254::/32, 2804:258::/32, 2804:25c::/32, 2804:260::/32, 2804:268::/32, 2804:26c::/32, 2804:270::/32, 2804:274::/32, 2804:27c::/32, 2804:280::/32, 2804:284::/32, 2804:288::/32, 2804:28c::/32, 2804:290::/32, 2804:294::/32, 2804:298::/32, 2804:29c::/32, 2804:2a0::/32, 2804:2a4::/32, 2804:2a8::/32, 2804:2ac::/32, 2804:2b0::/32, 2804:2b4::/32, 2804:2b8::/32, 2804:2bc::/32, 2804:2c0::/32, 2804:2c4::/32, 2804:2c8::/32, 2804:2cc::/32, 2804:2d0::/32, 2804:2d4::/32, 2804:2d8::/32, 2804:2dc::/32, 2804:2e0::/32, 2804:2e4::/32, 2804:2e8::/32, 2804:2ec::/32, 2804:2f0::/32, 2804:2f4::/32, 2804:2f8::/32, 2804:2fc::/32, 2804:300::/30, 2804:308::/32, 2804:30c::/32, 2804:310::/32, 2804:314::/32, 2804:318::/32, 2804:31c::/32, 2804:320::/32, 2804:324::/32, 2804:328::/32, 2804:32c::/32, 2804:330::/32, 2804:334::/32, 2804:338::/32, 2804:33c::/32, 2804:340::/32, 2804:344::/32, 2804:348::/32, 2804:350::/32, 2804:354::/32, 2804:358::/32, 2804:35c::/32, 2804:360::/32, 2804:364::/32, 2804:368::/32, 2804:36c::/32, 2804:370::/32, 2804:374::/32, 2804:378::/32, 2804:37c::/32, 2804:380::/32, 2804:384::/32, 2804:388::/30, 2804:390::/32, 2804:394::/32, 2804:398::/32, 2804:39c::/32, 2804:3a0::/32, 2804:3a4::/32, 2804:3a8::/32, 2804:3ac::/32, 2804:3b0::/32, 2804:3b4::/32, 2804:3b8::/32, 2804:3bc::/32, 2804:3c0::/32, 2804:3c4::/32, 2804:3c8::/32, 2804:3cc::/32, 2804:3d0::/32, 2804:3d4::/32, 2804:3d8::/32, 2804:3dc::/32, 2804:3e0::/32, 2804:3e4::/32, 2804:3e8::/32, 2804:3ec::/32, 2804:3f0::/32, 2804:3f4::/32, 2804:3f8::/32, 2804:3fc::/32, 2804:400::/32, 2804:404::/32, 2804:40c::/32, 2804:410::/32, 2804:414::/32, 2804:418::/32, 2804:41c::/32, 2804:420::/32, 2804:424::/32, 2804:428::/32, 2804:430::/31, 2804:438::/32, 2804:43c::/32, 2804:440::/32, 2804:444::/32, 2804:448::/32, 2804:44c::/32, 2804:450::/32, 2804:454::/32, 2804:458::/32, 2804:45c::/32, 2804:460::/32, 2804:464::/32, 2804:468::/32, 2804:46c::/32, 2804:470::/32, 2804:474::/32, 2804:478::/32, 2804:47c::/32, 2804:480::/32, 2804:484::/32, 2804:488::/32, 2804:48c::/32, 2804:490::/32, 2804:494::/32, 2804:498::/32, 2804:49c::/32, 2804:4a0::/32, 2804:4a4::/32, 2804:4a8::/32, 2804:4ac::/32, 2804:4b0::/32, 2804:4b4::/32, 2804:4b8::/32, 2804:4bc::/32, 2804:4c0::/32, 2804:4c4::/32, 2804:4c8::/32, 2804:4cc::/32, 2804:4d0::/32, 2804:4d4::/32, 2804:4d8::/32, 2804:4dc::/32, 2804:4e0::/32, 2804:4e4::/32, 2804:4e8::/32, 2804:4ec::/32, 2804:4f0::/32, 2804:4f4::/32, 2804:4f8::/32, 2804:4fc::/32, 2804:500::/32, 2804:504::/32, 2804:508::/32, 2804:50c::/32, 2804:510::/32, 2804:514::/32, 2804:518::/32, 2804:51c::/32, 2804:520::/32, 2804:528::/32, 2804:52c::/32, 2804:530::/32, 2804:534::/32, 2804:538::/32, 2804:53c::/32, 2804:540::/32, 2804:544::/32, 2804:548::/32, 2804:54c::/32, 2804:550::/32, 2804:554::/32, 2804:558::/32, 2804:55c::/32, 2804:560::/32, 2804:564::/32, 2804:568::/32, 2804:56c::/32, 2804:570::/32, 2804:574::/32, 2804:578::/32, 2804:57c::/32, 2804:580::/32, 2804:584::/32, 2804:588::/32, 2804:58c::/32, 2804:590::/32, 2804:594::/32, 2804:598::/32, 2804:59c::/32, 2804:5a0::/32, 2804:5a4::/32, 2804:5a8::/32, 2804:5ac::/32, 2804:5b0::/32, 2804:5b4::/32, 2804:5b8::/32, 2804:5bc::/32, 2804:5c0::/32, 2804:5c4::/32, 2804:5c8::/32, 2804:5cc::/32, 2804:5d0::/32, 2804:5d4::/32, 2804:5d8::/32, 2804:5dc::/32, 2804:5e0::/32, 2804:5e4::/32, 2804:5e8::/32, 2804:5ec::/32, 2804:5f0::/32, 2804:5f4::/32, 2804:5f8::/32, 2804:5fc::/32, 2804:600::/32, 2804:604::/32, 2804:608::/32, 2804:60c::/32, 2804:610::/32, 2804:614::/32, 2804:618::/32, 2804:61c::/32, 2804:620::/32, 2804:624::/32, 2804:628::/32, 2804:62c::/32, 2804:630::/32, 2804:634::/32, 2804:638::/32, 2804:63c::/32, 2804:640::/32, 2804:644::/32, 2804:648::/32, 2804:64c::/32, 2804:650::/32, 2804:654::/32, 2804:658::/32, 2804:65c::/32, 2804:660::/32, 2804:664::/32, 2804:668::/32, 2804:66c::/32, 2804:670::/32, 2804:674::/32, 2804:678::/32, 2804:680::/32, 2804:684::/32, 2804:688::/32, 2804:68c::/32, 2804:690::/32, 2804:694::/32, 2804:698::/32, 2804:6a0::/32, 2804:6a4::/32, 2804:6a8::/32, 2804:6ac::/32, 2804:6b0::/32, 2804:6b4::/32, 2804:6b8::/32, 2804:6bc::/32, 2804:6c0::/32, 2804:6c4::/32, 2804:6c8::/32, 2804:6cc::/32, 2804:6d0::/32, 2804:6d4::/32, 2804:6d8::/32, 2804:6dc::/32, 2804:6e0::/32, 2804:6e4::/32, 2804:6e8::/32, 2804:6ec::/32, 2804:6f0::/32, 2804:6f4::/32, 2804:6f8::/32, 2804:6fc::/32, 2804:700::/32, 2804:704::/32, 2804:708::/32, 2804:70c::/32, 2804:710::/32, 2804:718::/32, 2804:71c::/32, 2804:720::/32, 2804:724::/32, 2804:728::/32, 2804:72c::/32, 2804:730::/32, 2804:734::/32, 2804:738::/32, 2804:73c::/32, 2804:744::/32, 2804:748::/32, 2804:74c::/32, 2804:750::/32, 2804:754::/32, 2804:758::/32, 2804:75c::/32, 2804:760::/32, 2804:764::/32, 2804:768::/32, 2804:76c::/32, 2804:770::/32, 2804:774::/32, 2804:778::/32, 2804:77c::/32, 2804:780::/32, 2804:784::/32, 2804:788::/32, 2804:78c::/32, 2804:790::/32, 2804:794::/32, 2804:798::/32, 2804:79c::/32, 2804:7a0::/32, 2804:7a4::/32, 2804:7a8::/32, 2804:7ac::/32, 2804:7b0::/32, 2804:7b4::/32, 2804:7b8::/32, 2804:7bc::/32, 2804:7c0::/32, 2804:7c4::/32, 2804:7c8::/32, 2804:7cc::/32, 2804:7d0::/32, 2804:7d4::/32, 2804:7dc::/32, 2804:7e0::/32, 2804:7e4::/32, 2804:7e8::/32, 2804:7ec::/32, 2804:7f0::/29, 2804:800::/32, 2804:804::/32, 2804:808::/32, 2804:80c::/32, 2804:810::/32, 2804:814::/32, 2804:818::/32, 2804:81c::/32, 2804:820::/32, 2804:824::/32, 2804:828::/32, 2804:82c::/32, 2804:830::/32, 2804:834::/32, 2804:838::/32, 2804:83c::/32, 2804:840::/32, 2804:844::/32, 2804:848::/32, 2804:84c::/32, 2804:850::/32, 2804:854::/32, 2804:858::/32, 2804:85c::/32, 2804:860::/32, 2804:868::/32, 2804:86c::/32, 2804:870::/32, 2804:874::/32, 2804:878::/32, 2804:87c::/32, 2804:880::/32, 2804:884::/32, 2804:888::/32, 2804:88c::/32, 2804:890::/32, 2804:894::/32, 2804:898::/32, 2804:89c::/32, 2804:8a0::/32, 2804:8a4::/32, 2804:8a8::/32, 2804:8ac::/32, 2804:8b0::/32, 2804:8b4::/32, 2804:8bc::/32, 2804:8c0::/32, 2804:8c4::/32, 2804:8c8::/32, 2804:8cc::/32, 2804:8d0::/32, 2804:8d4::/32, 2804:8d8::/32, 2804:8dc::/32, 2804:8e0::/32, 2804:8e4::/32, 2804:8e8::/32, 2804:8ec::/32, 2804:8f0::/32, 2804:8f4::/32, 2804:8f8::/32, 2804:8fc::/32, 2804:904::/32, 2804:908::/32, 2804:90c::/32, 2804:910::/32, 2804:914::/32, 2804:918::/32, 2804:91c::/32, 2804:920::/32, 2804:924::/32, 2804:928::/32, 2804:92c::/32, 2804:930::/32, 2804:934::/32, 2804:938::/32, 2804:93c::/32, 2804:940::/32, 2804:944::/32, 2804:948::/32, 2804:94c::/32, 2804:950::/32, 2804:954::/32, 2804:958::/32, 2804:95c::/32, 2804:960::/32, 2804:964::/32, 2804:968::/32, 2804:96c::/32, 2804:970::/32, 2804:974::/32, 2804:978::/32, 2804:97c::/32, 2804:980::/32, 2804:984::/32, 2804:988::/32, 2804:98c::/32, 2804:990::/32, 2804:994::/32, 2804:998::/32, 2804:99c::/32, 2804:9a0::/32, 2804:9a4::/32, 2804:9a8::/32, 2804:9ac::/32, 2804:9b0::/32, 2804:9b4::/32, 2804:9b8::/32, 2804:9bc::/32, 2804:9c0::/32, 2804:9c4::/32, 2804:9c8::/32, 2804:9cc::/32, 2804:9d0::/32, 2804:9d4::/32, 2804:9d8::/32, 2804:9dc::/32, 2804:9e0::/32, 2804:9e8::/32, 2804:9ec::/32, 2804:9f0::/32, 2804:9f4::/32, 2804:9f8::/32, 2804:9fc::/32, 2804:a00::/32, 2804:a04::/32, 2804:a08::/32, 2804:a0c::/32, 2804:a14::/32, 2804:a18::/32, 2804:a1c::/32, 2804:a20::/32, 2804:a24::/32, 2804:a28::/32, 2804:a2c::/32, 2804:a30::/32, 2804:a34::/32, 2804:a38::/32, 2804:a3c::/32, 2804:a40::/32, 2804:a44::/32, 2804:a48::/32, 2804:a4c::/32, 2804:a50::/32, 2804:a54::/32, 2804:a58::/32, 2804:a5c::/32, 2804:a60::/32, 2804:a64::/32, 2804:a68::/32, 2804:a6c::/32, 2804:a70::/32, 2804:a74::/32, 2804:a78::/32, 2804:a7c::/32, 2804:a80::/32, 2804:a84::/32, 2804:a88::/32, 2804:a8c::/32, 2804:a90::/32, 2804:a94::/32, 2804:a98::/32, 2804:a9c::/32, 2804:aa0::/32, 2804:aa4::/32, 2804:aa8::/32, 2804:aac::/32, 2804:ab0::/32, 2804:ab4::/32, 2804:ab8::/32, 2804:abc::/32, 2804:ac0::/32, 2804:ac4::/32, 2804:ac8::/32, 2804:acc::/32, 2804:ad0::/32, 2804:ad4::/32, 2804:ad8::/32, 2804:adc::/32, 2804:ae0::/32, 2804:ae4::/32, 2804:ae8::/32, 2804:aec::/32, 2804:af0::/32, 2804:af4::/32, 2804:af8::/32, 2804:afc::/32, 2804:b00::/32, 2804:b04::/32, 2804:b08::/32, 2804:b0c::/32, 2804:b10::/32, 2804:b14::/32, 2804:b18::/32, 2804:b1c::/32, 2804:b24::/32, 2804:b28::/32, 2804:b2c::/32, 2804:b30::/32, 2804:b34::/32, 2804:b38::/32, 2804:b3c::/32, 2804:b40::/32, 2804:b44::/32, 2804:b48::/32, 2804:b4c::/32, 2804:b50::/32, 2804:b54::/32, 2804:b58::/32, 2804:b5c::/32, 2804:b60::/32, 2804:b64::/32, 2804:b68::/32, 2804:b6c::/32, 2804:b70::/32, 2804:b74::/32, 2804:b78::/32, 2804:b7c::/32, 2804:b80::/32, 2804:b84::/32, 2804:b88::/32, 2804:b8c::/32, 2804:b90::/32, 2804:b94::/32, 2804:b98::/32, 2804:b9c::/32, 2804:ba0::/32, 2804:ba4::/31, 2804:ba8::/32, 2804:bac::/32, 2804:bb0::/32, 2804:bb4::/32, 2804:bb8::/32, 2804:bbc::/32, 2804:bc0::/32, 2804:bc4::/32, 2804:bc8::/32, 2804:bcc::/32, 2804:bd0::/32, 2804:bd4::/32, 2804:bd8::/32, 2804:bdc::/32, 2804:be0::/32, 2804:be4::/32, 2804:be8::/32, 2804:bec::/32, 2804:bf0::/32, 2804:bf4::/32, 2804:bf8::/32, 2804:bfc::/32, 2804:c00::/32, 2804:c04::/32, 2804:c08::/32, 2804:c0c::/32, 2804:c10::/32, 2804:c14::/32, 2804:c18::/32, 2804:c1c::/32, 2804:c20::/32, 2804:c28::/32, 2804:c2c::/32, 2804:c30::/32, 2804:c34::/32, 2804:c38::/32, 2804:c3c::/32, 2804:c40::/32, 2804:c44::/32, 2804:c48::/32, 2804:c4c::/32, 2804:c50::/32, 2804:c54::/32, 2804:c58::/32, 2804:c5c::/32, 2804:c60::/32, 2804:c64::/32, 2804:c68::/32, 2804:c6c::/32, 2804:c70::/32, 2804:c74::/32, 2804:c78::/32, 2804:c7c::/32, 2804:c80::/32, 2804:c84::/32, 2804:c88::/32, 2804:c90::/32, 2804:c94::/32, 2804:c98::/32, 2804:c9c::/32, 2804:ca0::/32, 2804:ca4::/32, 2804:ca8::/32, 2804:cac::/32, 2804:cb0::/32, 2804:cb4::/32, 2804:cb8::/32, 2804:cbc::/32, 2804:cc0::/32, 2804:cc4::/32, 2804:cc8::/32, 2804:ccc::/32, 2804:cd0::/32, 2804:cd4::/32, 2804:cd8::/32, 2804:cdc::/32, 2804:ce0::/32, 2804:ce4::/32, 2804:ce8::/32, 2804:cec::/32, 2804:cf0::/32, 2804:cf4::/32, 2804:cf8::/32, 2804:cfc::/32, 2804:d00::/32, 2804:d04::/32, 2804:d08::/32, 2804:d0c::/32, 2804:d10::/32, 2804:d14::/32, 2804:d18::/32, 2804:d1c::/32, 2804:d20::/32, 2804:d24::/32, 2804:d28::/32, 2804:d2c::/32, 2804:d30::/32, 2804:d34::/32, 2804:d38::/32, 2804:d3c::/32, 2804:d40::-2804:d60:ffff:ffff:ffff:ffff:ffff:ffff, 2804:d64::/32, 2804:d68::/32, 2804:d6c::/32, 2804:d70::/32, 2804:d74::/32, 2804:d78::/32, 2804:d7c::/32, 2804:d80::/32, 2804:d84::/32, 2804:d88::/32, 2804:d8c::/32, 2804:d90::/32, 2804:d94::/32, 2804:d98::/32, 2804:d9c::/32, 2804:da0::/32, 2804:da4::/32, 2804:da8::/32, 2804:dac::/32, 2804:db0::/32, 2804:db4::/32, 2804:db8::/32, 2804:dbc::/32, 2804:dc0::/32, 2804:dc4::/32, 2804:dc8::/32, 2804:dcc::/32, 2804:dd0::/32, 2804:dd4::/32, 2804:dd8::/32, 2804:ddc::/32, 2804:de0::/32, 2804:de8::/32, 2804:dec::/32, 2804:df0::/32, 2804:df4::/32, 2804:df8::/32, 2804:dfc::/32, 2804:e00::/32, 2804:e04::/32, 2804:e08::/32, 2804:e0c::/32, 2804:e10::/32, 2804:e14::/32, 2804:e18::/32, 2804:e1c::/32, 2804:e20::/32, 2804:e24::/32, 2804:e28::/32, 2804:e2c::/32, 2804:e30::/32, 2804:e34::/32, 2804:e38::/32, 2804:e3c::/32, 2804:e40::/32, 2804:e44::/32, 2804:e48::/32, 2804:e4c::/32, 2804:e50::/32, 2804:e54::/32, 2804:e58::/32, 2804:e5c::/32, 2804:e60::/32, 2804:e64::/32, 2804:e68::/32, 2804:e6c::/32, 2804:e70::/32, 2804:e74::/32, 2804:e78::/32, 2804:e7c::/32, 2804:e80::/32, 2804:e84::/32, 2804:e88::/32, 2804:e8c::/32, 2804:e90::/32, 2804:e94::/32, 2804:e98::/32, 2804:e9c::/32, 2804:ea0::/32, 2804:ea4::/32, 2804:ea8::/32, 2804:eac::/32, 2804:eb0::/32, 2804:eb4::/32, 2804:eb8::/32, 2804:ebc::/32, 2804:ec0::/32, 2804:ec4::/32, 2804:ec8::/32, 2804:ecc::/32, 2804:ed0::/32, 2804:ed4::/32, 2804:ed8::/32, 2804:edc::/32, 2804:ee0::/32, 2804:ee4::/32, 2804:ee8::/32, 2804:eec::/32, 2804:ef0::/32, 2804:ef4::/32, 2804:ef8::/32, 2804:efc::/32, 2804:f00::/32, 2804:f04::/32, 2804:f08::/32, 2804:f0c::/32, 2804:f10::/32, 2804:f14::/32, 2804:f18::/32, 2804:f1c::/32, 2804:f20::/32, 2804:f24::/32, 2804:f28::/32, 2804:f2c::/32, 2804:f30::/32, 2804:f34::/32, 2804:f38::/32, 2804:f3c::/32, 2804:f40::/32, 2804:f44::/32, 2804:f48::/32, 2804:f4c::/32, 2804:f50::/32, 2804:f54::/32, 2804:f58::/32, 2804:f5c::/32, 2804:f60::/32, 2804:f64::/32, 2804:f68::/32, 2804:f6c::/32, 2804:f70::/32, 2804:f74::/32, 2804:f78::/32, 2804:f7c::/32, 2804:f80::/32, 2804:f84::/32, 2804:f88::/32, 2804:f8c::/32, 2804:f90::/32, 2804:f94::/32, 2804:f98::/32, 2804:f9c::/32, 2804:fa0::/32, 2804:fa4::/32, 2804:fa8::/32, 2804:fac::/32, 2804:fb0::/32, 2804:fb4::/32, 2804:fb8::/32, 2804:fbc::/32, 2804:fc0::/32, 2804:fc4::/32, 2804:fc8::/32, 2804:fcc::/32, 2804:fd0::/32, 2804:fd4::/32, 2804:fd8::/32, 2804:fdc::/32, 2804:fe0::/32, 2804:fe4::/32, 2804:fe8::/32, 2804:fec::/32, 2804:ff0::/32, 2804:ff4::/32, 2804:ff8::/32, 2804:ffc::/32, 2804:1000::/32, 2804:1004::/32, 2804:1008::/32, 2804:100c::/32, 2804:1010::/32, 2804:1014::/32, 2804:1018::/32, 2804:101c::/32, 2804:1020::/32, 2804:1024::/32, 2804:1028::/32, 2804:102c::/32, 2804:1030::/32, 2804:1034::/32, 2804:1038::/32, 2804:103c::/32, 2804:1040::/32, 2804:1044::/32, 2804:1048::/32, 2804:104c::/32, 2804:1050::/32, 2804:1054::/32, 2804:1058::/32, 2804:105c::/32, 2804:1060::/32, 2804:1064::/32, 2804:1068::/32, 2804:106c::/32, 2804:1070::/32, 2804:1074::/32, 2804:1078::/32, 2804:107c::/32, 2804:1080::/32, 2804:1084::/32, 2804:1088::/32, 2804:108c::/32, 2804:1090::/32, 2804:1094::/32, 2804:1098::/32, 2804:109c::/32, 2804:10a0::/32, 2804:10a4::/32, 2804:10a8::/32, 2804:10ac::/32, 2804:10b0::/32, 2804:10b4::/32, 2804:10b8::/32, 2804:10bc::/32, 2804:10c0::/32, 2804:10c4::/32, 2804:10c8::/32, 2804:10cc::/32, 2804:10d0::/32, 2804:10d4::/32, 2804:10d8::/32, 2804:10dc::/32, 2804:10e0::/32, 2804:10e4::/32, 2804:10e8::/32, 2804:10ec::/32, 2804:10f0::/32, 2804:10f4::/32, 2804:10f8::/32, 2804:10fc::/32, 2804:1100::/32, 2804:1104::/32, 2804:1108::/32, 2804:110c::/32, 2804:1110::/32, 2804:1114::/32, 2804:1118::/32, 2804:111c::/32, 2804:1120::/32, 2804:1124::/32, 2804:1128::/32, 2804:112c::/32, 2804:1130::/32, 2804:1134::/32, 2804:1138::/32, 2804:113c::/32, 2804:1140::/32, 2804:1144::/32, 2804:1148::/32, 2804:1150::/32, 2804:1154::/32, 2804:1158::/32, 2804:115c::/32, 2804:1160::/32, 2804:1164::/32, 2804:1168::/32, 2804:116c::/32, 2804:1170::/32, 2804:1174::/32, 2804:1178::/32, 2804:117c::/32, 2804:1180::/32, 2804:1184::/32, 2804:1188::/32, 2804:118c::/32, 2804:1190::/32, 2804:1194::/32, 2804:1198::/32, 2804:119c::/32, 2804:11a0::/32, 2804:11a4::/32, 2804:11a8::/32, 2804:11ac::/32, 2804:11b0::/32, 2804:11b4::/32, 2804:11b8::/32, 2804:11bc::/32, 2804:11c0::/32, 2804:11c4::/32, 2804:11c8::/32, 2804:11cc::/32, 2804:11d0::/32, 2804:11d4::/32, 2804:11d8::/32, 2804:11dc::/32, 2804:11e0::/32, 2804:11e4::/32, 2804:11e8::/32, 2804:11ec::/32, 2804:11f0::/32, 2804:11f4::/32, 2804:11f8::/32, 2804:11fc::/32, 2804:1200::/32, 2804:1204::/32, 2804:1208::/32, 2804:120c::/32, 2804:1210::/32, 2804:1214::/32, 2804:1218::/32, 2804:121c::/32, 2804:1220::/32, 2804:1224::/32, 2804:122c::/32, 2804:1230::/32, 2804:1234::/32, 2804:1238::/32, 2804:123c::/32, 2804:1240::/32, 2804:1244::/32, 2804:1248::/32, 2804:124c::/32, 2804:1250::/32, 2804:1254::/32, 2804:1258::/32, 2804:125c::/32, 2804:1260::/32, 2804:1264::/32, 2804:1268::/32, 2804:126c::/32, 2804:1270::/32, 2804:1274::/32, 2804:1278::/32, 2804:127c::/32, 2804:1280::/32, 2804:1284::/32, 2804:1288::/32, 2804:128c::/32, 2804:1290::/32, 2804:1294::/32, 2804:1298::/32, 2804:129c::/32, 2804:12a0::/32, 2804:12a4::/32, 2804:12a8::/32, 2804:12ac::/32, 2804:12b0::/32, 2804:12b4::/32, 2804:12b8::/32, 2804:12bc::/32, 2804:12c0::/32, 2804:12c4::/32, 2804:12c8::/32, 2804:12cc::/32, 2804:12d0::/32, 2804:12d4::/32, 2804:12d8::/32, 2804:12dc::/32, 2804:12e0::/32, 2804:12e4::/32, 2804:12e8::/32, 2804:12ec::/32, 2804:12f0::/32, 2804:12f4::/32, 2804:12f8::/32, 2804:12fc::/32, 2804:1300::/32, 2804:1304::/32, 2804:1308::/32, 2804:130c::/32, 2804:1310::/32, 2804:1314::/32, 2804:1318::/32, 2804:131c::/32, 2804:1320::/32, 2804:1324::/32, 2804:1328::/32, 2804:132c::/32, 2804:1330::/32, 2804:1334::/32, 2804:1338::/32, 2804:133c::/32, 2804:1340::/32, 2804:1344::/32, 2804:1348::/32, 2804:134c::/32, 2804:1350::/32, 2804:1354::/32, 2804:135c::/32, 2804:1360::/32, 2804:1364::/32, 2804:1368::/32, 2804:136c::/32, 2804:1370::/32, 2804:1374::/32, 2804:1378::/32, 2804:137c::/32, 2804:1380::/32, 2804:1384::/32, 2804:1388::/30, 2804:1390::/32, 2804:1394::/32, 2804:1398::/32, 2804:139c::/32, 2804:13a0::/32, 2804:13a4::/32, 2804:13a8::/32, 2804:13ac::/32, 2804:13b0::/32, 2804:13b4::/32, 2804:13b8::/32, 2804:13bc::/32, 2804:13c0::/32, 2804:13c4::/32, 2804:13c8::/32, 2804:13cc::/32, 2804:13d0::/32, 2804:13d4::/32, 2804:13d8::/32, 2804:13dc::/32, 2804:13e0::/32, 2804:13e4::/32, 2804:13e8::/32, 2804:13ec::/32, 2804:13f0::/32, 2804:13f4::/32, 2804:13f8::/32, 2804:13fc::/32, 2804:1400::/32, 2804:1404::/32, 2804:1408::/32, 2804:140c::/32, 2804:1410::/32, 2804:1414::/32, 2804:1418::/32, 2804:141c::/32, 2804:1420::/32, 2804:1424::/32, 2804:1428::/32, 2804:142c::/32, 2804:1430::/32, 2804:1434::/32, 2804:1438::/32, 2804:143c::/32, 2804:1440::/32, 2804:1444::/32, 2804:1448::/32, 2804:144c::/32, 2804:1450::/32, 2804:1454::/32, 2804:1458::/32, 2804:145c::/32, 2804:1460::/32, 2804:1464::/32, 2804:1468::/32, 2804:146c::/32, 2804:1470::/32, 2804:1474::/32, 2804:1478::/32, 2804:147c::/32, 2804:1480::/32, 2804:1484::/32, 2804:1488::/32, 2804:148c::/32, 2804:1490::/32, 2804:1494::/32, 2804:1498::/32, 2804:149c::/32, 2804:14a0::/32, 2804:14a4::/32, 2804:14a8::/32, 2804:14ac::/32, 2804:14b0::/32, 2804:14b4::/32, 2804:14b8::/32, 2804:14bc::/32, 2804:14c0::/32, 2804:14c4::/32, 2804:14c8::/32, 2804:14cc::/32, 2804:14d0::/32, 2804:14d4::/32, 2804:14d8::/32, 2804:14dc::/32, 2804:14e0::/32, 2804:14e4::/32, 2804:14e8::/32, 2804:14ec::/32, 2804:14f0::/32, 2804:14f4::/32, 2804:14f8::/32, 2804:14fc::/32, 2804:1500::/32, 2804:1504::/32, 2804:1508::/32, 2804:150c::/32, 2804:1510::/32, 2804:1514::/32, 2804:1518::/32, 2804:151c::/32, 2804:1520::/32, 2804:1524::/32, 2804:1528::/32, 2804:152c::/32, 2804:1530::/32, 2804:1534::/32, 2804:1538::/32, 2804:1540::/32, 2804:1544::/32, 2804:1548::/32, 2804:154c::/32, 2804:1550::/32, 2804:1554::/32, 2804:1558::/32, 2804:155c::/32, 2804:1560::/32, 2804:1564::/32, 2804:1568::/32, 2804:156c::/32, 2804:1570::/32, 2804:1574::/32, 2804:1578::/32, 2804:157c::/32, 2804:1580::/32, 2804:1588::/32, 2804:158c::/32, 2804:1590::/32, 2804:1594::/32, 2804:1598::/32, 2804:159c::/32, 2804:15a0::/32, 2804:15a4::/32, 2804:15a8::/32, 2804:15ac::/32, 2804:15b0::/32, 2804:15b4::/32, 2804:15b8::/32, 2804:15bc::/32, 2804:15c0::/32, 2804:15c4::/32, 2804:15c8::/32, 2804:15cc::/32, 2804:15d0::/32, 2804:15d4::/32, 2804:15d8::/32, 2804:15dc::/32, 2804:15e0::/32, 2804:15e4::/32, 2804:15e8::/32, 2804:15ec::/32, 2804:15f0::/32, 2804:15f4::/32, 2804:15f8::/32, 2804:15fc::/32, 2804:1600::/32, 2804:1604::/32, 2804:1608::/32, 2804:160c::/32, 2804:1610::/32, 2804:1614::/32, 2804:1618::/32, 2804:161c::/32, 2804:1620::/32, 2804:1624::/32, 2804:1628::/32, 2804:162c::/32, 2804:1630::/32, 2804:1634::/32, 2804:1638::/32, 2804:163c::/32, 2804:1640::/32, 2804:1644::/32, 2804:1648::/32, 2804:164c::/32, 2804:1650::/32, 2804:1654::/32, 2804:1658::/32, 2804:165c::/32, 2804:1660::/32, 2804:1664::/32, 2804:1668::/32, 2804:166c::/32, 2804:1670::/32, 2804:1674::/32, 2804:1678::/32, 2804:167c::/32, 2804:1680::/32, 2804:1684::/32, 2804:1688::/32, 2804:168c::/32, 2804:1690::/32, 2804:1694::/32, 2804:1698::/32, 2804:169c::/32, 2804:16a0::/32, 2804:16a4::/32, 2804:16a8::/32, 2804:16ac::/32, 2804:16b0::/32, 2804:16b4::/32, 2804:16b8::/32, 2804:16bc::/32, 2804:16c0::/32, 2804:16c4::/32, 2804:16c8::/32, 2804:16cc::/32, 2804:16d0::/32, 2804:16d4::/32, 2804:16d8::/32, 2804:16dc::/32, 2804:16e0::/32, 2804:16e4::/32, 2804:16e8::/32, 2804:16ec::/32, 2804:16f0::/32, 2804:16f4::/32, 2804:16f8::/32, 2804:16fc::/32, 2804:1700::/32, 2804:1704::/32, 2804:1708::/32, 2804:170c::/32, 2804:1710::/32, 2804:1714::/32, 2804:1718::/32, 2804:171c::/32, 2804:1720::/32, 2804:1724::/32, 2804:1728::/32, 2804:172c::/32, 2804:1730::/32, 2804:1734::/32, 2804:1738::/32, 2804:173c::/32, 2804:1740::/32, 2804:1744::/32, 2804:1748::/32, 2804:174c::/32, 2804:1750::/32, 2804:1754::/32, 2804:1758::/32, 2804:175c::/32, 2804:1760::/32, 2804:1764::/32, 2804:1768::/32, 2804:176c::/32, 2804:1770::/32, 2804:1774::/32, 2804:1778::/32, 2804:177c::/32, 2804:1780::/32, 2804:1784::/32, 2804:1788::/32, 2804:178c::/32, 2804:1790::/32, 2804:1794::/32, 2804:1798::/32, 2804:179c::/32, 2804:17a0::/32, 2804:17a4::/32, 2804:17a8::/32, 2804:17ac::/32, 2804:17b0::/32, 2804:17b4::/32, 2804:17b8::/32, 2804:17bc::/32, 2804:17c0::/32, 2804:17c4::/32, 2804:17c8::/32, 2804:17cc::/32, 2804:17d0::/32, 2804:17d4::/32, 2804:17d8::/32, 2804:17dc::/32, 2804:17e0::/32, 2804:17e4::/32, 2804:17e8::/32, 2804:17f0::/32, 2804:17f4::/32, 2804:17f8::/32, 2804:17fc::/32, 2804:1800::/32, 2804:1804::/32, 2804:1808::/32, 2804:180c::/32, 2804:1810::/32, 2804:1814::/32, 2804:1818::/32, 2804:181c::/32, 2804:1820::/32, 2804:1824::/32, 2804:1828::/32, 2804:182c::/32, 2804:1830::/32, 2804:1834::/32, 2804:1838::/32, 2804:183c::/32, 2804:1840::/32, 2804:1844::/32, 2804:1848::/32, 2804:184c::/32, 2804:1850::/32, 2804:1854::/32, 2804:1858::/32, 2804:185c::/32, 2804:1864::/32, 2804:1868::/32, 2804:186c::/32, 2804:1870::/32, 2804:1874::/32, 2804:1878::/32, 2804:187c::/32, 2804:1880::/32, 2804:1884::/32, 2804:1888::/32, 2804:188c::/32, 2804:1890::/32, 2804:1894::/32, 2804:1898::/32, 2804:189c::/32, 2804:18a0::/32, 2804:18a4::/32, 2804:18a8::/32, 2804:18ac::/32, 2804:18b0::/32, 2804:18b4::/32, 2804:18b8::/32, 2804:18bc::/32, 2804:18c0::/32, 2804:18c4::/32, 2804:18c8::/32, 2804:18cc::/32, 2804:18d0::/32, 2804:18d4::/32, 2804:18d8::/32, 2804:18dc::/32, 2804:18e0::/32, 2804:18e4::/32, 2804:18e8::/32, 2804:18ec::/32, 2804:18f0::/32, 2804:18f4::/32, 2804:18f8::/32, 2804:18fc::/32, 2804:1900::/32, 2804:1908::/32, 2804:190c::/32, 2804:1910::/32, 2804:1914::/32, 2804:1918::/32, 2804:191c::/32, 2804:1920::/32, 2804:1924::/32, 2804:1928::/32, 2804:192c::/32, 2804:1930::/32, 2804:1934::/32, 2804:1938::/32, 2804:193c::/32, 2804:1940::/32, 2804:1944::/32, 2804:1948::/32, 2804:194c::/32, 2804:1950::/32, 2804:1954::/32, 2804:1958::/32, 2804:195c::/32, 2804:1964::/32, 2804:1968::/32, 2804:196c::/32, 2804:1970::/32, 2804:1974::/32, 2804:1978::/32, 2804:197c::/32, 2804:1980::/32, 2804:1984::/32, 2804:1988::/32, 2804:198c::/32, 2804:1990::/32, 2804:1994::/32, 2804:1998::/32, 2804:199c::/32, 2804:19a0::/32, 2804:19a4::/32, 2804:19a8::/32, 2804:19ac::/32, 2804:19b0::/32, 2804:19b4::/32, 2804:19b8::/32, 2804:19bc::/32, 2804:19c0::/32, 2804:19c4::/32, 2804:19c8::/32, 2804:19cc::/32, 2804:19d0::/32, 2804:19d4::/32, 2804:19d8::/32, 2804:19dc::/32, 2804:19e0::/32, 2804:19e4::/32, 2804:19e8::/32, 2804:19ec::/32, 2804:19f0::/32, 2804:19f4::/32, 2804:19f8::/32, 2804:19fc::/32, 2804:1a00::/32, 2804:1a04::/32, 2804:1a08::/32, 2804:1a0c::/32, 2804:1a10::/32, 2804:1a14::/32, 2804:1a18::/32, 2804:1a1c::/32, 2804:1a20::/32, 2804:1a24::/32, 2804:1a28::/32, 2804:1a2c::/32, 2804:1a30::/32, 2804:1a34::/32, 2804:1a38::/32, 2804:1a3c::/32, 2804:1a40::/32, 2804:1a44::/32, 2804:1a48::/32, 2804:1a4c::/32, 2804:1a50::/32, 2804:1a54::/32, 2804:1a58::/32, 2804:1a5c::/32, 2804:1a60::/32, 2804:1a64::/32, 2804:1a68::/32, 2804:1a6c::/32, 2804:1a70::/32, 2804:1a74::/32, 2804:1a78::/32, 2804:1a7c::/32, 2804:1a80::/32, 2804:1a84::/32, 2804:1a88::/32, 2804:1a8c::/32, 2804:1a90::/32, 2804:1a94::/32, 2804:1a98::/32, 2804:1a9c::/32, 2804:1aa0::/32, 2804:1aa4::/32, 2804:1aa8::/32, 2804:1aac::/32, 2804:1ab0::/32, 2804:1ab4::/32, 2804:1ab8::/32, 2804:1abc::/32, 2804:1ac0::/32, 2804:1ac4::/32, 2804:1ac8::/32, 2804:1acc::/32, 2804:1ad0::/32, 2804:1ad4::/32, 2804:1ad8::/32, 2804:1adc::/32, 2804:1ae0::/32, 2804:1ae4::/32, 2804:1ae8::/32, 2804:1aec::/32, 2804:1af0::/32, 2804:1af4::/32, 2804:1af8::/32, 2804:1afc::/32, 2804:1b00::/32, 2804:1b04::/32, 2804:1b08::/32, 2804:1b0c::/32, 2804:1b10::/32, 2804:1b14::/32, 2804:1b18::/32, 2804:1b1c::/32, 2804:1b20::/32, 2804:1b24::/32, 2804:1b28::/32, 2804:1b2c::/32, 2804:1b30::/32, 2804:1b34::/32, 2804:1b38::/32, 2804:1b3c::/32, 2804:1b40::/32, 2804:1b44::/32, 2804:1b48::/32, 2804:1b4c::/32, 2804:1b50::/32, 2804:1b54::/32, 2804:1b58::/32, 2804:1b5c::/32, 2804:1b60::/32, 2804:1b64::/32, 2804:1b68::/32, 2804:1b6c::/32, 2804:1b70::/32, 2804:1b74::/32, 2804:1b78::/32, 2804:1b7c::/32, 2804:1b80::/32, 2804:1b84::/32, 2804:1b88::/32, 2804:1b8c::/32, 2804:1b90::/32, 2804:1b94::/32, 2804:1b98::/32, 2804:1b9c::/32, 2804:1ba0::/32, 2804:1ba4::/32, 2804:1ba8::/32, 2804:1bac::/32, 2804:1bb0::/32, 2804:1bb4::/32, 2804:1bb8::/32, 2804:1bbc::/32, 2804:1bc0::/32, 2804:1bc4::/32, 2804:1bc8::/32, 2804:1bcc::/32, 2804:1bd0::/32, 2804:1bd4::/32, 2804:1bd8::/32, 2804:1bdc::/32, 2804:1be0::/32, 2804:1be4::/32, 2804:1be8::/32, 2804:1bec::/32, 2804:1bf0::/32, 2804:1bf4::/32, 2804:1bf8::/32, 2804:1bfc::/32, 2804:1c00::/32, 2804:1c04::/32, 2804:1c08::/32, 2804:1c0c::/32, 2804:1c10::/32, 2804:1c14::/32, 2804:1c18::/32, 2804:1c1c::/32, 2804:1c20::/32, 2804:1c24::/32, 2804:1c28::/32, 2804:1c2c::/32, 2804:1c30::/32, 2804:1c34::/32, 2804:1c38::/32, 2804:1c3c::/32, 2804:1c40::/32, 2804:1c44::/32, 2804:1c48::/32, 2804:1c4c::/32, 2804:1c50::/32, 2804:1c54::/32, 2804:1c58::/32, 2804:1c5c::/32, 2804:1c60::/32, 2804:1c64::/32, 2804:1c68::/32, 2804:1c6c::/32, 2804:1c74::/32, 2804:1c78::/32, 2804:1c7c::/32, 2804:1c80::/32, 2804:1c84::/32, 2804:1c88::/32, 2804:1c8c::/32, 2804:1c90::/32, 2804:1c94::/32, 2804:1c98::/32, 2804:1c9c::/32, 2804:1ca0::/32, 2804:1ca4::/32, 2804:1ca8::/32, 2804:1cac::/32, 2804:1cb0::/32, 2804:1cb4::/32, 2804:1cb8::/32, 2804:1cbc::/32, 2804:1cc0::/32, 2804:1cc4::/32, 2804:1cc8::/32, 2804:1ccc::/32, 2804:1cd0::/32, 2804:1cd4::/32, 2804:1cd8::/32, 2804:1cdc::/32, 2804:1ce0::/32, 2804:1ce4::/32, 2804:1ce8::/32, 2804:1cec::/32, 2804:1cf0::/32, 2804:1cf4::/32, 2804:1cf8::/32, 2804:1cfc::/32, 2804:1d00::/32, 2804:1d04::/32, 2804:1d08::/32, 2804:1d0c::/32, 2804:1d10::/32, 2804:1d14::/32, 2804:1d18::/32, 2804:1d1c::/32, 2804:1d20::/32, 2804:1d24::/32, 2804:1d28::/32, 2804:1d2c::/32, 2804:1d30::/32, 2804:1d34::/32, 2804:1d38::/32, 2804:1d3c::/32, 2804:1d40::/32, 2804:1d44::/32, 2804:1d48::/32, 2804:1d4c::/32, 2804:1d50::/32, 2804:1d54::/32, 2804:1d58::/32, 2804:1d5c::/32, 2804:1d60::/32, 2804:1d64::/32, 2804:1d68::/32, 2804:1d6c::/32, 2804:1d70::/32, 2804:1d74::/32, 2804:1d78::/32, 2804:1d7c::/32, 2804:1d80::/32, 2804:1d84::/32, 2804:1d88::/32, 2804:1d8c::/32, 2804:1d90::/32, 2804:1d94::/32, 2804:1d98::/32, 2804:1d9c::/32, 2804:1da0::/32, 2804:1da4::/32, 2804:1da8::/32, 2804:1dac::/32, 2804:1db0::/32, 2804:1db4::/32, 2804:1db8::/32, 2804:1dbc::/32, 2804:1dc0::/32, 2804:1dc4::/32, 2804:1dc8::/32, 2804:1dcc::/32, 2804:1dd0::/32, 2804:1dd4::/32, 2804:1dd8::/32, 2804:1ddc::/32, 2804:1de0::/32, 2804:1de4::/32, 2804:1de8::/32, 2804:1dec::/32, 2804:1df0::/32, 2804:1df4::/32, 2804:1df8::/32, 2804:1dfc::/32, 2804:1e00::/32, 2804:1e04::/32, 2804:1e08::/32, 2804:1e0c::/32, 2804:1e10::/32, 2804:1e14::/32, 2804:1e18::/32, 2804:1e20::/32, 2804:1e28::/32, 2804:1e2c::/32, 2804:1e30::/32, 2804:1e34::/32, 2804:1e38::/32, 2804:1e3c::/32, 2804:1e40::/32, 2804:1e44::/32, 2804:1e48::/32, 2804:1e4c::/32, 2804:1e50::/32, 2804:1e54::/32, 2804:1e58::/32, 2804:1e5c::/32, 2804:1e60::/32, 2804:1e64::/32, 2804:1e68::/32, 2804:1e6c::/32, 2804:1e70::/32, 2804:1e74::/32, 2804:1e78::/32, 2804:1e7c::/32, 2804:1e80::/32, 2804:1e84::/32, 2804:1e88::/32, 2804:1e8c::/32, 2804:1e90::/32, 2804:1e94::/32, 2804:1e98::/32, 2804:1e9c::/32, 2804:1ea0::/32, 2804:1ea4::/32, 2804:1ea8::/32, 2804:1eac::/32, 2804:1eb0::/32, 2804:1eb4::/32, 2804:1eb8::/32, 2804:1ebc::/32, 2804:1ec0::/32, 2804:1ec4::/32, 2804:1ec8::/32, 2804:1ecc::/32, 2804:1ed0::/32, 2804:1ed4::/32, 2804:1ed8::/32, 2804:1edc::/32, 2804:1ee0::/32, 2804:1ee4::/32, 2804:1ee8::/32, 2804:1eec::/32, 2804:1ef0::/32, 2804:1ef4::/32, 2804:1ef8::/32, 2804:1efc::/32, 2804:1f00::/32, 2804:1f02::/32, 2804:1f04::/32, 2804:1f06::/32, 2804:1f08::/32, 2804:1f0a::/32, 2804:1f0c::/32, 2804:1f0e::/35, 2804:1f10::/32, 2804:1f12::/32, 2804:1f14::/32, 2804:1f16::/32, 2804:1f18::/32, 2804:1f1a::/32, 2804:1f1c::/32, 2804:1f1e::/32, 2804:1f20::/32, 2804:1f22::/32, 2804:1f24::/32, 2804:1f26::/32, 2804:1f28::/32, 2804:1f2a::/32, 2804:1f2c::/32, 2804:1f2e::/32, 2804:1f30::/32, 2804:1f32::/32, 2804:1f34::/32, 2804:1f36::/32, 2804:1f38::/32, 2804:1f3a::/32, 2804:1f3c::/36, 2804:1f3e::/32, 2804:2000::/32, 2804:2004::/32, 2804:2008::/32, 2804:200c::/32, 2804:2010::/32, 2804:2014::/32, 2804:2018::/32, 2804:201c::/32, 2804:2020::/32, 2804:2024::/32, 2804:2028::/32, 2804:202c::/32, 2804:2030::/32, 2804:2034::/32, 2804:2038::/32, 2804:203c::/32, 2804:2040::/32, 2804:2044::/32, 2804:2048::/32, 2804:204c::/32, 2804:2050::/32, 2804:2054::/32, 2804:2058::/32, 2804:205c::/32, 2804:2060::/32, 2804:2064::/32, 2804:2068::/32, 2804:206c::/32, 2804:2070::/32, 2804:2074::/32, 2804:2078::/32, 2804:207c::/32, 2804:2080::/32, 2804:2084::/32, 2804:2088::/32, 2804:208c::/32, 2804:2090::/32, 2804:2094::/32, 2804:2098::/32, 2804:209c::/32, 2804:20a0::/32, 2804:20a4::/32, 2804:20a8::/32, 2804:20ac::/32, 2804:20b0::/32, 2804:20b4::/32, 2804:20b8::/32, 2804:20bc::/32, 2804:20c0::/32, 2804:20c4::/32, 2804:20c8::/32, 2804:20cc::/32, 2804:20d0::/32, 2804:20d4::/32, 2804:20d8::/32, 2804:20dc::/32, 2804:20e0::/32, 2804:20e4::/32, 2804:20e8::/32, 2804:20ec::/32, 2804:20f0::/32, 2804:20f4::/32, 2804:20f8::/32, 2804:20fc::/32, 2804:2100::/32, 2804:2104::/32, 2804:2108::/32, 2804:210c::/32, 2804:2110::/32, 2804:2114::/32, 2804:2118::/32, 2804:211c::/32, 2804:2120::/32, 2804:2124::/32, 2804:2128::/32, 2804:212c::/32, 2804:2130::/32, 2804:2134::/32, 2804:2138::/32, 2804:213c::/32, 2804:2140::/32, 2804:2144::/32, 2804:2148::/32, 2804:214c::/32, 2804:2150::/32, 2804:2154::/32, 2804:2158::/32, 2804:215c::/32, 2804:2160::/32, 2804:2164::/32, 2804:2168::/32, 2804:216c::/32, 2804:2170::/32, 2804:2174::/32, 2804:2178::/32, 2804:217c::/32, 2804:2180::/32, 2804:2184::/32, 2804:2188::/32, 2804:218c::/32, 2804:2190::/32, 2804:2194::/32, 2804:2198::/32, 2804:219c::/32, 2804:21a0::/32, 2804:21a4::/32, 2804:21a8::/32, 2804:21ac::/32, 2804:21b0::/32, 2804:21b4::/32, 2804:21b8::/32, 2804:21bc::/32, 2804:21c0::/32, 2804:21c8::/32, 2804:21cc::/32, 2804:21d0::/32, 2804:21d4::/32, 2804:21d8::/32, 2804:21dc::/32, 2804:21e0::/32, 2804:21e4::/32, 2804:21e8::/32, 2804:21ec::/32, 2804:21f0::/32, 2804:21f4::/32, 2804:21f8::/32, 2804:21fc::/32, 2804:2200::/32, 2804:2204::/32, 2804:2208::/32, 2804:220c::/32, 2804:2210::/32, 2804:2214::/32, 2804:2218::/32, 2804:221c::/32, 2804:2224::/32, 2804:2228::/32, 2804:222c::/32, 2804:2230::/32, 2804:2234::/32, 2804:2238::/32, 2804:223c::/32, 2804:2240::/32, 2804:2244::/32, 2804:2248::/32, 2804:224c::/32, 2804:2250::/32, 2804:2254::/32, 2804:2258::/32, 2804:225c::/32, 2804:2260::/32, 2804:2264::/32, 2804:2268::/32, 2804:226c::/32, 2804:2270::/32, 2804:2274::/32, 2804:2278::/32, 2804:227c::/32, 2804:2280::/32, 2804:2284::/32, 2804:2288::/32, 2804:228c::/32, 2804:2290::/32, 2804:2294::/32, 2804:2298::/32, 2804:229c::/32, 2804:22a0::/32, 2804:22a4::/32, 2804:22a8::/32, 2804:22ac::/32, 2804:22b0::/32, 2804:22b4::/32, 2804:22b8::/32, 2804:22bc::/32, 2804:22c0::/32, 2804:22c4::/32, 2804:22c8::/32, 2804:22cc::/32, 2804:22d0::/32, 2804:22d4::/32, 2804:22d8::/32, 2804:22dc::/32, 2804:22e0::/32, 2804:22e4::/32, 2804:22e8::/32, 2804:22f0::/32, 2804:22f4::/32, 2804:22f8::/32, 2804:22fc::/32, 2804:2300::/32, 2804:2304::/32, 2804:2308::/32, 2804:230c::/32, 2804:2310::/32, 2804:2314::/32, 2804:2318::/32, 2804:231c::/32, 2804:2320::/32, 2804:2324::/32, 2804:2328::/32, 2804:232c::/32, 2804:2330::/32, 2804:2334::/32, 2804:2338::/32, 2804:233c::/32, 2804:2344::/32, 2804:2348::/32, 2804:234c::/32, 2804:2350::/32, 2804:2354::/32, 2804:2358::/32, 2804:235c::/32, 2804:2360::/32, 2804:2364::/32, 2804:2368::/32, 2804:236c::/32, 2804:2370::/32, 2804:2374::/32, 2804:2378::/32, 2804:2380::/32, 2804:2384::/32, 2804:2388::/32, 2804:238c::/32, 2804:2390::/32, 2804:2394::/32, 2804:2398::/32, 2804:239c::/32, 2804:23a0::/32, 2804:23a4::/32, 2804:23ac::/32, 2804:23b0::/32, 2804:23b4::/32, 2804:23b8::/32, 2804:23bc::/32, 2804:23c0::/31, 2804:23c4::/32, 2804:23c8::/32, 2804:23cc::/32, 2804:23d0::/32, 2804:23d4::/32, 2804:23d8::/32, 2804:23dc::/32, 2804:23e0::/32, 2804:23e4::/32, 2804:23e8::/32, 2804:23ec::/32, 2804:23f0::/32, 2804:23f4::/32, 2804:23f8::/32, 2804:23fc::/32, 2804:2400::/32, 2804:2404::/32, 2804:2408::/32, 2804:240c::/32, 2804:2410::/32, 2804:2414::/32, 2804:2418::/32, 2804:241c::/32, 2804:2420::/32, 2804:2424::/32, 2804:2428::/32, 2804:242c::/32, 2804:2430::/32, 2804:2434::/32, 2804:2438::/32, 2804:243c::/32, 2804:2440::/32, 2804:2444::/32, 2804:2448::/32, 2804:244c::/32, 2804:2450::/32, 2804:2454::/32, 2804:2458::/32, 2804:245c::/32, 2804:2460::/32, 2804:2464::/32, 2804:2468::/32, 2804:246c::/32, 2804:2470::/32, 2804:2474::/32, 2804:2478::/32, 2804:247c::/32, 2804:2480::/32, 2804:2484::/32, 2804:2488::/32, 2804:248c::/32, 2804:2490::/32, 2804:2494::/32, 2804:2498::/32, 2804:249c::/32, 2804:24a0::/32, 2804:24a4::/32, 2804:24a8::/32, 2804:24ac::/32, 2804:24b0::/32, 2804:24b4::/32, 2804:24b8::/32, 2804:24bc::/32, 2804:24c0::/32, 2804:24c4::/32, 2804:24c8::/32, 2804:24cc::/32, 2804:24d0::/32, 2804:24d4::/32, 2804:24d8::/32, 2804:24dc::/32, 2804:24e0::/32, 2804:24e4::/32, 2804:24e8::/32, 2804:24ec::/32, 2804:24f0::/32, 2804:24f4::/32, 2804:24f8::/32, 2804:24fc::/32, 2804:2500::/32, 2804:2504::/32, 2804:2508::/32, 2804:250c::/32, 2804:2510::/32, 2804:2514::/32, 2804:2518::/32, 2804:251c::/32, 2804:2520::/32, 2804:2524::/32, 2804:2528::/32, 2804:252c::/32, 2804:2530::/32, 2804:2534::/32, 2804:2538::/32, 2804:253c::/32, 2804:2540::/32, 2804:2544::/32, 2804:2548::/32, 2804:254c::/32, 2804:2550::/32, 2804:2554::/32, 2804:2558::/32, 2804:255c::/32, 2804:2564::/32, 2804:2568::/32, 2804:256c::/32, 2804:2570::/32, 2804:2574::/32, 2804:2578::/32, 2804:257c::/32, 2804:2580::/32, 2804:2584::/32, 2804:2588::/32, 2804:258c::/32, 2804:2590::/32, 2804:2594::/32, 2804:2598::/32, 2804:259c::/32, 2804:25a4::/32, 2804:25a8::/32, 2804:25ac::/32, 2804:25b0::/32, 2804:25b4::/32, 2804:25b8::/32, 2804:25bc::/32, 2804:25c0::/32, 2804:25c4::/32, 2804:25c8::/32, 2804:25cc::/32, 2804:25d0::/32, 2804:25d4::/32, 2804:25d8::/32, 2804:25dc::/32, 2804:25e0::/32, 2804:25e4::/32, 2804:25e8::/32, 2804:25ec::/32, 2804:25f0::/32, 2804:25f4::/32, 2804:25f8::/32, 2804:25fc::/32, 2804:2600::/32, 2804:2604::/32, 2804:2608::/32, 2804:260c::/32, 2804:2610::/32, 2804:2614::/32, 2804:2618::/32, 2804:261c::/32, 2804:2620::/32, 2804:2624::/32, 2804:2628::/32, 2804:262c::/32, 2804:2630::/32, 2804:2634::/32, 2804:2638::/32, 2804:263c::/32, 2804:2640::/32, 2804:2644::/32, 2804:2648::/32, 2804:264c::/32, 2804:2650::/32, 2804:2654::/32, 2804:2658::/32, 2804:265c::/32, 2804:2660::/32, 2804:2664::/32, 2804:2668::/32, 2804:266c::/32, 2804:2670::/32, 2804:2674::/32, 2804:2678::/32, 2804:267c::/32, 2804:2680::/32, 2804:2684::/32, 2804:2688::/32, 2804:268c::/32, 2804:2690::/32, 2804:2694::/32, 2804:2698::/32, 2804:269c::/32, 2804:26a0::/32, 2804:26a4::/32, 2804:26a8::/32, 2804:26ac::/32, 2804:26b0::/32, 2804:26b4::/32, 2804:26b8::/32, 2804:26bc::/32, 2804:26c0::/32, 2804:26c4::/32, 2804:26c8::/32, 2804:26cc::/32, 2804:26d0::/32, 2804:26d4::/32, 2804:26d8::/32, 2804:26dc::/32, 2804:26e0::/32, 2804:26e4::/32, 2804:26e8::/32, 2804:26ec::/32, 2804:26f0::/32, 2804:26f4::/32, 2804:26f8::/32, 2804:26fc::/32, 2804:2700::/32, 2804:2704::/32, 2804:270c::/32, 2804:2710::/32, 2804:2714::/32, 2804:2718::/32, 2804:271c::/32, 2804:2720::/32, 2804:2724::/32, 2804:2728::/32, 2804:272c::/32, 2804:2730::/32, 2804:2734::/32, 2804:2738::/32, 2804:273c::/32, 2804:2740::/32, 2804:2744::/32, 2804:2748::/32, 2804:274c::/32, 2804:2750::/32, 2804:2754::/32, 2804:2758::/32, 2804:275c::/32, 2804:2760::/32, 2804:2764::/32, 2804:2768::/32, 2804:276c::/32, 2804:2770::/32, 2804:2774::/32, 2804:2778::/32, 2804:277c::/32, 2804:2780::/32, 2804:2784::/32, 2804:2788::/32, 2804:278c::/32, 2804:2790::/32, 2804:2794::/32, 2804:2798::/32, 2804:279c::/32, 2804:27a0::/32, 2804:27a4::/32, 2804:27a8::/32, 2804:27ac::/32, 2804:27b0::/32, 2804:27b4::/32, 2804:27b8::/32, 2804:27bc::/32, 2804:27c0::/32, 2804:27c4::/32, 2804:27c8::/32, 2804:27cc::/32, 2804:27d0::/32, 2804:27d4::/32, 2804:27d8::/32, 2804:27dc::/32, 2804:27e0::/32, 2804:27e4::/32, 2804:27e8::/32, 2804:27ec::/32, 2804:27f0::/32, 2804:27f4::/32, 2804:27f8::/32, 2804:27fc::/32, 2804:2800::/32, 2804:2804::/32, 2804:2808::/32, 2804:280c::/32, 2804:2810::/32, 2804:2814::/32, 2804:2818::/32, 2804:281c::/32, 2804:2820::/32, 2804:2824::/32, 2804:2828::/32, 2804:282c::/32, 2804:2830::/32, 2804:2834::/32, 2804:2838::/32, 2804:283c::/32, 2804:2840::/32, 2804:2844::/32, 2804:2848::/32, 2804:284c::/32, 2804:2850::/32, 2804:2854::/32, 2804:2858::/32, 2804:285c::/32, 2804:2860::/32, 2804:2864::/32, 2804:2868::/32, 2804:286c::/32, 2804:2870::/32, 2804:2874::/32, 2804:2878::/32, 2804:287c::/32, 2804:2880::/32, 2804:2884::/32, 2804:2888::/32, 2804:288c::/32, 2804:2890::/32, 2804:2894::/32, 2804:2898::/32, 2804:289c::/32, 2804:28a0::/32, 2804:28a4::/32, 2804:28a8::/32, 2804:28ac::/32, 2804:28b0::/32, 2804:28b4::/32, 2804:28b8::/32, 2804:28bc::/32, 2804:28c0::/32, 2804:28c4::/32, 2804:28c8::/32, 2804:28cc::/32, 2804:28d0::/32, 2804:28d4::/32, 2804:28d8::/32, 2804:28dc::/32, 2804:28e0::/32, 2804:28e4::/32, 2804:28e8::/32, 2804:28ec::/32, 2804:28f0::/32, 2804:28f4::/32, 2804:28f8::/32, 2804:28fc::/32, 2804:2900::/32, 2804:2904::/32, 2804:2908::/32, 2804:290c::/32, 2804:2910::/32, 2804:2914::/32, 2804:2918::/32, 2804:291c::/32, 2804:2920::/32, 2804:2924::/32, 2804:2928::/32, 2804:292c::/32, 2804:2930::/32, 2804:2938::/32, 2804:293c::/32, 2804:2940::/32, 2804:2944::/32, 2804:2948::/32, 2804:294c::/32, 2804:2950::/32, 2804:2954::/32, 2804:2958::/32, 2804:295c::/32, 2804:2960::/32, 2804:2964::/32, 2804:2968::/32, 2804:296c::/32, 2804:2970::/32, 2804:2974::/32, 2804:2978::/32, 2804:297c::/32, 2804:2980::/32, 2804:2984::/32, 2804:2988::/32, 2804:298c::/32, 2804:2990::/32, 2804:2994::/32, 2804:2998::/32, 2804:299c::/32, 2804:29a0::/32, 2804:29a4::/32, 2804:29a8::/32, 2804:29ac::/32, 2804:29b0::/32, 2804:29b4::/32, 2804:29b8::/32, 2804:29bc::/32, 2804:29c0::/32, 2804:29c4::/32, 2804:29c8::/32, 2804:29cc::/32, 2804:29d0::/32, 2804:29d4::/32, 2804:29d8::/32, 2804:29dc::/32, 2804:29e0::/32, 2804:29e4::/32, 2804:29e8::/32, 2804:29ec::/32, 2804:29f0::/32, 2804:29f4::/32, 2804:29f8::/32, 2804:29fc::/32, 2804:2a00::/32, 2804:2a04::/32, 2804:2a08::/32, 2804:2a0c::/32, 2804:2a10::/32, 2804:2a14::/32, 2804:2a18::/32, 2804:2a1c::/32, 2804:2a20::/32, 2804:2a24::/32, 2804:2a28::/32, 2804:2a2c::/32, 2804:2a30::/32, 2804:2a34::/32, 2804:2a38::/32, 2804:2a3c::/32, 2804:2a40::/32, 2804:2a44::/32, 2804:2a48::/32, 2804:2a4c::/32, 2804:2a50::/32, 2804:2a54::/32, 2804:2a58::/32, 2804:2a5c::/32, 2804:2a60::/32, 2804:2a64::/32, 2804:2a68::/32, 2804:2a6c::/32, 2804:2a70::/32, 2804:2a74::/32, 2804:2a78::/32, 2804:2a7c::/32, 2804:2a80::/32, 2804:2a84::/32, 2804:2a88::/32, 2804:2a8c::/32, 2804:2a90::/32, 2804:2a98::/32, 2804:2a9c::/32, 2804:2aa4::/32, 2804:2aa8::/32, 2804:2aac::/32, 2804:2ab0::/32, 2804:2ab4::/32, 2804:2ab8::/32, 2804:2abc::/32, 2804:2ac0::/32, 2804:2ac4::/32, 2804:2ac8::/32, 2804:2acc::/32, 2804:2ad4::/32, 2804:2ad8::/32, 2804:2adc::/32, 2804:2ae0::/32, 2804:2ae4::/32, 2804:2ae8::/32, 2804:2aec::/32, 2804:2af0::/32, 2804:2af4::/32, 2804:2af8::/32, 2804:2afc::/32, 2804:2b00::/32, 2804:2b04::/32, 2804:2b08::/32, 2804:2b0c::/32, 2804:2b10::/32, 2804:2b14::/32, 2804:2b18::/32, 2804:2b1c::/32, 2804:2b20::/32, 2804:2b24::/32, 2804:2b28::/32, 2804:2b2c::/32, 2804:2b30::/32, 2804:2b34::/32, 2804:2b38::/32, 2804:2b3c::/32, 2804:2b40::/32, 2804:2b44::/32, 2804:2b48::/32, 2804:2b4c::/32, 2804:2b50::/32, 2804:2b54::/32, 2804:2b58::/32, 2804:2b5c::/32, 2804:2b60::/32, 2804:2b64::/32, 2804:2b68::/32, 2804:2b6c::/32, 2804:2b70::/32, 2804:2b74::/32, 2804:2b78::/32, 2804:2b7c::/32, 2804:2b80::/32, 2804:2b84::/32, 2804:2b88::/32, 2804:2b8c::/32, 2804:2b90::/32, 2804:2b94::/32, 2804:2b98::/32, 2804:2b9c::/32, 2804:2ba0::/32, 2804:2ba4::/32, 2804:2ba8::/32, 2804:2bac::/32, 2804:2bb0::/32, 2804:2bb4::/32, 2804:2bb8::/32, 2804:2bbc::/32, 2804:2bc0::/32, 2804:2bc4::/32, 2804:2bc8::/32, 2804:2bcc::/32, 2804:2bd0::/32, 2804:2bd4::/32, 2804:2bd8::/32, 2804:2bdc::/32, 2804:2be0::/32, 2804:2be4::/32, 2804:2be8::/32, 2804:2bec::/32, 2804:2bf0::/32, 2804:2bf4::/32, 2804:2bf8::/32, 2804:2bfc::/32, 2804:2c00::/32, 2804:2c04::/32, 2804:2c08::/32, 2804:2c0c::/32, 2804:2c10::/32, 2804:2c14::/32, 2804:2c18::/32, 2804:2c20::/32, 2804:2c24::/32, 2804:2c28::/32, 2804:2c2c::/32, 2804:2c30::/32, 2804:2c34::/32, 2804:2c38::/32, 2804:2c3c::/32, 2804:2c40::/32, 2804:2c44::/32, 2804:2c48::/32, 2804:2c4c::/32, 2804:2c50::/32, 2804:2c54::/32, 2804:2c58::/32, 2804:2c5c::/32, 2804:2c60::/32, 2804:2c64::/32, 2804:2c68::/32, 2804:2c6c::/32, 2804:2c70::/32, 2804:2c74::/32, 2804:2c78::/32, 2804:2c7c::/32, 2804:2c80::/32, 2804:2c84::/32, 2804:2c88::/32, 2804:2c8c::/32, 2804:2c90::/32, 2804:2c94::/32, 2804:2c98::/32, 2804:2c9c::/32, 2804:2ca0::/32, 2804:2ca4::/32, 2804:2ca8::/32, 2804:2cac::/32, 2804:2cb0::/32, 2804:2cb4::/32, 2804:2cb8::/32, 2804:2cbc::/32, 2804:2cc0::/32, 2804:2cc4::/32, 2804:2cc8::/32, 2804:2ccc::/32, 2804:2cd0::/32, 2804:2cd4::/32, 2804:2cd8::/32, 2804:2cdc::/32, 2804:2ce0::/32, 2804:2ce4::/32, 2804:2ce8::/32, 2804:2cec::/32, 2804:2cf0::/32, 2804:2cf4::/32, 2804:2cf8::/32, 2804:2cfc::/32, 2804:2d00::/32, 2804:2d04::/32, 2804:2d08::/32, 2804:2d0c::/32, 2804:2d10::/32, 2804:2d14::/32, 2804:2d18::/32, 2804:2d1c::/32, 2804:2d20::/32, 2804:2d24::/32, 2804:2d28::/32, 2804:2d2c::/32, 2804:2d30::/32, 2804:2d34::/32, 2804:2d38::/32, 2804:2d3c::/32, 2804:2d40::/32, 2804:2d44::/32, 2804:2d48::/32, 2804:2d4c::/32, 2804:2d50::/32, 2804:2d54::/32, 2804:2d58::/32, 2804:2d5c::/32, 2804:2d60::/32, 2804:2d64::/32, 2804:2d68::/32, 2804:2d6c::/32, 2804:2d70::/32, 2804:2d74::/32, 2804:2d78::/32, 2804:2d7c::/32, 2804:2d80::/32, 2804:2d84::/32, 2804:2d88::/32, 2804:2d8c::/32, 2804:2d90::/32, 2804:2d94::/32, 2804:2d98::/32, 2804:2d9c::/32, 2804:2da0::/32, 2804:2da4::/32, 2804:2da8::/32, 2804:2dac::/32, 2804:2db0::/32, 2804:2db4::/32, 2804:2db8::/32, 2804:2dbc::/32, 2804:2dc0::/32, 2804:2dc4::/32, 2804:2dc8::/32, 2804:2dcc::/32, 2804:2dd0::/32, 2804:2dd4::/32, 2804:2dd8::/32, 2804:2ddc::/32, 2804:2de0::/32, 2804:2de4::/32, 2804:2de8::/32, 2804:2dec::/32, 2804:2df0::/32, 2804:2df4::/32, 2804:2df8::/32, 2804:2e00::/32, 2804:2e04::/32, 2804:2e08::/32, 2804:2e0c::/32, 2804:2e10::/32, 2804:2e14::/32, 2804:2e18::/32, 2804:2e1c::/32, 2804:2e20::/32, 2804:2e24::/32, 2804:2e28::/32, 2804:2e2c::/32, 2804:2e30::/32, 2804:2e34::/32, 2804:2e38::/32, 2804:2e3c::/32, 2804:2e40::/32, 2804:2e44::/32, 2804:2e48::/32, 2804:2e4c::/32, 2804:2e50::/32, 2804:2e54::/32, 2804:2e58::/32, 2804:2e5c::/32, 2804:2e60::/32, 2804:2e64::/32, 2804:2e68::/32, 2804:2e6c::/32, 2804:2e70::/32, 2804:2e74::/32, 2804:2e78::/32, 2804:2e7c::/32, 2804:2e80::/32, 2804:2e84::/32, 2804:2e88::/32, 2804:2e90::/32, 2804:2e94::/32, 2804:2e98::/32, 2804:2e9c::/32, 2804:2ea0::/32, 2804:2ea4::/32, 2804:2ea8::/32, 2804:2eac::/32, 2804:2eb0::/32, 2804:2eb4::/32, 2804:2eb8::/32, 2804:2ebc::/32, 2804:2ec0::/32, 2804:2ec4::/32, 2804:2ec8::/32, 2804:2ecc::/32, 2804:2ed0::/32, 2804:2ed4::/32, 2804:2ed8::/32, 2804:2edc::/32, 2804:2ee0::/32, 2804:2ee4::/32, 2804:2ee8::/32, 2804:2eec::/32, 2804:2ef0::/32, 2804:2ef4::/32, 2804:2ef8::/32, 2804:2efc::/32, 2804:2f00::/32, 2804:2f04::/32, 2804:2f08::/32, 2804:2f0c::/32, 2804:2f10::/32, 2804:2f14::/32, 2804:2f18::/32, 2804:2f1c::/32, 2804:2f20::/32, 2804:2f24::/32, 2804:2f28::/32, 2804:2f2c::/32, 2804:2f30::/32, 2804:2f34::/32, 2804:2f38::/32, 2804:2f3c::/32, 2804:2f40::/32, 2804:2f44::/32, 2804:2f48::/32, 2804:2f4c::/32, 2804:2f50::/32, 2804:2f54::/32, 2804:2f58::/32, 2804:2f5c::/32, 2804:2f60::/32, 2804:2f64::/32, 2804:2f68::/32, 2804:2f6c::/32, 2804:2f70::/32, 2804:2f74::/32, 2804:2f78::/32, 2804:2f7c::/32, 2804:2f80::/32, 2804:2f84::/32, 2804:2f88::/32, 2804:2f8c::/32, 2804:2f90::/32, 2804:2f94::/32, 2804:2f98::/32, 2804:2f9c::/32, 2804:2fa0::/32, 2804:2fa4::/32, 2804:2fa8::/32, 2804:2fac::/32, 2804:2fb0::/32, 2804:2fb4::/32, 2804:2fb8::/32, 2804:2fbc::/32, 2804:2fc0::/32, 2804:2fc4::/32, 2804:2fc8::/32, 2804:2fcc::/32, 2804:2fd0::/32, 2804:2fd4::/32, 2804:2fd8::/32, 2804:2fdc::/32, 2804:2fe0::/32, 2804:2fe4::/32, 2804:2fe8::/32, 2804:2fec::/32, 2804:2ff0::/32, 2804:2ff8::/32, 2804:2ffc::/32, 2804:3000::/32, 2804:3004::/32, 2804:3008::/32, 2804:3010::/32, 2804:3014::/32, 2804:3018::/32, 2804:301c::/32, 2804:3020::/32, 2804:3024::/32, 2804:3028::/32, 2804:302c::/32, 2804:3030::/32, 2804:3034::/32, 2804:3038::/32, 2804:303c::/32, 2804:3040::/32, 2804:3044::/32, 2804:3048::/32, 2804:304c::/32, 2804:3050::/32, 2804:3054::/32, 2804:3058::/32, 2804:305c::/32, 2804:3060::/32, 2804:3064::/32, 2804:3068::/32, 2804:306c::/32, 2804:3070::/32, 2804:3074::/32, 2804:3078::/32, 2804:307c::/32, 2804:3080::/32, 2804:3084::/32, 2804:3088::/32, 2804:308c::/32, 2804:3090::/32, 2804:3094::/32, 2804:3098::/32, 2804:309c::/32, 2804:30a0::/32, 2804:30a4::/32, 2804:30a8::/32, 2804:30ac::/32, 2804:30b0::/32, 2804:30b4::/32, 2804:30b8::/32, 2804:30bc::/32, 2804:30c0::/32, 2804:30c4::/32, 2804:30c8::/32, 2804:30cc::/32, 2804:30d0::/32, 2804:30d4::/32, 2804:30d8::/32, 2804:30dc::/32, 2804:30e0::/32, 2804:30e4::/32, 2804:30e8::/32, 2804:30ec::/32, 2804:30f0::/32, 2804:30f4::/32, 2804:30f8::/32, 2804:30fc::/32, 2804:3100::/32, 2804:3104::/32, 2804:3108::/32, 2804:310c::/32, 2804:3110::/32, 2804:3114::/32, 2804:3118::/32, 2804:311c::/32, 2804:3120::/32, 2804:3124::/32, 2804:3128::/32, 2804:312c::/32, 2804:3130::/32, 2804:3134::/32, 2804:3138::/32, 2804:313c::/32, 2804:3140::/32, 2804:3144::/32, 2804:3148::/32, 2804:314c::/32, 2804:3150::/32, 2804:3154::/32, 2804:3158::/32, 2804:315c::/32, 2804:3160::/32, 2804:3164::/32, 2804:3168::/32, 2804:316c::/32, 2804:3170::/32, 2804:3174::/32, 2804:3178::/32, 2804:317c::/32, 2804:3180::/32, 2804:3184::/32, 2804:3188::/32, 2804:318c::/32, 2804:3190::/32, 2804:3194::/32, 2804:3198::/32, 2804:319c::/32, 2804:31a0::/32, 2804:31a4::/32, 2804:31a8::/32, 2804:31ac::/32, 2804:31b0::/32, 2804:31b4::/32, 2804:31b8::/32, 2804:31bc::/32, 2804:31c0::/32, 2804:31c4::/32, 2804:31c8::/32, 2804:31cc::/32, 2804:31d0::/32, 2804:31d4::/32, 2804:31d8::/32, 2804:31dc::/32, 2804:31e0::/32, 2804:31e4::/32, 2804:31e8::/32, 2804:31ec::/32, 2804:31f0::/32, 2804:31f4::/32, 2804:31f8::/32, 2804:31fc::/32, 2804:3200::/32, 2804:3204::/32, 2804:3208::/32, 2804:320c::/32, 2804:3210::/32, 2804:3214::/32, 2804:3218::/32, 2804:321c::/32, 2804:3220::/32, 2804:3224::/32, 2804:3228::/32, 2804:322c::/32, 2804:3230::/32, 2804:3234::/32, 2804:3238::/32, 2804:323c::/32, 2804:3240::/32, 2804:3244::/32, 2804:3248::/32, 2804:324c::/32, 2804:3250::/32, 2804:3254::/32, 2804:3258::/32, 2804:325c::/32, 2804:3260::/32, 2804:3264::/32, 2804:3268::/32, 2804:326c::/32, 2804:3270::/32, 2804:3274::/32, 2804:3278::/32, 2804:327c::/32, 2804:3280::/32, 2804:3284::/32, 2804:3288::/32, 2804:328c::/32, 2804:3290::/32, 2804:3294::/32, 2804:3298::/32, 2804:329c::/32, 2804:32a0::/32, 2804:32a4::/32, 2804:32a8::/32, 2804:32ac::/32, 2804:32b0::/32, 2804:32b4::/32, 2804:32b8::/32, 2804:32bc::/32, 2804:32c0::/32, 2804:32c4::/32, 2804:32c8::/32, 2804:32cc::/32, 2804:32d0::/32, 2804:32d4::/32, 2804:32d8::/32, 2804:32dc::/32, 2804:32e0::/32, 2804:32e4::/32, 2804:32e8::/32, 2804:32ec::/32, 2804:32f0::/32, 2804:32f4::/32, 2804:32f8::/32, 2804:32fc::/32, 2804:3300::/32, 2804:3304::/32, 2804:3308::/32, 2804:330c::/32, 2804:3310::/32, 2804:3318::/32, 2804:331c::/32, 2804:3320::/32, 2804:3324::/32, 2804:3328::/32, 2804:332c::/32, 2804:3330::/32, 2804:3334::/32, 2804:3338::/32, 2804:333c::/32, 2804:3340::/32, 2804:3344::/32, 2804:3348::/32, 2804:334c::/32, 2804:3350::/32, 2804:3354::/32, 2804:3358::/32, 2804:335c::/32, 2804:3360::/32, 2804:3364::/32, 2804:3368::/32, 2804:336c::/32, 2804:3370::/32, 2804:3374::/32, 2804:3378::/32, 2804:337c::/32, 2804:3380::/32, 2804:3384::/32, 2804:3388::/32, 2804:338c::/32, 2804:3390::/32, 2804:3394::/32, 2804:3398::/32, 2804:339c::/32, 2804:33a0::/32, 2804:33a4::/32, 2804:33a8::/32, 2804:33ac::/32, 2804:33b0::/32, 2804:33b4::/32, 2804:33b8::/32, 2804:33bc::/32, 2804:33c0::/32, 2804:33c4::/32, 2804:33c8::/32, 2804:33cc::/32, 2804:33d0::/32, 2804:33d4::/32, 2804:33d8::/32, 2804:33dc::/32, 2804:33e0::/32, 2804:33e4::/32, 2804:33e8::/32, 2804:33ec::/32, 2804:33f0::/32, 2804:33f4::/32, 2804:33f8::/32, 2804:33fc::/32, 2804:3400::/32, 2804:3404::/32, 2804:3408::/32, 2804:340c::/32, 2804:3410::/32, 2804:3414::/32, 2804:3418::/32, 2804:341c::/32, 2804:3420::/32, 2804:3424::/32, 2804:3428::/32, 2804:342c::/32, 2804:3430::/32, 2804:3434::/32, 2804:3438::/32, 2804:343c::/32, 2804:3440::/32, 2804:3444::/32, 2804:3448::/32, 2804:344c::/32, 2804:3450::/32, 2804:3454::/32, 2804:3458::/32, 2804:345c::/32, 2804:3460::/32, 2804:3464::/32, 2804:3468::/32, 2804:346c::/32, 2804:3470::/32, 2804:3474::/32, 2804:3478::/32, 2804:347c::/32, 2804:3480::/32, 2804:3484::/32, 2804:3488::/32, 2804:348c::/32, 2804:3490::/32, 2804:3494::/32, 2804:3498::/32, 2804:349c::/32, 2804:34a0::/32, 2804:34a4::/32, 2804:34a8::/32, 2804:34ac::/32, 2804:34b0::/32, 2804:34b4::/32, 2804:34b8::/32, 2804:34bc::/32, 2804:34c0::/32, 2804:34c4::/32, 2804:34c8::/32, 2804:34cc::/32, 2804:34d0::/32, 2804:34d4::/32, 2804:34d8::/32, 2804:34dc::/32, 2804:34e0::/32, 2804:34e4::/32, 2804:34e8::/32, 2804:34ec::/32, 2804:34f0::/32, 2804:34f4::/32, 2804:34f8::/32, 2804:34fc::/32, 2804:3500::/32, 2804:3504::/32, 2804:3508::/32, 2804:350c::/32, 2804:3510::/32, 2804:3514::/32, 2804:3518::/32, 2804:351c::/32, 2804:3520::/32, 2804:3524::/32, 2804:3528::/32, 2804:352c::/32, 2804:3530::/32, 2804:3534::/32, 2804:3538::/32, 2804:353c::/32, 2804:3540::/32, 2804:3544::/32, 2804:3548::/32, 2804:354c::/32, 2804:3550::/32, 2804:3554::/32, 2804:3558::/32, 2804:355c::/32, 2804:3560::/32, 2804:3564::/32, 2804:3568::/32, 2804:356c::/32, 2804:3570::/32, 2804:3574::/32, 2804:3578::/32, 2804:357c::/32, 2804:3580::/32, 2804:3584::/32, 2804:3588::/32, 2804:358c::/32, 2804:3590::/32, 2804:3594::/32, 2804:3598::/32, 2804:359c::/32, 2804:35a0::/32, 2804:35a4::/32, 2804:35a8::/32, 2804:35ac::/32, 2804:35b0::/32, 2804:35b4::/32, 2804:35b8::/32, 2804:35bc::/32, 2804:35c0::/32, 2804:35c4::/32, 2804:35c8::/32, 2804:35cc::/32, 2804:35d0::/32, 2804:35d4::/32, 2804:35d8::/32, 2804:35dc::/32, 2804:35e0::/32, 2804:35e4::/32, 2804:35e8::/32, 2804:35ec::/32, 2804:35f0::/32, 2804:35f4::/32, 2804:35f8::/32, 2804:35fc::/32, 2804:3600::/32, 2804:3604::/32, 2804:3608::/32, 2804:360c::/32, 2804:3610::/32, 2804:3614::/32, 2804:3618::/32, 2804:361c::/32, 2804:3620::/32, 2804:3624::/32, 2804:3628::/32, 2804:362c::/32, 2804:3630::/32, 2804:3634::/32, 2804:3638::/32, 2804:363c::/32, 2804:3640::/32, 2804:3644::/32, 2804:3648::/32, 2804:364c::/32, 2804:3650::/32, 2804:3654::/32, 2804:3658::/32, 2804:365c::/32, 2804:3660::/32, 2804:3664::/32, 2804:3668::/32, 2804:366c::/32, 2804:3670::/32, 2804:3674::/32, 2804:3678::/32, 2804:367c::/32, 2804:3680::/32, 2804:3684::/32, 2804:3688::/32, 2804:368c::/32, 2804:3690::/32, 2804:3694::/32, 2804:3698::/32, 2804:369c::/32, 2804:36a0::/32, 2804:36a4::/32, 2804:36a8::/32, 2804:36ac::/32, 2804:36b0::/32, 2804:36b4::/32, 2804:36b8::/32, 2804:36bc::/32, 2804:36c0::/32, 2804:36c4::/32, 2804:36c8::/32, 2804:36cc::/32, 2804:36d0::/32, 2804:36d4::/32, 2804:36d8::/32, 2804:36dc::/32, 2804:36e0::/32, 2804:36e4::/32, 2804:36e8::/32, 2804:36ec::/32, 2804:36f0::/32, 2804:36f4::/32, 2804:36f8::/32, 2804:36fc::/32, 2804:3700::/32, 2804:3704::/32, 2804:3708::/32, 2804:370c::/32, 2804:3710::/32, 2804:3714::/32, 2804:3718::/32, 2804:371c::/32, 2804:3720::/32, 2804:3724::/32, 2804:3728::/32, 2804:372c::/32, 2804:3730::/32, 2804:3734::/32, 2804:3738::/32, 2804:373c::/32, 2804:3740::/32, 2804:3744::/32, 2804:3748::/32, 2804:374c::/32, 2804:3750::/32, 2804:3754::/32, 2804:3758::/32, 2804:375c::/32, 2804:3760::/32, 2804:3764::/32, 2804:3768::/32, 2804:376c::/32, 2804:3770::/32, 2804:3774::/32, 2804:3778::/32, 2804:377c::/32, 2804:3780::/32, 2804:3784::/32, 2804:3788::/32, 2804:378c::/32, 2804:3790::/32, 2804:3794::/32, 2804:3798::/32, 2804:379c::/32, 2804:37a0::/32, 2804:37a4::/32, 2804:37a8::/32, 2804:37ac::/32, 2804:37b0::/32, 2804:37b4::/32, 2804:37b8::/32, 2804:37bc::/32, 2804:37c0::/32, 2804:37c4::/32, 2804:37c8::/32, 2804:37cc::/32, 2804:37d0::/32, 2804:37d4::/32, 2804:37d8::/32, 2804:37dc::/32, 2804:37e0::/32, 2804:37e4::/32, 2804:37e8::/32, 2804:37ec::/32, 2804:37f0::/32, 2804:37f4::/32, 2804:37f8::/32, 2804:37fc::/32, 2804:3800::/32, 2804:3804::/32, 2804:3808::/32, 2804:380c::/32, 2804:3810::/32, 2804:3814::/32, 2804:3818::/32, 2804:381c::/32, 2804:3820::/32, 2804:3824::/32, 2804:3828::/32, 2804:382c::/32, 2804:3830::/32, 2804:3834::/32, 2804:3838::/32, 2804:383c::/32, 2804:3840::/32, 2804:3844::/32, 2804:3848::/32, 2804:384c::/32, 2804:3850::/32, 2804:3854::/32, 2804:3858::/32, 2804:385c::/32, 2804:3860::/32, 2804:3864::/32, 2804:3868::/32, 2804:386c::/32, 2804:3870::/32, 2804:3874::/32, 2804:3878::/32, 2804:387c::/32, 2804:3880::/32, 2804:3884::/32, 2804:3888::/32, 2804:388c::/32, 2804:3890::/32, 2804:3894::/32, 2804:3898::/32, 2804:389c::/32, 2804:38a0::/32, 2804:38a4::/32, 2804:38a8::/32, 2804:38ac::/32, 2804:38b0::/32, 2804:38b4::/32, 2804:38b8::/32, 2804:38bc::/32, 2804:38c0::/32, 2804:38c4::/32, 2804:38c8::/32, 2804:38cc::/32, 2804:38d0::/32, 2804:38d4::/32, 2804:38d8::/32, 2804:38dc::/32, 2804:38e0::/32, 2804:38e4::/32, 2804:38e8::/32, 2804:38ec::/32, 2804:38f0::/32, 2804:38f4::/32, 2804:38f8::/32, 2804:38fc::/32, 2804:3900::/32, 2804:3904::/32, 2804:3908::/32, 2804:390c::/32, 2804:3910::/32, 2804:3914::/32, 2804:3918::/32, 2804:391c::/32, 2804:3920::/32, 2804:3924::/32, 2804:3928::/32, 2804:392c::/32, 2804:3930::/32, 2804:3934::/32, 2804:3938::/32, 2804:393c::/32, 2804:3940::/32, 2804:3944::/32, 2804:3948::/32, 2804:394c::/32, 2804:3950::/32, 2804:3954::/32, 2804:3958::/32, 2804:395c::/32, 2804:3960::/32, 2804:3964::/32, 2804:3968::/32, 2804:396c::/32, 2804:3970::/32, 2804:3974::/32, 2804:3978::/32, 2804:397c::/32, 2804:3980::/32, 2804:3984::/32, 2804:3988::/32, 2804:398c::/32, 2804:3990::/32, 2804:3994::/32, 2804:3998::/32, 2804:399c::/32, 2804:39a0::/32, 2804:39a4::/32, 2804:39a8::/32, 2804:39ac::/32, 2804:39b0::/32, 2804:39b4::/32, 2804:39b8::/32, 2804:39bc::/32, 2804:39c0::/32, 2804:39c4::/32, 2804:39c8::/32, 2804:39cc::/32, 2804:39d0::/32, 2804:39d4::/32, 2804:39d8::/32, 2804:39dc::/32, 2804:39e0::/32, 2804:39e4::/32, 2804:39e8::/32, 2804:39ec::/32, 2804:39f0::/32, 2804:39f4::/32, 2804:39f8::/32, 2804:39fc::/32, 2804:3a00::/32, 2804:3a04::/32, 2804:3a08::/32, 2804:3a0c::/32, 2804:3a10::/32, 2804:3a14::/32, 2804:3a18::/32, 2804:3a1c::/32, 2804:3a20::/32, 2804:3a24::/32, 2804:3a28::/32, 2804:3a2c::/32, 2804:3a30::/32, 2804:3a34::/32, 2804:3a38::/32, 2804:3a3c::/32, 2804:3a40::/32, 2804:3a44::/32, 2804:3a48::/32, 2804:3a4c::/32, 2804:3a50::/32, 2804:3a54::/32, 2804:3a58::/32, 2804:3a5c::/32, 2804:3a60::/32, 2804:3a64::/32, 2804:3a68::/32, 2804:3a6c::/32, 2804:3a70::/32, 2804:3a74::/32, 2804:3a78::/32, 2804:3a7c::/32, 2804:3a80::/32, 2804:3a84::/32, 2804:3a88::/32, 2804:3a8c::/32, 2804:3a90::/32, 2804:3a94::/32, 2804:3a98::/32, 2804:3a9c::/32, 2804:3aa0::/32, 2804:3aa4::/32, 2804:3aa8::/32, 2804:3aac::/32, 2804:3ab0::/32, 2804:3ab4::/32, 2804:3ab8::/32, 2804:3abc::/32, 2804:3ac0::/32, 2804:3ac4::/32, 2804:3ac8::/32, 2804:3acc::/32, 2804:3ad0::/32, 2804:3ad4::/32, 2804:3ad8::/32, 2804:3adc::/32, 2804:3ae0::/32, 2804:3ae4::/32, 2804:3ae8::/32, 2804:3aec::/32, 2804:3af0::/32, 2804:3af4::/32, 2804:3af8::/32, 2804:3afc::/32, 2804:3b00::/32, 2804:3b04::/32, 2804:3b08::/32, 2804:3b0c::/32, 2804:3b10::/32, 2804:3b14::/32, 2804:3b18::/32, 2804:3b1c::/32, 2804:3b20::/32, 2804:3b24::/32, 2804:3b28::/32, 2804:3b2c::/32, 2804:3b30::/32, 2804:3b34::/32, 2804:3b38::/32, 2804:3b3c::/32, 2804:3b40::/32, 2804:3b44::/32, 2804:3b48::/32, 2804:3b4c::/32, 2804:3b50::/32, 2804:3b54::/32, 2804:3b58::/32, 2804:3b5c::/32, 2804:3b60::/32, 2804:3b64::/32, 2804:3b68::/32, 2804:3b6c::/32, 2804:3b70::/32, 2804:3b74::/32, 2804:3b78::/32, 2804:3b7c::/32, 2804:3b80::/32, 2804:3b84::/32, 2804:3b88::/32, 2804:3b8c::/32, 2804:3b90::/32, 2804:3b94::/32, 2804:3b98::/32, 2804:3b9c::/32, 2804:3ba0::/32, 2804:3ba4::/32, 2804:3ba8::/32, 2804:3bac::/32, 2804:3bb0::/32, 2804:3bb4::/32, 2804:3bb8::/32, 2804:3bbc::/32, 2804:3bc0::/32, 2804:3bc4::/32, 2804:3bc8::/32, 2804:3bcc::/32, 2804:3bd0::/32, 2804:3bd4::/32, 2804:3bd8::/32, 2804:3bdc::/32, 2804:3be0::/32, 2804:3be4::/32, 2804:3be8::/32, 2804:3bec::/32, 2804:3bf0::/32, 2804:3bf4::/32, 2804:3bf8::/32, 2804:3bfc::/32, 2804:3c00::/32, 2804:3c04::/32, 2804:3c08::/32, 2804:3c0c::/32, 2804:3c10::/32, 2804:3c14::/32, 2804:3c18::/32, 2804:3c1c::/32, 2804:3c20::/32, 2804:3c24::/32, 2804:3c28::/32, 2804:3c2c::/32, 2804:3c30::/32, 2804:3c34::/32, 2804:3c38::/32, 2804:3c3c::/32, 2804:3c40::/32, 2804:3c44::/32, 2804:3c48::/32, 2804:3c4c::/32, 2804:3c50::/32, 2804:3c54::/32, 2804:3c58::/32, 2804:3c5c::/32, 2804:3c60::/32, 2804:3c64::/32, 2804:3c68::/32, 2804:3c6c::/32, 2804:3c70::/32, 2804:3c74::/32, 2804:3c78::/32, 2804:3c7c::/32, 2804:3c80::/32, 2804:3c84::/32, 2804:3c88::/32, 2804:3c8c::/32, 2804:3c90::/32, 2804:3c94::/32, 2804:3c98::/32, 2804:3c9c::/32, 2804:3ca0::/32, 2804:3ca4::/32, 2804:3ca8::/32, 2804:3cac::/32, 2804:3cb0::/32, 2804:3cb4::/32, 2804:3cb8::/32, 2804:3cbc::/32, 2804:3cc0::/32, 2804:3cc4::/32, 2804:3cc8::/32, 2804:3ccc::/32, 2804:3cd0::/32, 2804:3cd4::/32, 2804:3cd8::/32, 2804:3cdc::/32, 2804:3ce0::/32, 2804:3ce4::/32, 2804:3ce8::/32, 2804:3cec::/32, 2804:3cf0::/32, 2804:3cf4::/32, 2804:3cf8::/32, 2804:3cfc::/32, 2804:3d00::/32, 2804:3d04::/32, 2804:3d08::/32, 2804:3d0c::/32, 2804:3d10::/32, 2804:3d14::/32, 2804:3d18::/32, 2804:3d1c::/32, 2804:3d20::/32, 2804:3d24::/32, 2804:3d28::/32, 2804:3d2c::/32, 2804:3d30::/32, 2804:3d34::/32, 2804:3d38::/32, 2804:3d3c::/32, 2804:3d40::/32, 2804:3d44::/32, 2804:3d48::/32, 2804:3d4c::/32, 2804:3d50::/32, 2804:3d54::/32, 2804:3d58::/32, 2804:3d5c::/32, 2804:3d60::/32, 2804:3d64::/32, 2804:3d68::/32, 2804:3d6c::/32, 2804:3d70::/32, 2804:3d74::/32, 2804:3d78::/32, 2804:3d7c::/32, 2804:3d80::/32, 2804:3d84::/32, 2804:3d88::/32, 2804:3d8c::/32, 2804:3d90::/32, 2804:3d94::/32, 2804:3d98::/32, 2804:3d9c::/32, 2804:3da0::/32, 2804:3da4::/32, 2804:3da8::/32, 2804:3dac::/32, 2804:3db0::/32, 2804:3db4::/32, 2804:3db8::/32, 2804:3dbc::/32, 2804:3dc0::/32, 2804:3dc4::/32, 2804:3dc8::/32, 2804:3dcc::/32, 2804:3dd0::/32, 2804:3dd4::/32, 2804:3dd8::/32, 2804:3ddc::/32, 2804:3de0::/32, 2804:3de4::/32, 2804:3de8::/32, 2804:3dec::/32, 2804:3df0::/32, 2804:3df4::/32, 2804:3df8::/32, 2804:3dfc::/32, 2804:3e00::/32, 2804:3e04::/32, 2804:3e08::/32, 2804:3e0c::/32, 2804:3e10::/32, 2804:3e14::/32, 2804:3e18::/32, 2804:3e1c::/32, 2804:3e20::/32, 2804:3e24::/32, 2804:3e28::/32, 2804:3e2c::/32, 2804:3e30::/32, 2804:3e34::/32, 2804:3e38::/32, 2804:3e3c::/32, 2804:3e40::/32, 2804:3e44::/32, 2804:3e4c::/32, 2804:3e50::/32, 2804:3e54::/32, 2804:3e58::/32, 2804:3e5c::/32, 2804:3e60::/32, 2804:3e64::/32, 2804:3e68::/32, 2804:3e6c::/32, 2804:3e70::/32, 2804:3e74::/32, 2804:3e78::/32, 2804:3e7c::/32, 2804:3e80::/32, 2804:3e84::/32, 2804:3e88::/32, 2804:3e8c::/32, 2804:3e90::/32, 2804:3e94::/32, 2804:3e98::/32, 2804:3e9c::/32, 2804:3ea0::/32, 2804:3ea4::/32, 2804:3ea8::/32, 2804:3eac::/32, 2804:3eb0::/32, 2804:3eb4::/32, 2804:3eb8::/32, 2804:3ebc::/32, 2804:3ec0::/32, 2804:3ec4::/32, 2804:3ec8::/32, 2804:3ecc::/32, 2804:3ed0::/32, 2804:3ed4::/32, 2804:3ed8::/32, 2804:3edc::/32, 2804:3ee0::/32, 2804:3ee4::/32, 2804:3ee8::/32, 2804:3eec::/32, 2804:3ef0::/32, 2804:3ef4::/32, 2804:3ef8::/32, 2804:3efc::/32, 2804:3f00::/32, 2804:3f04::/32, 2804:3f08::/32, 2804:3f0c::/32, 2804:3f10::/32, 2804:3f14::/32, 2804:3f18::/32, 2804:3f1c::/32, 2804:3f20::/32, 2804:3f24::/32, 2804:3f28::/32, 2804:3f2c::/32, 2804:3f30::/32, 2804:3f34::/32, 2804:3f38::/32, 2804:3f3c::/32, 2804:3f40::/32, 2804:3f44::/32, 2804:3f48::/32, 2804:3f4c::/32, 2804:3f50::/32, 2804:3f54::/32, 2804:3f58::/32, 2804:3f5c::/32, 2804:3f60::/32, 2804:3f64::/32, 2804:3f68::/32, 2804:3f6c::/32, 2804:3f70::/32, 2804:3f74::/32, 2804:3f78::/32, 2804:3f7c::/32, 2804:3f80::/32, 2804:3f84::/32, 2804:3f88::/32, 2804:3f90::/32, 2804:3f94::/32, 2804:3f98::/32, 2804:3f9c::/32, 2804:3fa0::/32, 2804:3fa4::/32, 2804:3fa8::/32, 2804:3fac::/32, 2804:3fb0::/32, 2804:3fb8::/32, 2804:3fbc::/32, 2804:3fc0::/32, 2804:3fc4::/32, 2804:3fc8::/32, 2804:3fcc::/32, 2804:3fd0::/32, 2804:3fd4::/32, 2804:3fd8::/32, 2804:3fdc::/32, 2804:3fe0::/32, 2804:3fe4::/32, 2804:3fec::/32, 2804:3ff0::/32, 2804:3ff4::/32, 2804:3ff8::/32, 2804:3ffc::/32, 2804:4000::/32, 2804:4004::/32, 2804:4008::/32, 2804:400c::/32, 2804:4010::/32, 2804:4014::/32, 2804:4018::/32, 2804:401c::/32, 2804:4020::/32, 2804:4024::/32, 2804:4028::/32, 2804:402c::/32, 2804:4030::/32, 2804:4034::/32, 2804:4038::/32, 2804:403c::/32, 2804:4040::/32, 2804:4044::/32, 2804:4048::/32, 2804:404c::/32, 2804:4050::/32, 2804:4054::/32, 2804:4058::/32, 2804:405c::/32, 2804:4060::/32, 2804:4064::/32, 2804:4068::/32, 2804:406c::/32, 2804:4070::/32, 2804:4074::/32, 2804:4078::/32, 2804:407c::/32, 2804:4080::/32, 2804:4084::/32, 2804:4088::/32, 2804:408c::/32, 2804:4090::/32, 2804:4094::/32, 2804:4098::/32, 2804:409c::/32, 2804:40a0::/32, 2804:40a4::/32, 2804:40a8::/32, 2804:40ac::/32, 2804:40b0::/32, 2804:40b4::/32, 2804:40b8::/32, 2804:40bc::/32, 2804:40c0::/32, 2804:40c4::/32, 2804:40c8::/32, 2804:40cc::/32, 2804:40d0::/32, 2804:40d4::/32, 2804:40d8::/32, 2804:40dc::/32, 2804:40e0::/32, 2804:40e4::/32, 2804:40e8::/32, 2804:40ec::/32, 2804:40f0::/32, 2804:40f4::/32, 2804:40f8::/32, 2804:40fc::/32, 2804:4100::/32, 2804:4104::/32, 2804:4108::/32, 2804:410c::/32, 2804:4110::/32, 2804:4114::/32, 2804:4118::/32, 2804:411c::/32, 2804:4120::/32, 2804:4124::/32, 2804:412c::/32, 2804:4130::/32, 2804:4134::/32, 2804:4138::/32, 2804:413c::/32, 2804:4140::/32, 2804:4144::/32, 2804:4148::/32, 2804:414c::/32, 2804:4150::/32, 2804:4154::/32, 2804:4158::/32, 2804:415c::/32, 2804:4160::/32, 2804:4164::/32, 2804:4168::/32, 2804:416c::/32, 2804:4170::/32, 2804:4174::/32, 2804:4178::/32, 2804:417c::/32, 2804:4180::/32, 2804:4184::/32, 2804:4188::/32, 2804:418c::/32, 2804:4190::/32, 2804:4194::/32, 2804:4198::/32, 2804:419c::/32, 2804:41a0::/32, 2804:41a4::/32, 2804:41a8::/32, 2804:41ac::/32, 2804:41b0::/32, 2804:41b4::/32, 2804:41b8::/32, 2804:41bc::/32, 2804:41c0::/32, 2804:41c4::/32, 2804:41c8::/32, 2804:41cc::/32, 2804:41d0::/32, 2804:41d4::/32, 2804:41d8::/32, 2804:41dc::/32, 2804:41e0::/32, 2804:41e4::/32, 2804:41e8::/32, 2804:41ec::/32, 2804:41f0::/32, 2804:41f4::/32, 2804:41f8::/32, 2804:41fc::/32, 2804:4200::/32, 2804:4204::/32, 2804:4208::/32, 2804:420c::/32, 2804:4210::/32, 2804:4214::/32, 2804:4218::/32, 2804:421c::/32, 2804:4220::/32, 2804:4224::/32, 2804:4228::/32, 2804:422c::/32, 2804:4230::/32, 2804:4234::/32, 2804:4238::/32, 2804:423c::/32, 2804:4240::/32, 2804:4244::/32, 2804:4248::/32, 2804:424c::/32, 2804:4250::/32, 2804:4254::/32, 2804:4258::/32, 2804:425c::/32, 2804:4260::/32, 2804:4264::/32, 2804:4268::/32, 2804:426c::/32, 2804:4270::/32, 2804:4274::/32, 2804:4278::/32, 2804:427c::/32, 2804:4280::/32, 2804:4284::/32, 2804:4288::/32, 2804:428c::/32, 2804:4290::/32, 2804:4294::/32, 2804:4298::/32, 2804:429c::/32, 2804:42a0::/32, 2804:42a4::/32, 2804:42a8::/32, 2804:42ac::/32, 2804:42b0::/32, 2804:42b4::/32, 2804:42b8::/32, 2804:42bc::/32, 2804:42c0::/32, 2804:42c4::/32, 2804:42c8::/32, 2804:42cc::/32, 2804:42d0::/32, 2804:42d4::/32, 2804:42d8::/32, 2804:42dc::/32, 2804:42e0::/32, 2804:42e4::/32, 2804:42e8::/32, 2804:42ec::/32, 2804:42f0::/32, 2804:42f4::/32, 2804:42f8::/32, 2804:42fc::/32, 2804:4300::/32, 2804:4304::/32, 2804:4308::/32, 2804:430c::/32, 2804:4310::/32, 2804:4314::/32, 2804:4318::/32, 2804:431c::/32, 2804:4320::/32, 2804:4324::/32, 2804:4328::/32, 2804:432c::/32, 2804:4330::/32, 2804:4334::/32, 2804:4338::/32, 2804:433c::/32, 2804:4340::/32, 2804:4344::/32, 2804:4348::/32, 2804:434c::/32, 2804:4350::/32, 2804:4354::/32, 2804:4358::/32, 2804:435c::/32, 2804:4360::/32, 2804:4364::/32, 2804:4368::/32, 2804:436c::/32, 2804:4370::/32, 2804:4374::/32, 2804:4378::/32, 2804:437c::/32, 2804:4380::/32, 2804:4384::/32, 2804:4388::/32, 2804:438c::/32, 2804:4390::/32, 2804:4394::/32, 2804:4398::/32, 2804:439c::/32, 2804:43a0::/32, 2804:43a4::/32, 2804:43a8::/32, 2804:43ac::/32, 2804:43b0::/32, 2804:43b4::/32, 2804:43b8::/32, 2804:43bc::/32, 2804:43c0::/32, 2804:43c4::/32, 2804:43c8::/32, 2804:43cc::/32, 2804:43d0::/32, 2804:43d4::/32, 2804:43d8::/32, 2804:43dc::/32, 2804:43e0::/32, 2804:43e4::/32, 2804:43e8::/32, 2804:43ec::/32, 2804:43f0::/32, 2804:43f4::/32, 2804:43f8::/32, 2804:43fc::/32, 2804:4400::/32, 2804:4404::/32, 2804:4408::/32, 2804:440c::/32, 2804:4410::/32, 2804:4414::/32, 2804:4418::/32, 2804:441c::/32, 2804:4420::/32, 2804:4424::/32, 2804:4428::/32, 2804:442c::/32, 2804:4430::/32, 2804:4434::/32, 2804:4438::/32, 2804:443c::/32, 2804:4440::/32, 2804:4444::/32, 2804:4448::/32, 2804:444c::/32, 2804:4450::/32, 2804:4454::/32, 2804:4458::/32, 2804:445c::/32, 2804:4460::/32, 2804:4464::/32, 2804:4468::/32, 2804:446c::/32, 2804:4470::/32, 2804:4474::/32, 2804:4478::/32, 2804:447c::/32, 2804:4480::/32, 2804:4484::/32, 2804:4488::/32, 2804:448c::/32, 2804:4490::/32, 2804:4494::/32, 2804:4498::/32, 2804:449c::/32, 2804:44a0::/32, 2804:44a8::/32, 2804:44ac::/32, 2804:44b0::/32, 2804:44b4::/32, 2804:44b8::/32, 2804:44bc::/32, 2804:44c0::/32, 2804:44c4::/32, 2804:44c8::/32, 2804:44cc::/32, 2804:44d0::/32, 2804:44d4::/32, 2804:44d8::/32, 2804:44dc::/32, 2804:44e0::/32, 2804:44e4::/32, 2804:44e8::/32, 2804:44ec::/32, 2804:44f0::/32, 2804:44f4::/32, 2804:44f8::/32, 2804:44fc::/32, 2804:4500::/32, 2804:4504::/32, 2804:4508::/32, 2804:450c::/32, 2804:4510::/32, 2804:4514::/32, 2804:4518::/32, 2804:451c::/32, 2804:4520::/32, 2804:4524::/32, 2804:4528::/32, 2804:452c::/32, 2804:4530::/32, 2804:4534::/32, 2804:4538::/32, 2804:4540::/32, 2804:4544::/32, 2804:4548::/32, 2804:454c::/32, 2804:4550::/32, 2804:4554::/32, 2804:4558::/32, 2804:455c::/32, 2804:4560::/32, 2804:4564::/32, 2804:4568::/32, 2804:456c::/32, 2804:4570::/32, 2804:4574::/32, 2804:4578::/32, 2804:457c::/32, 2804:4580::/32, 2804:4584::/32, 2804:4588::/32, 2804:458c::/32, 2804:4590::/32, 2804:4594::/32, 2804:4598::/32, 2804:459c::/32, 2804:45a0::/32, 2804:45a4::/32, 2804:45a8::/32, 2804:45ac::/32, 2804:45b0::/32, 2804:45b4::/32, 2804:45b8::/32, 2804:45bc::/32, 2804:45c0::/32, 2804:45c4::/32, 2804:45c8::/32, 2804:45cc::/32, 2804:45d0::/32, 2804:45d4::/32, 2804:45d8::/32, 2804:45dc::/32, 2804:45e0::/32, 2804:45e4::/32, 2804:45e8::/32, 2804:45ec::/32, 2804:45f0::/32, 2804:45f4::/32, 2804:45f8::/32, 2804:45fc::/32, 2804:4600::/32, 2804:4604::/32, 2804:4608::/32, 2804:460c::/32, 2804:4610::/32, 2804:4614::/32, 2804:4618::/32, 2804:461c::/32, 2804:4620::/32, 2804:4624::/32, 2804:4628::/32, 2804:462c::/32, 2804:4630::/32, 2804:4634::/32, 2804:4638::/32, 2804:463c::/32, 2804:4640::/32, 2804:4644::/32, 2804:464c::/32, 2804:4650::/32, 2804:4654::/32, 2804:4658::/32, 2804:465c::/32, 2804:4660::/32, 2804:4664::/32, 2804:4668::/32, 2804:466c::/32, 2804:4670::/32, 2804:4674::/32, 2804:4678::/32, 2804:467c::/32, 2804:4680::/32, 2804:4688::/32, 2804:468c::/32, 2804:4690::/32, 2804:4694::/32, 2804:4698::/32, 2804:469c::/32, 2804:46a0::/32, 2804:46a4::/32, 2804:46a8::/32, 2804:46ac::/32, 2804:46b0::/32, 2804:46b4::/32, 2804:46b8::/32, 2804:46bc::/32, 2804:46c0::/32, 2804:46c4::/32, 2804:46c8::/32, 2804:46cc::/32, 2804:46d0::/32, 2804:46d4::/32, 2804:46d8::/32, 2804:46dc::/32, 2804:46e0::/32, 2804:46e4::/32, 2804:46e8::/32, 2804:46ec::/32, 2804:46f0::/32, 2804:46f4::/32, 2804:46f8::/32, 2804:46fc::/32, 2804:4700::/32, 2804:4704::/32, 2804:4708::/32, 2804:470c::/32, 2804:4710::/32, 2804:4714::/32, 2804:4718::/32, 2804:471c::/32, 2804:4720::/32, 2804:4724::/32, 2804:4728::/32, 2804:472c::/32, 2804:4730::/32, 2804:4734::/32, 2804:4738::/32, 2804:473c::/32, 2804:4740::/32, 2804:4744::/32, 2804:4748::/32, 2804:474c::/32, 2804:4750::/32, 2804:4754::/32, 2804:4758::/32, 2804:475c::/32, 2804:4760::/32, 2804:4764::/32, 2804:4768::/32, 2804:476c::/32, 2804:4770::/32, 2804:4774::/32, 2804:4778::/32, 2804:477c::/32, 2804:4780::/32, 2804:4784::/32, 2804:4788::/32, 2804:478c::/32, 2804:4790::/32, 2804:4794::/32, 2804:4798::/32, 2804:479c::/32, 2804:47a0::/32, 2804:47a4::/32, 2804:47a8::/32, 2804:47ac::/32, 2804:47b0::/32, 2804:47b4::/32, 2804:47b8::/32, 2804:47bc::/32, 2804:47c0::/32, 2804:47c4::/32, 2804:47c8::/32, 2804:47cc::/32, 2804:47d0::/32, 2804:47d4::/32, 2804:47d8::/32, 2804:47dc::/32, 2804:47e0::/32, 2804:47e4::/32, 2804:47e8::/32, 2804:47ec::/32, 2804:47f0::/32, 2804:47f4::/32, 2804:47f8::/32, 2804:47fc::/32, 2804:4800::/32, 2804:4804::/32, 2804:4808::/32, 2804:480c::/32, 2804:4810::/32, 2804:4814::/32, 2804:4818::/32, 2804:481c::/32, 2804:4824::/32, 2804:4828::/32, 2804:482c::/32, 2804:4830::/32, 2804:4834::/32, 2804:4838::/32, 2804:483c::/32, 2804:4840::/32, 2804:4844::/32, 2804:4848::/32, 2804:484c::/32, 2804:4850::/32, 2804:4854::/32, 2804:4858::/32, 2804:485c::/32, 2804:4860::/32, 2804:4864::/32, 2804:4868::/32, 2804:486c::/32, 2804:4870::/32, 2804:4874::/32, 2804:4878::/32, 2804:487c::/32, 2804:4880::/32, 2804:4884::/32, 2804:4888::/32, 2804:488c::/32, 2804:4890::/32, 2804:4894::/32, 2804:4898::/32, 2804:489c::/32, 2804:48a0::/32, 2804:48a4::/32, 2804:48a8::/32, 2804:48ac::/32, 2804:48b0::/32, 2804:48b4::/32, 2804:48b8::/32, 2804:48bc::/32, 2804:48c0::/32, 2804:48c4::/32, 2804:48c8::/32, 2804:48cc::/32, 2804:48d0::/32, 2804:48d4::/32, 2804:48d8::/32, 2804:48dc::/32, 2804:48e0::/32, 2804:48e4::/32, 2804:48e8::/32, 2804:48ec::/32, 2804:48f0::/32, 2804:48f4::/32, 2804:48f8::/32, 2804:48fc::/32, 2804:4900::/32, 2804:4904::/32, 2804:4908::/32, 2804:490c::/32, 2804:4910::/32, 2804:4914::/32, 2804:4918::/32, 2804:491c::/32, 2804:4920::/32, 2804:4924::/32, 2804:4928::/32, 2804:492c::/32, 2804:4930::/32, 2804:4934::/32, 2804:4938::/32, 2804:493c::/32, 2804:4940::/32, 2804:4944::/32, 2804:4948::/32, 2804:494c::/32, 2804:4950::/32, 2804:4954::/32, 2804:4958::/32, 2804:495c::/32, 2804:4960::/32, 2804:4964::/32, 2804:4968::/32, 2804:496c::/32, 2804:4970::/32, 2804:4974::/32, 2804:4978::/32, 2804:497c::/32, 2804:4980::/32, 2804:4984::/32, 2804:4988::/32, 2804:498c::/32, 2804:4990::/32, 2804:4994::/32, 2804:4998::/32, 2804:499c::/32, 2804:49a0::/32, 2804:49a4::/32, 2804:49a8::/32, 2804:49ac::/32, 2804:49b0::/32, 2804:49b4::/32, 2804:49b8::/32, 2804:49bc::/32, 2804:49c0::/32, 2804:49c4::/32, 2804:49c8::/32, 2804:49cc::/32, 2804:49d0::/32, 2804:49d4::/32, 2804:49d8::/32, 2804:49dc::/32, 2804:49e0::/32, 2804:49e4::/32, 2804:49e8::/32, 2804:49ec::/32, 2804:49f0::/32, 2804:49f4::/32, 2804:49f8::/32, 2804:49fc::/32, 2804:4a00::/32, 2804:4a04::/32, 2804:4a08::/32, 2804:4a0c::/32, 2804:4a10::/32, 2804:4a14::/32, 2804:4a18::/32, 2804:4a1c::/32, 2804:4a20::/32, 2804:4a24::/32, 2804:4a28::/32, 2804:4a2c::/32, 2804:4a30::/32, 2804:4a34::/32, 2804:4a38::/32, 2804:4a3c::/32, 2804:4a40::/32, 2804:4a44::/32, 2804:4a48::/32, 2804:4a4c::/32, 2804:4a50::/32, 2804:4a54::/32, 2804:4a58::/32, 2804:4a5c::/32, 2804:4a60::/32, 2804:4a64::/32, 2804:4a68::/32, 2804:4a6c::/32, 2804:4a70::/32, 2804:4a74::/32, 2804:4a78::/32, 2804:4a7c::/32, 2804:4a80::/32, 2804:4a84::/32, 2804:4a88::/32, 2804:4a8c::/32, 2804:4a90::/32, 2804:4a94::/32, 2804:4a98::/32, 2804:4a9c::/32, 2804:4aa0::/32, 2804:4aa4::/32, 2804:4aa8::/32, 2804:4aac::/32, 2804:4ab0::/32, 2804:4ab4::/32, 2804:4ab8::/32, 2804:4abc::/32, 2804:4ac0::/32, 2804:4ac4::/32, 2804:4ac8::/32, 2804:4acc::/32, 2804:4ad0::/32, 2804:4ad4::/32, 2804:4ad8::/32, 2804:4adc::/32, 2804:4ae0::/32, 2804:4ae4::/32, 2804:4ae8::/32, 2804:4aec::/32, 2804:4af0::/32, 2804:4af4::/32, 2804:4af8::/32, 2804:4afc::/32, 2804:4b00::/32, 2804:4b04::/32, 2804:4b08::/32, 2804:4b0c::/32, 2804:4b10::/32, 2804:4b14::/32, 2804:4b18::/32, 2804:4b1c::/32, 2804:4b20::/32, 2804:4b24::/32, 2804:4b28::/32, 2804:4b2c::/32, 2804:4b30::/32, 2804:4b34::/32, 2804:4b38::/32, 2804:4b3c::/32, 2804:4b40::/32, 2804:4b44::/32, 2804:4b48::/32, 2804:4b4c::/32, 2804:4b50::/32, 2804:4b54::/32, 2804:4b58::/32, 2804:4b5c::/32, 2804:4b60::/32, 2804:4b64::/32, 2804:4b68::/32, 2804:4b6c::/32, 2804:4b70::/32, 2804:4b74::/32, 2804:4b78::/32, 2804:4b7c::/32, 2804:4b80::/32, 2804:4b84::/32, 2804:4b88::/32, 2804:4b8c::/32, 2804:4b90::/32, 2804:4b94::/32, 2804:4b98::/32, 2804:4b9c::/32, 2804:4ba0::/32, 2804:4ba4::/32, 2804:4ba8::/32, 2804:4bac::/32, 2804:4bb0::/32, 2804:4bb4::/32, 2804:4bb8::/32, 2804:4bbc::/32, 2804:4bc0::/32, 2804:4bc4::/32, 2804:4bc8::/32, 2804:4bcc::/32, 2804:4bd0::/32, 2804:4bd4::/32, 2804:4bd8::/32, 2804:4bdc::/32, 2804:4be0::/32, 2804:4be4::/32, 2804:4be8::/32, 2804:4bec::/32, 2804:4bf0::/32, 2804:4bf4::/32, 2804:4bf8::/32, 2804:4bfc::/32, 2804:4c00::/32, 2804:4c04::/32, 2804:4c08::/32, 2804:4c0c::/32, 2804:4c10::/32, 2804:4c14::/32, 2804:4c18::/32, 2804:4c1c::/32, 2804:4c20::/32, 2804:4c24::/32, 2804:4c28::/32, 2804:4c2c::/32, 2804:4c30::/32, 2804:4c34::/32, 2804:4c38::/32, 2804:4c3c::/32, 2804:4c40::/32, 2804:4c44::/32, 2804:4c48::/32, 2804:4c4c::/32, 2804:4c50::/32, 2804:4c54::/32, 2804:4c58::/32, 2804:4c5c::/32, 2804:4c60::/32, 2804:4c64::/32, 2804:4c68::/32, 2804:4c6c::/32, 2804:4c70::/32, 2804:4c74::/32, 2804:4c78::/32, 2804:4c7c::/32, 2804:4c80::/32, 2804:4c84::/32, 2804:4c88::/32, 2804:4c8c::/32, 2804:4c90::/32, 2804:4c94::/32, 2804:4c98::/32, 2804:4c9c::/32, 2804:4ca0::/32, 2804:4ca4::/32, 2804:4ca8::/32, 2804:4cac::/32, 2804:4cb0::/32, 2804:4cb4::/32, 2804:4cb8::/32, 2804:4cbc::/32, 2804:4cc0::/32, 2804:4cc4::/32, 2804:4cc8::/32, 2804:4ccc::/32, 2804:4cd0::/32, 2804:4cd4::/32, 2804:4cd8::/32, 2804:4cdc::/32, 2804:4ce0::/32, 2804:4ce4::/32, 2804:4ce8::/32, 2804:4cec::/32, 2804:4cf0::/32, 2804:4cf4::/32, 2804:4cf8::/32, 2804:4cfc::/32, 2804:4d00::/32, 2804:4d04::/32, 2804:4d08::/32, 2804:4d0c::/32, 2804:4d10::/32, 2804:4d14::/32, 2804:4d18::/32, 2804:4d1c::/32, 2804:4d20::/32, 2804:4d24::/32, 2804:4d28::/32, 2804:4d2c::/32, 2804:4d30::/32, 2804:4d34::/32, 2804:4d38::/32, 2804:4d3c::/32, 2804:4d40::/32, 2804:4d44::/32, 2804:4d48::/32, 2804:4d4c::/32, 2804:4d50::/32, 2804:4d54::/32, 2804:4d58::/32, 2804:4d5c::/32, 2804:4d60::/32, 2804:4d64::/32, 2804:4d68::/32, 2804:4d6c::/32, 2804:4d70::/32, 2804:4d74::/32, 2804:4d78::/32, 2804:4d7c::/32, 2804:4d80::/32, 2804:4d84::/32, 2804:4d88::/32, 2804:4d8c::/32, 2804:4d90::/32, 2804:4d94::/32, 2804:4d98::/32, 2804:4d9c::/32, 2804:4da0::/32, 2804:4da4::/32, 2804:4da8::/32, 2804:4dac::/32, 2804:4db0::/32, 2804:4db4::/32, 2804:4db8::/32, 2804:4dbc::/32, 2804:4dc0::/32, 2804:4dc4::/32, 2804:4dc8::/32, 2804:4dcc::/32, 2804:4dd0::/32, 2804:4dd4::/32, 2804:4dd8::/32, 2804:4ddc::/32, 2804:4de0::/32, 2804:4de4::/32, 2804:4de8::/32, 2804:4dec::/32, 2804:4df0::/32, 2804:4df4::/32, 2804:4df8::/32, 2804:4dfc::/32, 2804:4e00::/32, 2804:4e04::/32, 2804:4e08::/32, 2804:4e0c::/32, 2804:4e10::/32, 2804:4e14::/32, 2804:4e18::/32, 2804:4e1c::/32, 2804:4e20::/32, 2804:4e24::/32, 2804:4e28::/32, 2804:4e2c::/32, 2804:4e30::/32, 2804:4e34::/32, 2804:4e38::/32, 2804:4e3c::/32, 2804:4e40::/32, 2804:4e44::/32, 2804:4e48::/32, 2804:4e4c::/32, 2804:4e50::/32, 2804:4e54::/32, 2804:4e58::/32, 2804:4e5c::/32, 2804:4e60::/32, 2804:4e64::/32, 2804:4e68::/32, 2804:4e6c::/32, 2804:4e70::/32, 2804:4e74::/32, 2804:4e78::/32, 2804:4e7c::/32, 2804:4e80::/32, 2804:4e84::/32, 2804:4e88::/32, 2804:4e8c::/32, 2804:4e90::/32, 2804:4e94::/32, 2804:4e98::/32, 2804:4e9c::/32, 2804:4ea0::/32, 2804:4ea4::/32, 2804:4ea8::/32, 2804:4eac::/32, 2804:4eb0::/32, 2804:4eb4::/32, 2804:4eb8::/32, 2804:4ebc::/32, 2804:4ec0::/32, 2804:4ec4::/32, 2804:4ec8::/32, 2804:4ecc::/32, 2804:4ed0::/32, 2804:4ed4::/32, 2804:4ed8::/32, 2804:4edc::/32, 2804:4ee0::/32, 2804:4ee4::/32, 2804:4ee8::/32, 2804:4eec::/32, 2804:4ef0::/32, 2804:4ef4::/32, 2804:4ef8::/32, 2804:4efc::/32, 2804:4f00::/32, 2804:4f04::/32, 2804:4f08::/32, 2804:4f0c::/32, 2804:4f10::/32, 2804:4f14::/32, 2804:4f18::/32, 2804:4f1c::/32, 2804:4f20::/32, 2804:4f24::/32, 2804:4f28::/32, 2804:4f2c::/32, 2804:4f30::/32, 2804:4f34::/32, 2804:4f38::/32, 2804:4f3c::/32, 2804:4f40::/32, 2804:4f44::/32, 2804:4f48::/32, 2804:4f4c::/32, 2804:4f50::/32, 2804:4f54::/32, 2804:4f58::/32, 2804:4f5c::/32, 2804:4f60::/32, 2804:4f64::/32, 2804:4f68::/32, 2804:4f6c::/32, 2804:4f70::/32, 2804:4f74::/32, 2804:4f78::/32, 2804:4f7c::/32, 2804:4f80::/32, 2804:4f84::/32, 2804:4f88::/32, 2804:4f8c::/32, 2804:4f90::/32, 2804:4f94::/32, 2804:4f98::/32, 2804:4f9c::/32, 2804:4fa0::/32, 2804:4fa4::/32, 2804:4fa8::/32, 2804:4fac::/32, 2804:4fb0::/32, 2804:4fb4::/32, 2804:4fb8::/32, 2804:4fbc::/32, 2804:4fc0::/32, 2804:4fc4::/32, 2804:4fc8::/32, 2804:4fcc::/32, 2804:4fd0::/32, 2804:4fd4::/32, 2804:4fd8::/32, 2804:4fdc::/32, 2804:4fe0::/32, 2804:4fe4::/32, 2804:4fe8::/32, 2804:4fec::/32, 2804:4ff0::/32, 2804:4ff4::/32, 2804:4ff8::/32, 2804:4ffc::/32, 2804:5000::/32, 2804:5004::/32, 2804:5008::/32, 2804:500c::/32, 2804:5010::/32, 2804:5014::/32, 2804:5018::/32, 2804:501c::/32, 2804:5020::/32, 2804:5024::/32, 2804:5028::/32, 2804:502c::/32, 2804:5030::/32, 2804:5034::/32, 2804:5038::/32, 2804:503c::/32, 2804:5040::/32, 2804:5044::/32, 2804:5048::/32, 2804:504c::/32, 2804:5050::/32, 2804:5054::/32, 2804:5058::/32, 2804:505c::/32, 2804:5060::/32, 2804:5064::/32, 2804:5068::/32, 2804:506c::/32, 2804:5070::/32, 2804:5074::/32, 2804:5078::/32, 2804:507c::/32, 2804:5080::/32, 2804:5084::/32, 2804:5088::/32, 2804:508c::/32, 2804:5090::/32, 2804:5094::/32, 2804:5098::/32, 2804:509c::/32, 2804:50a0::/32, 2804:50a4::/32, 2804:50a8::/32, 2804:50ac::/32, 2804:50b0::/32, 2804:50b4::/32, 2804:50b8::/32, 2804:50bc::/32, 2804:50c0::/32, 2804:50c4::/32, 2804:50c8::/32, 2804:50cc::/32, 2804:50d0::/32, 2804:50d4::/32, 2804:50d8::/32, 2804:50dc::/32, 2804:50e0::/32, 2804:50e4::/32, 2804:50e8::/32, 2804:50ec::/32, 2804:50f0::/32, 2804:50f4::/32, 2804:50f8::/32, 2804:50fc::/32, 2804:5100::/32, 2804:5104::/32, 2804:5108::/32, 2804:510c::/32, 2804:5110::/32, 2804:5114::/32, 2804:5118::/32, 2804:511c::/32, 2804:5120::/32, 2804:5124::/32, 2804:5128::/32, 2804:512c::/32, 2804:5130::/32, 2804:5134::/32, 2804:5138::/32, 2804:513c::/32, 2804:5140::/32, 2804:5144::/32, 2804:5148::/32, 2804:514c::/32, 2804:5150::/32, 2804:5154::/32, 2804:5158::/32, 2804:515c::/32, 2804:5160::/32, 2804:5164::/32, 2804:5168::/32, 2804:516c::/32, 2804:5170::/32, 2804:5174::/32, 2804:5178::/32, 2804:517c::/32, 2804:5180::/32, 2804:5184::/32, 2804:5188::/32, 2804:518c::/32, 2804:5190::/32, 2804:5194::/32, 2804:5198::/32, 2804:519c::/32, 2804:51a0::/32, 2804:51a4::/32, 2804:51a8::/32, 2804:51ac::/32, 2804:51b0::/32, 2804:51b4::/32, 2804:51b8::/32, 2804:51bc::/32, 2804:51c0::/32, 2804:51c4::/32, 2804:51c8::/32, 2804:51cc::/32, 2804:51d0::/32, 2804:51d4::/32, 2804:51d8::/32, 2804:51dc::/32, 2804:51e0::/32, 2804:51e4::/32, 2804:51e8::/32, 2804:51ec::/32, 2804:51f0::/32, 2804:51f4::/32, 2804:51f8::/32, 2804:51fc::/32, 2804:5200::/32, 2804:5204::/32, 2804:5208::/32, 2804:520c::/32, 2804:5210::/32, 2804:5214::/32, 2804:5218::/32, 2804:521c::/32, 2804:5220::/32, 2804:5224::/32, 2804:5228::/32, 2804:522c::/32, 2804:5230::/32, 2804:5234::/32, 2804:5238::/32, 2804:523c::/32, 2804:5240::/32, 2804:5244::/32, 2804:5248::/32, 2804:524c::/32, 2804:5250::/32, 2804:5254::/32, 2804:5258::/32, 2804:525c::/32, 2804:5260::/32, 2804:5264::/32, 2804:5268::/32, 2804:526c::/32, 2804:5270::/32, 2804:5274::/32, 2804:5278::/32, 2804:527c::/32, 2804:5280::/32, 2804:5284::/32, 2804:5288::/32, 2804:528c::/32, 2804:5290::/32, 2804:5294::/32, 2804:5298::/32, 2804:529c::/32, 2804:52a0::/32, 2804:52a4::/32, 2804:52a8::/32, 2804:52ac::/32, 2804:52b0::/32, 2804:52b4::/32, 2804:52b8::/32, 2804:52bc::/32, 2804:52c0::/32, 2804:52c4::/32, 2804:52c8::/32, 2804:52cc::/32, 2804:52d0::/32, 2804:52d4::/32, 2804:52d8::/32, 2804:52dc::/32, 2804:52e0::/32, 2804:52e4::/32, 2804:52e8::/32, 2804:52ec::/32, 2804:52f0::/32, 2804:52f4::/32, 2804:52f8::/32, 2804:52fc::/32, 2804:5300::/32, 2804:5304::/32, 2804:5308::/32, 2804:530c::/32, 2804:5310::/32, 2804:5314::/32, 2804:5318::/32, 2804:531c::/32, 2804:5320::/32, 2804:5324::/32, 2804:5328::/32, 2804:532c::/32, 2804:5330::/32, 2804:5334::/32, 2804:5338::/32, 2804:533c::/32, 2804:5340::/32, 2804:5344::/32, 2804:5348::/32, 2804:534c::/32, 2804:5350::/32, 2804:5354::/32, 2804:5358::/32, 2804:535c::/32, 2804:5360::/32, 2804:5364::/32, 2804:5368::/32, 2804:536c::/32, 2804:5370::/32, 2804:5374::/32, 2804:5378::/32, 2804:537c::/32, 2804:5380::/32, 2804:5384::/32, 2804:5388::/32, 2804:538c::/32, 2804:5390::/32, 2804:5394::/32, 2804:5398::/32, 2804:539c::/32, 2804:53a0::/32, 2804:53a4::/32, 2804:53a8::/32, 2804:53ac::/32, 2804:53b0::/32, 2804:53b4::/32, 2804:53b8::/32, 2804:53bc::/32, 2804:53c0::/32, 2804:53c4::/32, 2804:53c8::/32, 2804:53cc::/32, 2804:53d0::/32, 2804:53d4::/32, 2804:53d8::/32, 2804:53dc::/32, 2804:53e0::/32, 2804:53e4::/32, 2804:53e8::/32, 2804:53ec::/32, 2804:53f0::/32, 2804:53f4::/32, 2804:53f8::/32, 2804:53fc::/32, 2804:5400::/32, 2804:5404::/32, 2804:5408::/32, 2804:540c::/32, 2804:5410::/32, 2804:5414::/32, 2804:5418::/32, 2804:541c::/32, 2804:5420::/32, 2804:5424::/32, 2804:5428::/32, 2804:542c::/32, 2804:5430::/32, 2804:5434::/32, 2804:5438::/32, 2804:543c::/32, 2804:5440::/32, 2804:5444::/32, 2804:5448::/32, 2804:544c::/32, 2804:5450::/32, 2804:5454::/32, 2804:5458::/32, 2804:545c::/32, 2804:5460::/32, 2804:5464::/32, 2804:5468::/32, 2804:546c::/32, 2804:5470::/32, 2804:5474::/32, 2804:5478::/32, 2804:547c::/32, 2804:5480::/32, 2804:5484::/32, 2804:5488::/32, 2804:548c::/32, 2804:5490::/32, 2804:5494::/32, 2804:5498::/32, 2804:549c::/32, 2804:54a0::/32, 2804:54a4::/32, 2804:54a8::/32, 2804:54ac::/32, 2804:54b0::/32, 2804:54b4::/32, 2804:54b8::/32, 2804:54bc::/32, 2804:54c0::/32, 2804:54c4::/32, 2804:54c8::/32, 2804:54cc::/32, 2804:54d0::/32, 2804:54d4::/32, 2804:54d8::/32, 2804:54dc::/32, 2804:54e0::/32, 2804:54e4::/32, 2804:54e8::/32, 2804:54ec::/32, 2804:54f0::/32, 2804:54f4::/32, 2804:54f8::/32, 2804:54fc::/32, 2804:5500::/32, 2804:5504::/32, 2804:5508::/32, 2804:550c::/32, 2804:5510::/32, 2804:5514::/32, 2804:5518::/32, 2804:551c::/32, 2804:5520::/32, 2804:5524::/32, 2804:5528::/32, 2804:552c::/32, 2804:5530::/32, 2804:5534::/32, 2804:5538::/32, 2804:553c::/32, 2804:5540::/32, 2804:5544::/32, 2804:5548::/32, 2804:554c::/32, 2804:5550::/32, 2804:5554::/32, 2804:5558::/32, 2804:555c::/32, 2804:5560::/32, 2804:5564::/32, 2804:5568::/32, 2804:556c::/32, 2804:5570::/32, 2804:5574::/32, 2804:5578::/32, 2804:557c::/32, 2804:5580::/32, 2804:5584::/32, 2804:5588::/32, 2804:558c::/32, 2804:5590::/32, 2804:5594::/32, 2804:5598::/32, 2804:559c::/32, 2804:55a0::/32, 2804:55a4::/32, 2804:55a8::/32, 2804:55ac::/32, 2804:55b0::/32, 2804:55b4::/32, 2804:55b8::/32, 2804:55bc::/32, 2804:55c0::/32, 2804:55c4::/32, 2804:55c8::/32, 2804:55cc::/32, 2804:55d0::/32, 2804:55d4::/32, 2804:55d8::/32, 2804:55dc::/32, 2804:55e0::/32, 2804:55e4::/32, 2804:55e8::/32, 2804:55ec::/32, 2804:55f0::/32, 2804:55f4::/32, 2804:55f8::/32, 2804:55fc::/32, 2804:5600::/32, 2804:5604::/32, 2804:5608::/32, 2804:560c::/32, 2804:5610::/32, 2804:5614::/32, 2804:5618::/32, 2804:561c::/32, 2804:5620::/32, 2804:5624::/32, 2804:5628::/32, 2804:562c::/32, 2804:5630::/32, 2804:5634::/32, 2804:5638::/32, 2804:563c::/32, 2804:5640::/32, 2804:5644::/32, 2804:5648::/32, 2804:564c::/32, 2804:5650::/32, 2804:5654::/32, 2804:5658::/32, 2804:565c::/32, 2804:5660::/32, 2804:5664::/32, 2804:5668::/32, 2804:566c::/32, 2804:5670::/32, 2804:5674::/32, 2804:5678::/32, 2804:567c::/32, 2804:5680::/32, 2804:5684::/32, 2804:5688::/32, 2804:568c::/32, 2804:5690::/32, 2804:5694::/32, 2804:5698::/32, 2804:569c::/32, 2804:56a0::/32, 2804:56a4::/32, 2804:56a8::/32, 2804:56ac::/32, 2804:56b0::/32, 2804:56b4::/32, 2804:56b8::/32, 2804:56bc::/32, 2804:56c0::/32, 2804:56c4::/32, 2804:56c8::/32, 2804:56cc::/32, 2804:56d0::/32, 2804:56d4::/32, 2804:56d8::/32, 2804:56dc::/32, 2804:56e0::/32, 2804:56e4::/32, 2804:56e8::/32, 2804:56ec::/32, 2804:56f0::/32, 2804:56f4::/32, 2804:56f8::/32, 2804:56fc::/32, 2804:5700::/32, 2804:5704::/32, 2804:5708::/32, 2804:570c::/32, 2804:5710::/32, 2804:5714::/32, 2804:5718::/32, 2804:571c::/32, 2804:5720::/32, 2804:5724::/32, 2804:5728::/32, 2804:572c::/32, 2804:5730::/32, 2804:5734::/32, 2804:5738::/32, 2804:573c::/32, 2804:5740::/32, 2804:5744::/32, 2804:5748::/32, 2804:574c::/32, 2804:5750::/32, 2804:5754::/32, 2804:5758::/32, 2804:575c::/32, 2804:5760::/32, 2804:5764::/32, 2804:5768::/32, 2804:576c::/32, 2804:5770::/32, 2804:5774::/32, 2804:5778::/32, 2804:577c::/32, 2804:5780::/32, 2804:5784::/32, 2804:5788::/32, 2804:578c::/32, 2804:5790::/32, 2804:5794::/32, 2804:5798::/32, 2804:579c::/32, 2804:57a0::/32, 2804:57a4::/32, 2804:57a8::/32, 2804:57ac::/32, 2804:57b0::/32, 2804:57b4::/32, 2804:57b8::/32, 2804:57bc::/32, 2804:57c0::/32, 2804:57c4::/32, 2804:57c8::/32, 2804:57cc::/32, 2804:57d0::/32, 2804:57d4::/32, 2804:57d8::/32, 2804:57dc::/32, 2804:57e0::/32, 2804:57e4::/32, 2804:57e8::/32, 2804:57ec::/32, 2804:57f0::/32, 2804:57f4::/32, 2804:57f8::/32, 2804:57fc::/32, 2804:5800::/32, 2804:5804::/32, 2804:5808::/32, 2804:580c::/32, 2804:5810::/32, 2804:5814::/32, 2804:5818::/32, 2804:581c::/32, 2804:5820::/32, 2804:5824::/32, 2804:5828::/32, 2804:582c::/32, 2804:5830::/32, 2804:5834::/32, 2804:5838::/32, 2804:583c::/32, 2804:5840::/32, 2804:5844::/32, 2804:5848::/32, 2804:584c::/32, 2804:5850::/32, 2804:5854::/32, 2804:5858::/32, 2804:585c::/32, 2804:5860::/32, 2804:5864::/32, 2804:5868::/32, 2804:586c::/32, 2804:5870::/32, 2804:5874::/32, 2804:5878::/32, 2804:587c::/32, 2804:5880::/32, 2804:5884::/32, 2804:5888::/32, 2804:588c::/32, 2804:5890::/32, 2804:5894::/32, 2804:5898::/32, 2804:589c::/32, 2804:58a0::/32, 2804:58a4::/32, 2804:58a8::/32, 2804:58ac::/32, 2804:58b0::/32, 2804:58b4::/32, 2804:58b8::/32, 2804:58bc::/32, 2804:58c0::/32, 2804:58c4::/32, 2804:58c8::/32, 2804:58cc::/32, 2804:58d0::/32, 2804:58d4::/32, 2804:58d8::/32, 2804:58dc::/32, 2804:58e0::/32, 2804:58e4::/32, 2804:58e8::/32, 2804:58ec::/32, 2804:58f0::/32, 2804:58f4::/32, 2804:58f8::/32, 2804:58fc::/32, 2804:5900::/32, 2804:5904::/32, 2804:5908::/32, 2804:590c::/32, 2804:5910::/32, 2804:5914::/32, 2804:5918::/32, 2804:591c::/32, 2804:5920::/32, 2804:5924::/32, 2804:5928::/32, 2804:592c::/32, 2804:5930::/32, 2804:5934::/32, 2804:5938::/32, 2804:593c::/32, 2804:5940::/32, 2804:5944::/32, 2804:5948::/32, 2804:594c::/32, 2804:5950::/32, 2804:5954::/32, 2804:5958::/32, 2804:595c::/32, 2804:5960::/32, 2804:5964::/32, 2804:5968::/32, 2804:596c::/32, 2804:5970::/32, 2804:5974::/32, 2804:5978::/32, 2804:597c::/32, 2804:5980::/32, 2804:5984::/32, 2804:5988::/32, 2804:598c::/32, 2804:5990::/32, 2804:5994::/32, 2804:5998::/32, 2804:599c::/32, 2804:59a0::/32, 2804:59a4::/32, 2804:59a8::/32, 2804:59ac::/32, 2804:59b0::/32, 2804:59b4::/32, 2804:59b8::/32, 2804:59bc::/32, 2804:59c0::/32, 2804:59c8::/32, 2804:59cc::/32, 2804:59d0::/32, 2804:59d4::/32, 2804:59d8::/32, 2804:59dc::/32, 2804:59e0::/32, 2804:59e4::/32, 2804:59e8::/32, 2804:59ec::/32, 2804:59f0::/32, 2804:59f4::/32, 2804:59f8::/32, 2804:59fc::/32, 2804:5a00::/32, 2804:5a04::/32, 2804:5a08::/32, 2804:5a0c::/32, 2804:5a10::/32, 2804:5a14::/32, 2804:5a18::/32, 2804:5a1c::/32, 2804:5a20::/32, 2804:5a24::/32, 2804:5a28::/32, 2804:5a2c::/32, 2804:5a30::/32, 2804:5a34::/32, 2804:5a38::/32, 2804:5a3c::/32, 2804:5a40::/32, 2804:5a44::/32, 2804:5a48::/32, 2804:5a4c::/32, 2804:5a50::/32, 2804:5a54::/32, 2804:5a58::/32, 2804:5a5c::/32, 2804:5a60::/32, 2804:5a64::/32, 2804:5a68::/32, 2804:5a6c::/32, 2804:5a70::/32, 2804:5a74::/32, 2804:5a78::/32, 2804:5a7c::/32, 2804:5a80::/32, 2804:5a84::/32, 2804:5a88::/32, 2804:5a8c::/32, 2804:5a90::/32, 2804:5a94::/32, 2804:5a98::/32, 2804:5a9c::/32, 2804:5aa0::/32, 2804:5aa4::/32, 2804:5aa8::/32, 2804:5aac::/32, 2804:5ab0::/32, 2804:5ab4::/32, 2804:5ab8::/32, 2804:5abc::/32, 2804:5ac0::/32, 2804:5ac4::/32, 2804:5ac8::/32, 2804:5acc::/32, 2804:5ad0::/32, 2804:5ad4::/32, 2804:5ad8::/32, 2804:5adc::/32, 2804:5ae0::/32, 2804:5ae4::/32, 2804:5ae8::/32, 2804:5aec::/32, 2804:5af0::/32, 2804:5af4::/32, 2804:5af8::/32, 2804:5afc::/32, 2804:5b00::/32, 2804:5b04::/32, 2804:5b08::/32, 2804:5b0c::/32, 2804:5b10::/32, 2804:5b14::/32, 2804:5b18::/32, 2804:5b1c::/32, 2804:5b20::/32, 2804:5b24::/32, 2804:5b28::/32, 2804:5b2c::/32, 2804:5b30::/32, 2804:5b34::/32, 2804:5b38::/32, 2804:5b3c::/32, 2804:5b40::/32, 2804:5b44::/32, 2804:5b48::/32, 2804:5b4c::/32, 2804:5b50::/32, 2804:5b54::/32, 2804:5b58::/32, 2804:5b5c::/32, 2804:5b60::/32, 2804:5b64::/32, 2804:5b68::/32, 2804:5b6c::/32, 2804:5b70::/32, 2804:5b74::/32, 2804:5b78::/32, 2804:5b7c::/32, 2804:5b80::/32, 2804:5b84::/32, 2804:5b88::/32, 2804:5b8c::/32, 2804:5b90::/32, 2804:5b94::/32, 2804:5b98::/32, 2804:5b9c::/32, 2804:5ba0::/32, 2804:5ba4::/32, 2804:5ba8::/32, 2804:5bac::/32, 2804:5bb0::/32, 2804:5bb4::/32, 2804:5bb8::/32, 2804:5bbc::/32, 2804:5bc0::/32, 2804:5bc4::/32, 2804:5bc8::/32, 2804:5bcc::/32, 2804:5bd0::/32, 2804:5bd4::/32, 2804:5bd8::/32, 2804:5bdc::/32, 2804:5be0::/32, 2804:5be4::/32, 2804:5be8::/32, 2804:5bec::/32, 2804:5bf0::/32, 2804:5bf4::/32, 2804:5bf8::/32, 2804:5bfc::/32, 2804:5c00::/32, 2804:5c04::/32, 2804:5c08::/32, 2804:5c0c::/32, 2804:5c10::/32, 2804:5c14::/32, 2804:5c18::/32, 2804:5c1c::/32, 2804:5c20::/32, 2804:5c24::/32, 2804:5c28::/32, 2804:5c2c::/32, 2804:5c30::/32, 2804:5c34::/32, 2804:5c38::/32, 2804:5c3c::/32, 2804:5c40::/32, 2804:5c44::/32, 2804:5c48::/32, 2804:5c4c::/32, 2804:5c50::/32, 2804:5c54::/32, 2804:5c58::/32, 2804:5c5c::/32, 2804:5c60::/32, 2804:5c64::/32, 2804:5c68::/32, 2804:5c6c::/32, 2804:5c70::/32, 2804:5c74::/32, 2804:5c78::/32, 2804:5c7c::/32, 2804:5c80::/32, 2804:5c84::/32, 2804:5c88::/32, 2804:5c8c::/32, 2804:5c90::/32, 2804:5c94::/32, 2804:5c98::/32, 2804:5c9c::/32, 2804:5ca0::/32, 2804:5ca4::/32, 2804:5ca8::/32, 2804:5cac::/32, 2804:5cb0::/32, 2804:5cb4::/32, 2804:5cb8::/32, 2804:5cbc::/32, 2804:5cc0::/32, 2804:5cc4::/32, 2804:5cc8::/32, 2804:5ccc::/32, 2804:5cd0::/32, 2804:5cd4::/32, 2804:5cd8::/32, 2804:5cdc::/32, 2804:5ce0::/32, 2804:5ce4::/32, 2804:5ce8::/32, 2804:5cec::/32, 2804:5cf0::/32, 2804:5cf4::/32, 2804:5cf8::/32, 2804:5cfc::/32, 2804:5d00::/32, 2804:5d04::/32, 2804:5d08::/32, 2804:5d0c::/32, 2804:5d10::/32, 2804:5d14::/32, 2804:5d18::/32, 2804:5d1c::/32, 2804:5d20::/32, 2804:5d24::/32, 2804:5d28::/32, 2804:5d2c::/32, 2804:5d30::/32, 2804:5d34::/32, 2804:5d38::/32, 2804:5d3c::/32, 2804:5d40::/32, 2804:5d44::/32, 2804:5d48::/32, 2804:5d4c::/32, 2804:5d50::/32, 2804:5d54::/32, 2804:5d58::/32, 2804:5d5c::/32, 2804:5d60::/32, 2804:5d64::/32, 2804:5d68::/32, 2804:5d6c::/32, 2804:5d70::/32, 2804:5d74::/32, 2804:5d78::/32, 2804:5d7c::/32, 2804:5d80::/32, 2804:5d84::/32, 2804:5d88::/32, 2804:5d8c::/32, 2804:5d90::/32, 2804:5d94::/32, 2804:5d98::/32, 2804:5d9c::/32, 2804:5da0::/32, 2804:5da4::/32, 2804:5da8::/32, 2804:5dac::/32, 2804:5db0::/32, 2804:5db4::/32, 2804:5db8::/32, 2804:5dbc::/32, 2804:5dc0::/32, 2804:5dc4::/32, 2804:5dc8::/32, 2804:5dcc::/32, 2804:5dd0::/32, 2804:5dd4::/32, 2804:5dd8::/32, 2804:5ddc::/32, 2804:5de0::/32, 2804:5de4::/32, 2804:5de8::/32, 2804:5dec::/32, 2804:5df0::/32, 2804:5df4::/32, 2804:5df8::/32, 2804:5dfc::/32, 2804:5e00::/32, 2804:5e04::/32, 2804:5e08::/32, 2804:5e0c::/32, 2804:5e10::/32, 2804:5e14::/32, 2804:5e18::/32, 2804:5e1c::/32, 2804:5e20::/32, 2804:5e24::/32, 2804:5e28::/32, 2804:5e2c::/32, 2804:5e30::/32, 2804:5e34::/32, 2804:5e38::/32, 2804:5e3c::/32, 2804:5e40::/32, 2804:5e44::/32, 2804:5e48::/32, 2804:5e4c::/32, 2804:5e50::/32, 2804:5e54::/32, 2804:5e58::/32, 2804:5e5c::/32, 2804:5e60::/32, 2804:5e64::/32, 2804:5e68::/32, 2804:5e6c::/32, 2804:5e70::/32, 2804:5e74::/32, 2804:5e78::/32, 2804:5e7c::/32, 2804:5e80::/32, 2804:5e84::/32, 2804:5e88::/32, 2804:5e8c::/32, 2804:5e90::/32, 2804:5e94::/32, 2804:5e98::/32, 2804:5e9c::/32, 2804:5ea0::/32, 2804:5ea4::/32, 2804:5ea8::/32, 2804:5eac::/32, 2804:5eb0::/32, 2804:5eb4::/32, 2804:5eb8::/32, 2804:5ebc::/32, 2804:5ec0::/32, 2804:5ec4::/32, 2804:5ec8::/32, 2804:5ecc::/32, 2804:5ed0::/32, 2804:5ed4::/32, 2804:5ed8::/32, 2804:5edc::/32, 2804:5ee0::/32, 2804:5ee4::/32, 2804:5ee8::/32, 2804:5eec::/32, 2804:5ef0::/32, 2804:5ef4::/32, 2804:5ef8::/32, 2804:5efc::/32, 2804:5f00::/32, 2804:5f04::/32, 2804:5f08::/32, 2804:5f0c::/32, 2804:5f10::/32, 2804:5f14::/32, 2804:5f18::/32, 2804:5f1c::/32, 2804:5f20::/32, 2804:5f24::/32, 2804:5f28::/32, 2804:5f2c::/32, 2804:5f30::/32, 2804:5f34::/32, 2804:5f38::/32, 2804:5f3c::/32, 2804:5f40::/32, 2804:5f44::/32, 2804:5f48::/32, 2804:5f4c::/32, 2804:5f50::/32, 2804:5f54::/32, 2804:5f58::/32, 2804:5f5c::/32, 2804:5f60::/32, 2804:5f64::/32, 2804:5f68::/32, 2804:5f6c::/32, 2804:5f70::/32, 2804:5f74::/32, 2804:5f78::/32, 2804:5f7c::/32, 2804:5f80::/32, 2804:5f84::/32, 2804:5f88::/32, 2804:5f8c::/32, 2804:5f90::/32, 2804:5f94::/32, 2804:5f98::/32, 2804:5f9c::/32, 2804:5fa0::/32, 2804:5fa4::/32, 2804:5fa8::/32, 2804:5fac::/32, 2804:5fb0::/32, 2804:5fb4::/32, 2804:5fb8::/32, 2804:5fbc::/32, 2804:5fc0::/32, 2804:5fc4::/32, 2804:5fc8::/32, 2804:5fcc::/32, 2804:5fd0::/32, 2804:5fd4::/32, 2804:5fd8::/32, 2804:5fdc::/32, 2804:5fe0::/32, 2804:5fe4::/32, 2804:5fe8::/32, 2804:5fec::/32, 2804:5ff0::/32, 2804:5ff4::/32, 2804:5ff8::/32, 2804:5ffc::/32, 2804:6000::/32, 2804:6004::/32, 2804:6008::/32, 2804:600c::/32, 2804:6010::/32, 2804:6014::/32, 2804:6018::/32, 2804:601c::/32, 2804:6020::/32, 2804:6024::/32, 2804:6028::/32, 2804:602c::/32, 2804:6030::/32, 2804:6034::/32, 2804:6038::/32, 2804:603c::/32, 2804:6040::/32, 2804:6044::/32, 2804:6048::/32, 2804:604c::/32, 2804:6050::/32, 2804:6054::/32, 2804:6058::/32, 2804:605c::/32, 2804:6060::/32, 2804:6064::/32, 2804:6068::/32, 2804:606c::/32, 2804:6070::/32, 2804:6074::/32, 2804:6078::/32, 2804:607c::/32, 2804:6080::/32, 2804:6084::/32, 2804:6088::/32, 2804:608c::/32, 2804:6090::/32, 2804:6094::/32, 2804:6098::/32, 2804:609c::/32, 2804:60a0::/32, 2804:60a4::/32, 2804:60a8::/32, 2804:60ac::/32, 2804:60b0::/32, 2804:60b4::/32, 2804:60b8::/32, 2804:60bc::/32, 2804:60c0::/32, 2804:60c4::/32, 2804:60c8::/32, 2804:60cc::/32, 2804:60d0::/32, 2804:60d4::/32, 2804:60d8::/32, 2804:60dc::/32, 2804:60e0::/32, 2804:60e4::/32, 2804:60e8::/32, 2804:60ec::/32, 2804:60f0::/32, 2804:60f4::/32, 2804:60f8::/32, 2804:60fc::/32, 2804:6100::/32, 2804:6104::/32, 2804:6108::/32, 2804:610c::/32, 2804:6110::/32, 2804:6114::/32, 2804:6118::/32, 2804:611c::/32, 2804:6120::/32, 2804:6124::/32, 2804:6128::/32, 2804:612c::/32, 2804:6130::/32, 2804:6134::/32, 2804:6138::/32, 2804:613c::/32, 2804:6140::/32, 2804:6144::/32, 2804:6148::/32, 2804:614c::/32, 2804:6150::/32, 2804:6154::/32, 2804:6158::/32, 2804:615c::/32, 2804:6160::/32, 2804:6164::/32, 2804:6168::/32, 2804:616c::/32, 2804:6170::/32, 2804:6174::/32, 2804:6178::/32, 2804:617c::/32, 2804:6180::/32, 2804:6184::/32, 2804:6188::/32, 2804:618c::/32, 2804:6190::/32, 2804:6194::/32, 2804:6198::/32, 2804:619c::/32, 2804:61a0::/32, 2804:61a4::/32, 2804:61a8::/32, 2804:61ac::/32, 2804:61b0::/32, 2804:61b4::/32, 2804:61b8::/32, 2804:61bc::/32, 2804:61c0::/32, 2804:61c4::/32, 2804:61c8::/32, 2804:61cc::/32, 2804:61d0::/32, 2804:61d4::/32, 2804:61d8::/32, 2804:61dc::/32, 2804:61e0::/32, 2804:61e4::/32, 2804:61e8::/32, 2804:61ec::/32, 2804:61f0::/32, 2804:61f4::/32, 2804:61f8::/32, 2804:61fc::/32, 2804:6200::/32, 2804:6204::/32, 2804:6208::/32, 2804:620c::/32, 2804:6210::/32, 2804:6214::/32, 2804:6218::/32, 2804:621c::/32, 2804:6220::/32, 2804:6224::/32, 2804:6228::/32, 2804:622c::/32, 2804:6230::/32, 2804:6234::/32, 2804:6238::/32, 2804:623c::/32, 2804:6240::/32, 2804:6244::/32, 2804:6248::/32, 2804:624c::/32, 2804:6250::/32, 2804:6254::/32, 2804:6258::/32, 2804:625c::/32, 2804:6260::/32, 2804:6264::/32, 2804:6268::/32, 2804:626c::/32, 2804:6270::/32, 2804:6274::/32, 2804:6278::/32, 2804:627c::/32, 2804:6280::/32, 2804:6284::/32, 2804:6288::/32, 2804:628c::/32, 2804:6290::/32, 2804:6294::/32, 2804:6298::/32, 2804:629c::/32, 2804:62a0::/32, 2804:62a4::/32, 2804:62a8::/32, 2804:62ac::/32, 2804:62b0::/32, 2804:62b4::/32, 2804:62b8::/32, 2804:62bc::/32, 2804:62c0::/32, 2804:62c4::/32, 2804:62c8::/32, 2804:62cc::/32, 2804:62d0::/32, 2804:62d4::/32, 2804:62d8::/32, 2804:62dc::/32, 2804:62e0::/32, 2804:62e4::/32, 2804:62e8::/32, 2804:62ec::/32, 2804:62f0::/32, 2804:62f4::/32, 2804:62f8::/32, 2804:62fc::/32, 2804:6300::/32, 2804:6304::/32, 2804:6308::/32, 2804:630c::/32, 2804:6310::/32, 2804:6314::/32, 2804:6318::/32, 2804:631c::/32, 2804:6320::/32, 2804:6324::/32, 2804:6328::/32, 2804:632c::/32, 2804:6330::/32, 2804:6334::/32, 2804:6338::/32, 2804:633c::/32, 2804:6340::/32, 2804:6344::/32, 2804:6348::/32, 2804:634c::/32, 2804:6350::/32, 2804:6354::/32, 2804:6358::/32, 2804:635c::/32, 2804:6360::/32, 2804:6364::/32, 2804:6368::/32, 2804:636c::/32, 2804:6370::/32, 2804:6374::/32, 2804:6378::/32, 2804:637c::/32, 2804:6380::/32, 2804:6384::/32, 2804:6388::/32, 2804:638c::/32, 2804:6390::/32, 2804:6394::/32, 2804:6398::/32, 2804:639c::/32, 2804:63a0::/32, 2804:63a4::/32, 2804:63a8::/32, 2804:63ac::/32, 2804:63b0::/32, 2804:63b4::/32, 2804:63b8::/32, 2804:63bc::/32, 2804:63c0::/32, 2804:63c4::/32, 2804:63c8::/32, 2804:63cc::/32, 2804:63d0::/32, 2804:63d4::/32, 2804:63d8::/32, 2804:63dc::/32, 2804:63e0::/32, 2804:63e4::/32, 2804:63e8::/32, 2804:63ec::/32, 2804:63f0::/32, 2804:63f4::/32, 2804:63f8::/32, 2804:63fc::/32, 2804:6400::/32, 2804:6404::/32, 2804:6408::/32, 2804:640c::/32, 2804:6410::/32, 2804:6414::/32, 2804:6418::/32, 2804:641c::/32, 2804:6420::/32, 2804:6424::/32, 2804:6428::/32, 2804:642c::/32, 2804:6430::/32, 2804:6434::/32, 2804:6438::/32, 2804:643c::/32, 2804:6440::/32, 2804:6444::/32, 2804:6448::/32, 2804:644c::/32, 2804:6450::/32, 2804:6454::/32, 2804:6458::/32, 2804:645c::/32, 2804:6460::/32, 2804:6464::/32, 2804:6468::/32, 2804:646c::/32, 2804:6470::/32, 2804:6474::/32, 2804:6478::/32, 2804:647c::/32, 2804:6480::/32, 2804:6484::/32, 2804:6488::/32, 2804:648c::/32, 2804:6490::/32, 2804:6494::/32, 2804:6498::/32, 2804:649c::/32, 2804:64a0::/32, 2804:64a4::/32, 2804:64a8::/32, 2804:64ac::/32, 2804:64b0::/32, 2804:64b4::/32, 2804:64b8::/32, 2804:64bc::/32, 2804:64c0::/32, 2804:64c4::/32, 2804:64c8::/32, 2804:64cc::/32, 2804:64d0::/32, 2804:64d4::/32, 2804:64d8::/32, 2804:64dc::/32, 2804:64e0::/32, 2804:64e4::/32, 2804:64e8::/32, 2804:64ec::/32, 2804:64f0::/32, 2804:64f4::/32, 2804:64f8::/32, 2804:64fc::/32, 2804:6500::/32, 2804:6504::/32, 2804:6508::/32, 2804:650c::/32, 2804:6510::/32, 2804:6514::/32, 2804:6518::/32, 2804:651c::/32, 2804:6520::/32, 2804:6524::/32, 2804:6528::/32, 2804:652c::/32, 2804:6530::/32, 2804:6534::/32, 2804:6538::/32, 2804:653c::/32, 2804:6540::/32, 2804:6544::/32, 2804:6548::/32, 2804:654c::/32, 2804:6550::/32, 2804:6554::/32, 2804:6558::/32, 2804:655c::/32, 2804:6560::/32, 2804:6564::/32, 2804:6568::/32, 2804:656c::/32, 2804:6570::/32, 2804:6574::/32, 2804:6578::/32, 2804:657c::/32, 2804:6580::/32, 2804:6584::/32, 2804:6588::/32, 2804:658c::/32, 2804:6590::/32, 2804:6594::/32, 2804:6598::/32, 2804:659c::/32, 2804:65a0::/32, 2804:65a4::/32, 2804:65a8::/32, 2804:65ac::/32, 2804:65b0::/32, 2804:65b4::/32, 2804:65b8::/32, 2804:65bc::/32, 2804:65c0::/32, 2804:65c4::/32, 2804:65c8::/32, 2804:65cc::/32, 2804:65d0::/32, 2804:65d4::/32, 2804:65d8::/32, 2804:65dc::/32, 2804:65e0::/32, 2804:65e4::/32, 2804:65e8::/32, 2804:65ec::/32, 2804:65f0::/32, 2804:65f4::/32, 2804:65f8::/32, 2804:65fc::/32, 2804:6600::/32, 2804:6604::/32, 2804:6608::/32, 2804:660c::/32, 2804:6610::/32, 2804:6614::/32, 2804:6618::/32, 2804:661c::/32, 2804:6620::/32, 2804:6624::/32, 2804:6628::/32, 2804:662c::/32, 2804:6630::/32, 2804:6634::/32, 2804:6638::/32, 2804:663c::/32, 2804:6640::/32, 2804:6644::/32, 2804:6648::/32, 2804:664c::/32, 2804:6650::/32, 2804:6654::/32, 2804:6658::/32, 2804:665c::/32, 2804:6660::/32, 2804:6664::/32, 2804:6668::/32, 2804:666c::/32, 2804:6670::/32, 2804:6674::/32, 2804:6678::/32, 2804:667c::/32, 2804:6680::/32, 2804:6684::/32, 2804:6688::/32, 2804:668c::/32, 2804:6690::/32, 2804:6694::/32, 2804:6698::/32, 2804:669c::/32, 2804:66a0::/32, 2804:66a4::/32, 2804:66a8::/32, 2804:66ac::/32, 2804:66b0::/32, 2804:66b4::/32, 2804:66b8::/32, 2804:66bc::/32, 2804:66c0::/32, 2804:66c4::/32, 2804:66c8::/32, 2804:66cc::/32, 2804:66d0::/32, 2804:66d4::/32, 2804:66d8::/32, 2804:66dc::/32, 2804:66e0::/32, 2804:66e4::/32, 2804:66e8::/32, 2804:66ec::/32, 2804:66f0::/32, 2804:66f4::/32, 2804:66f8::/32, 2804:66fc::/32, 2804:6700::/32, 2804:6704::/32, 2804:6708::/32, 2804:670c::/32, 2804:6710::/32, 2804:6714::/32, 2804:6718::/32, 2804:671c::/32, 2804:6720::/32, 2804:6724::/32, 2804:6728::/32, 2804:672c::/32, 2804:6730::/32, 2804:6734::/32, 2804:6738::/32, 2804:673c::/32, 2804:6740::/32, 2804:6744::/32, 2804:6748::/32, 2804:674c::/32, 2804:6750::/32, 2804:6754::/32, 2804:6758::/32, 2804:675c::/32, 2804:6760::/32, 2804:6764::/32, 2804:6768::/32, 2804:676c::/32, 2804:6770::/32, 2804:6774::/32, 2804:6778::/32, 2804:677c::/32, 2804:6780::/32, 2804:6784::/32, 2804:6788::/32, 2804:678c::/32, 2804:6790::/32, 2804:6794::/32, 2804:6798::/32, 2804:679c::/32, 2804:67a0::/32, 2804:67a4::/32, 2804:67a8::/32, 2804:67ac::/32' -KRILL_CHILD_ASNS = 'AS10906, AS11284, AS11644, AS11752, AS12136, AS14026, AS14650, AS22548, AS26162, AS53034, AS61580' -KRILL_CHILD_IPV4S = '45.6.53.0/24, 45.6.52.0/24, 45.6.54.0/23, 45.184.144.0/22, 45.227.0.0/22, 168.181.20.0/22, 187.16.192.0/19, 189.76.96.0/19, 200.160.0.0/20, 200.189.40.0/22, 200.192.104.0/24, 200.192.108.0/22, 200.192.232.0/22, 200.194.128.0/19, 200.219.130.0/23, 200.219.138.0-200.219.141.255, 200.219.143.0-200.219.148.255, 200.219.154.0-200.219.157.255, 200.219.158.0/23, 200.229.248.0/23' -KRILL_CHILD_IPV6S = '2001:12f8::/48, 2001:12f8:2::-2001:12f8:d:ffff:ffff:ffff:ffff:ffff, 2001:12fe::/31, 2801:80:1700::/40, 2801:80:1e00::/40' \ No newline at end of file diff --git a/tests/e2e/simple_rp_roa_test.py b/tests/e2e/simple_rp_roa_test.py deleted file mode 100644 index 8d32c003..00000000 --- a/tests/e2e/simple_rp_roa_test.py +++ /dev/null @@ -1,294 +0,0 @@ -import logging -import pytest -import rtrlib - -from retrying import retry, RetryError -from time import time -from operator import attrgetter -import krill_ca_api as krill_ca_api_lib -import krill_pub_api as krill_pub_api_lib - -from tests.util import krill -from tests.util.docker import docker_project, class_service_manager, function_service_manager, run_command, docker_host_fqdn -from tests.util.krill import krill_api_config -from tests.util.rtr import rtr_fetch_one, roa_to_roa_string -from tests.util.relyingparties import * - -from data import * - - -# Test classes that use this fixture will cause Krill and its dependencies to -# be started (and torn down at the end of all tests in the class), and to be -# configured with CAs and ROas. If you want many test classes to use the -# created resources before they are torn down module scope might then be more -# appropriate. -@pytest.fixture(scope="class") -def krill_with_roas(docker_project, krill_api_config, class_service_manager): - # - # Define some retry helpers for situations where the API call to Krill - # can succeed but Krill may not yet be in the expected state. - # - def no_retry_if_forbidden(e): - """Return True if we should retry, False otherwise""" - return not (isinstance(e, krill_ca_api_lib.ApiException) and e.status == 403) - - def retry_if_not(result): - """Return True if we should retry, False otherwise""" - # e.g. return True for empty lists, empty strings, None - return not bool(result) - - @retry( - stop_max_attempt_number=10, - wait_fixed=2000, - retry_on_exception=no_retry_if_forbidden, - wrap_exception=True) - def wait_until_ready(): - return krill_other_api.is_authorized() - - @retry( - stop_max_attempt_number=10, - wait_exponential_multiplier=1000, - wait_exponential_max=10000, - retry_on_result=retry_if_not, - wrap_exception=True) - def wait_until_ca_has(ca_handle, property, matcher_func): - ca = krill_ca_api.get_ca(ca_handle) - f = attrgetter(property) - cas = f(ca) - return [ca for ca in cas if matcher_func(ca)] - - @retry( - stop_max_attempt_number=10, - wait_exponential_multiplier=1000, - wait_exponential_max=10000, - retry_on_result=retry_if_not, - wrap_exception=True) - def wait_until_child_ca_has_at_least_one(parent_handle, child_handle, property): - ca = krill_ca_api.get_child_ca(parent_handle, child_handle) - f = attrgetter(property) - return f(ca) - - @retry( - stop_max_attempt_number=10, - wait_exponential_multiplier=1000, - wait_exponential_max=10000, - retry_on_result=retry_if_not, - wrap_exception=True) - def wait_until_ca_has_resources(ca_handle, asn, ipv4, ipv6): - ca = krill_ca_api.get_ca(ca_handle) - f = attrgetter("resources") - res = f(ca) - return set(res.asn) == set(asn) and set(res.ipv4) == set(ipv4) and set(res.ipv6) == set(ipv6) - - # - # define some helper functions - # - def add_ca(ca_handle): - logging.info(f'-> Adding CA "{ca_handle}"') - krill_ca_api.add_ca(krill_ca_api_lib.AddCARequest(ca_handle)) - - logging.info(f'-> Getting RFC 8183 publisher request for CA "{ca_handle}" (API call `get_ca_publisher_request()`)') - rfc8183_request = krill_ca_api.get_ca_publisher_request(ca_handle, format='json') - - logging.info(f'-> Submitting RFC 8183 publisher request for CA "{ca_handle}" in exchange for an RFC 8183 repository_response (API call `add_publisher()`)') - rfc8183_response = krill_pub_api.add_publisher(rfc8183_request) - - logging.info(f'-> Submitting RFC 8181 repository response for CA "{ca_handle}" (API call `update_ca_repository()`)') - krill_ca_api.update_ca_repository( - ca_handle, - inline_object=krill_ca_api_lib.InlineObject(repository_response=rfc8183_response)) - logging.info(f'-> Added CA "{ca_handle}"') - - def link_child_ca_under_parent_ca(child_ca_handle, parent_ca_handle, resources): - logging.info(f'-> Getting RFC 8183 child request for CA "{child_ca_handle}" (API call `get_ca_child_request()`)') - rfc8183_request = krill_ca_api.get_ca_child_request(child_ca_handle, format="json") - - logging.info(f'-> Adding CA "{child_ca_handle}" as a child of "{parent_ca_handle}" (API call `add_child_ca()`)') - req = krill_ca_api_lib.AddCAChildRequest( - handle=child_ca_handle, - resources=resources, - id_cert=rfc8183_request.id_cert) - krill_ca_api.add_child_ca(parent_ca_handle, req) - logging.info(f'-> Added CA "{child_ca_handle} as a child of "{parent_ca_handle}"') - - logging.info(f'-> Waiting for CA "{child_ca_handle}" to be registered as a child of "{parent_ca_handle}"') - wait_until_ca_has(parent_ca_handle, 'children', lambda handle: handle == child_ca_handle) - - logging.info(f'-> Waiting for resources of child CA "{child_ca_handle}" to be registered') - wait_until_child_ca_has_at_least_one(parent_ca_handle, child_ca_handle, 'entitled_resources.asn') - - def link_parent_ca_above_child_ca(parent_ca_handle, child_ca_handle, resources): - logging.info(f'-> Getting RFC 8183 parent response for CA "{child_ca_handle}" (API call `get_child_ca_parent_contact()`)') - rfc8183parentresponse = krill_ca_api.get_child_ca_parent_contact(parent_ca_handle, child_ca_handle) - - logging.info(f'-> Adding CA "{parent_ca_handle}" as a parent of "{child_ca_handle}" (API call `add_ca_parent()`)') - req = krill_ca_api_lib.AddParentCARequest( - handle=parent_ca_handle, - contact=rfc8183parentresponse) - krill_ca_api.add_ca_parent(child_ca_handle, req) - logging.info(f'-> Added CA "{parent_ca_handle}" as a parent of "{child_ca_handle}"') - - logging.info(f'-> Waiting for CA "{parent_ca_handle}" to be registered as a parent of "{child_ca_handle}"') - wait_until_ca_has(child_ca_handle, 'parents', lambda ca: ca.handle == parent_ca_handle) - - logging.info(f'-> Waiting for resources of CA "{child_ca_handle}" to be issued:') - wait_until_ca_has_resources(child_ca_handle, resources.asn, resources.ipv4, resources.ipv6) - - # - # Go! - # - - try: - # Bring up Krill and its dependencies - krill.select_krill_config_file(docker_project, 'krill.conf') - class_service_manager.start_services_with_dependencies(docker_project, ['krill']) - - # Strategy: Test then add, don't add then handle failure because that will - # cause errors to appear in the Krill server log which can be confusing - # when investigating problems. - - # Get the API helper objects we need - krill_ca_api_client = krill_ca_api_lib.ApiClient(krill_api_config) - krill_ca_api = krill_ca_api_lib.CertificateAuthoritiesApi(krill_ca_api_client) - krill_roa_api = krill_ca_api_lib.RouteAuthorizationsApi(krill_ca_api_client) - krill_other_api = krill_ca_api_lib.OtherApi(krill_ca_api_client) - - krill_pub_api_client = krill_pub_api_lib.ApiClient(krill_api_config) - krill_pub_api = krill_pub_api_lib.PublishersApi(krill_pub_api_client) - - # Define the CA handles that we will work with - ta_handle = 'ta' - parent_handle = 'parent' - child_handle = 'child' - - # Ensure that Krill is ready for our attempts to communicate with it - logging.info('Wait till we can connect to Krill...') - wait_until_ready() - - # - # Create the desired state inside Krill - # - - parent_resources = krill_ca_api_lib.Resources(asn=KRILL_PARENT_ASNS, ipv4=KRILL_PARENT_IPV4S, ipv6=KRILL_PARENT_IPV6S) - child_resources = krill_ca_api_lib.Resources(asn=KRILL_CHILD_ASNS, ipv4=KRILL_CHILD_IPV4S, ipv6=KRILL_CHILD_IPV6S) - - logging.info(f'Checking if Krill has an embedded TA "{ta_handle}"') - ca_handles = [ca.handle for ca in krill_ca_api.list_cas().cas] - - if ta_handle in ca_handles: - logging.info(f'Configuring Krill for use with embedded TA "{ta_handle}"') - - logging.info(f'Adding CA "{parent_handle}" if not already present') - if not parent_handle in ca_handles: - add_ca(parent_handle) - - logging.info(f'Creating TA "{ta_handle}" -> CA "{parent_handle}" relationship if not already present') - ta_children = krill_ca_api.get_ca(ta_handle).children - if not parent_handle in ta_children: - link_child_ca_under_parent_ca(parent_handle, ta_handle, parent_resources) - - logging.info(f'Creating TA "{ta_handle}" <- CA "{parent_handle}" relationship if not already present') - if len(krill_ca_api.get_ca(parent_handle).parents) == 0: - link_parent_ca_above_child_ca(ta_handle, parent_handle, parent_resources) - - logging.info(f'Adding CA "{child_handle}" if not already present') - if not child_handle in ca_handles: - add_ca(child_handle) - - logging.info(f'Creating CA "{parent_handle}" -> CA "{child_handle}" relationship if not already present') - if len(krill_ca_api.get_ca(parent_handle).children) == 0: - link_child_ca_under_parent_ca(child_handle, parent_handle, child_resources) - - logging.info(f'Creating CA "{parent_handle}" <- CA "{child_handle}" relationship if not already present') - if len(krill_ca_api.get_ca(child_handle).parents) == 0: - link_parent_ca_above_child_ca(parent_handle, child_handle, child_resources) - - logging.info(f'Creating CA "{child_handle}" ROAs if not already present') - if len(krill_roa_api.list_route_authorizations(child_handle)) == 0: - delta = krill_ca_api_lib.ROADelta(added=TEST_ROAS, removed=[]) - - @retry( - stop_max_attempt_number=10, - wait_exponential_multiplier=1000, - wait_exponential_max=10000, - wrap_exception=True) - def update_roas(): - logging.info('Updating ROAs...') - krill_roa_api.update_route_authorizations(child_handle, delta) - - update_roas() - - logging.info('Krill configuration complete') - - except RetryError as e: - if e.last_attempt.has_exception: - (ex_type, ex_value, traceback) = e.last_attempt.value - pytest.fail(f'Retries exhausted while configuring Krill: {ex_value} caused by {e}') - else: - pytest.fail(f'Retries exhausted while configuring Krill: {e}') - - yield (krill_ca_api_client, krill_pub_api_client) - - -@pytest.mark.usefixtures("krill_with_roas") -class TestKrillWithRelyingParties: - def test_setup(self): - # Cause the krill_with_roas and dependent fixtures to be setup once - # before the tests below run, otherwise the first real test also - # includes the work and output of creating the fixtures. - pass - - #@pytest.mark.parametrize("service", [Routinator, RoutinatorUnstable, FortValidator, OctoRPKI, Rcynic, RPKIClient, RPKIValidator3]) - @pytest.mark.parametrize("service", [Routinator, RoutinatorUnstable, FortValidator, OctoRPKI, Rcynic, RPKIClient]) - def test_rtr(self, docker_host_fqdn, docker_project, function_service_manager, service, metadata): - # - # Use Docker Compose to deploy the given Relying Party service and its dependencies. - # On tear down the service container and its dependent containers will be killed and removed. - # - function_service_manager.start_services_with_dependencies(docker_project, service.name) - - class UpdateWasEmpty(Exception): - pass - - def retry_if_incomplete_update(exception): - return isinstance(exception, rtrlib.exceptions.SyncTimeout) or \ - isinstance(exception, UpdateWasEmpty) - - @retry( - stop_max_attempt_number=10, - wait_exponential_multiplier=5000, - wait_exponential_max=20000, - retry_on_exception=retry_if_incomplete_update, - wrap_exception=True) - def fetch_from_rtr_server(): - try: - rtr_start_time = int(time()) - logging.info(f'Connecting RTR client to {docker_host_fqdn}:{service.rtr_port}') - received_roas = set(rtr_fetch_one(docker_host_fqdn, service.rtr_port, service.rtr_timeout_seconds)) - rtr_elapsed_time = int(time()) - rtr_start_time - - # r is now a list of PFXRecord - # see: https://python-rtrlib.readthedocs.io/en/latest/api.html#rtrlib.records.PFXRecord - logging.info(f'Received {len(received_roas)} ROAs via RTR from {service.name} in {rtr_elapsed_time} seconds') - - if len(received_roas) == 0: - # retry, maybe the ROAs are not available yet - raise UpdateWasEmpty() - - # are each of the TEST_ROAS items in r? - # i.e. is the intersection of the two sets equal to that of the TEST_ROAS set? - - logging.info(f'Comparing {len(received_roas)} received ROAs to {len(TEST_ROAS)} expected ROAs...') - expected_roas = set([roa_to_roa_string(r) for r in TEST_ROAS]) - assert received_roas == expected_roas - except rtrlib.exceptions.SyncTimeout as e: - logging.error(f'Timeout (>{service.rtr_timeout_seconds} seconds) while syncing RTR with {service.name} at {docker_host_fqdn}:{service.rtr_port}') - try: - if not service.is_ready(): - logging.error(f'{service.name} is not ready') - except Exception as innerE: - logging.error(f'Unable to determine if {service.name} is ready: {innerE}') - - raise e - - fetch_from_rtr_server() diff --git a/tests/multi_user_admin_token.rs b/tests/multi_user_admin_token.rs deleted file mode 100644 index aa701f39..00000000 --- a/tests/multi_user_admin_token.rs +++ /dev/null @@ -1,8 +0,0 @@ -#[cfg(feature = "ui-tests")] -mod ui; - -#[tokio::test] -#[cfg(feature = "ui-tests")] -async fn multi_user_admin_token_test() { - ui::run_krill_ui_test("multi_user_admin_token", ui::OpenIDConnectMockConfig::do_not_start()).await; -} diff --git a/tests/multi_user_config_file.rs b/tests/multi_user_config_file.rs deleted file mode 100644 index 5e59906d..00000000 --- a/tests/multi_user_config_file.rs +++ /dev/null @@ -1,8 +0,0 @@ -#[cfg(all(feature = "ui-tests", feature = "multi-user"))] -mod ui; - -#[tokio::test] -#[cfg(all(feature = "ui-tests", feature = "multi-user"))] -async fn multi_user_config_file_test() { - ui::run_krill_ui_test("multi_user_config_file", ui::OpenIDConnectMockConfig::do_not_start()).await -} diff --git a/tests/multi_user_config_file_with_ta.rs b/tests/multi_user_config_file_with_ta.rs deleted file mode 100644 index a45ae848..00000000 --- a/tests/multi_user_config_file_with_ta.rs +++ /dev/null @@ -1,72 +0,0 @@ -#[cfg(all(feature = "ui-tests", feature = "multi-user"))] -mod ui; - -#[tokio::test] -#[cfg(all(feature = "ui-tests", feature = "multi-user"))] -async fn multi_user_config_file_with_ta_test() { - use log::info; - - use std::{ - collections::{HashMap, HashSet}, - str::FromStr, - }; - - use rpki::ca::idexchange::Handle; - - use krill::{ - cli::{ - options::{CaCommand, Command, HistoryOptions}, - report::ApiResponse, - }, - test::*, - }; - - ui::run_krill_ui_test( - "multi_user_config_file_with_ta", - ui::OpenIDConnectMockConfig::do_not_start(), - ) - .await; - - // Check the Krill event history after the actions performed against Krill - // by the Cypress browser driving test script we just executed. Expect at - // least one action to be attributed to the logged in user who interacted - // with the CA allocated to them and at least one action with the same CA to - // be attributed to the internal 'krill' user. - // TODO: improve this to match the exact sequence of expected actions and - // attributed actors. - info!("Verifying that CAs were modified by the expected users according to the history log"); - - let mut cas_and_users = HashMap::new(); - cas_and_users.insert("ca_admin", vec!["krill", "user:admin@krill"]); - cas_and_users.insert( - "ca_readwrite", - vec!["krill", "user:readwrite@krill", "user:joe", "user:sally"], - ); - cas_and_users.insert("ca_readonly", vec!["krill", "user:rohelper@krill"]); - - for (ca, expected_users) in cas_and_users { - let r = krill_admin(Command::CertAuth(CaCommand::ShowHistoryCommands( - Handle::from_str(ca).unwrap(), - HistoryOptions::default(), - ))) - .await; - - assert!( - matches!(r, ApiResponse::CertAuthHistory(_)), - "Expected a history API response" - ); - - if let ApiResponse::CertAuthHistory(history) = r { - // each expected user should be present at least once in the history of the CA - // no other users should be present in the CA history - let expected_users_set: HashSet = expected_users.iter().map(|u| u.to_string()).collect(); - let found_users_set: HashSet = history.commands().iter().map(|r| r.actor.clone()).collect(); - - assert_eq!( - expected_users_set, found_users_set, - "One or more users in the history of CA '{}' is missing or unexpected", - ca - ); - } - } -} diff --git a/tests/multi_user_openid_connect.rs b/tests/multi_user_openid_connect.rs deleted file mode 100644 index 51c5814c..00000000 --- a/tests/multi_user_openid_connect.rs +++ /dev/null @@ -1,14 +0,0 @@ -#[cfg(all(feature = "ui-tests", feature = "multi-user"))] -mod ui; - -#[tokio::test] -#[cfg(all(feature = "ui-tests", feature = "multi-user"))] -async fn multi_user_openid_connect_test() { - use crate::ui::{OpenIDConnectMockConfig, OpenIDConnectMockMode::*}; - - ui::run_krill_ui_test( - "multi_user_openid_connect", - OpenIDConnectMockConfig::enabled(WithRPInitiatedLogout), - ) - .await -} diff --git a/tests/multi_user_openid_connect_provider_not_available.rs b/tests/multi_user_openid_connect_provider_not_available.rs deleted file mode 100644 index 959a38cd..00000000 --- a/tests/multi_user_openid_connect_provider_not_available.rs +++ /dev/null @@ -1,14 +0,0 @@ -#[cfg(all(feature = "ui-tests", feature = "multi-user"))] -mod ui; - -#[tokio::test] -#[cfg(all(feature = "ui-tests", feature = "multi-user"))] -async fn multi_user_openid_connect_provider_not_available_test() { - use crate::ui::{OpenIDConnectMockConfig, OpenIDConnectMockMode::*}; - - ui::run_krill_ui_test( - "multi_user_openid_connect_provider_not_available", - OpenIDConnectMockConfig::disabled(WithRPInitiatedLogout), - ) - .await -} diff --git a/tests/multi_user_openid_connect_provider_with_custom_logout.rs b/tests/multi_user_openid_connect_provider_with_custom_logout.rs deleted file mode 100644 index 4e8b4212..00000000 --- a/tests/multi_user_openid_connect_provider_with_custom_logout.rs +++ /dev/null @@ -1,14 +0,0 @@ -#[cfg(all(feature = "ui-tests", feature = "multi-user"))] -mod ui; - -#[tokio::test] -#[cfg(all(feature = "ui-tests", feature = "multi-user"))] -async fn multi_user_openid_connect_provider_with_custom_logout() { - use crate::ui::{OpenIDConnectMockConfig, OpenIDConnectMockMode::*}; - - ui::run_krill_ui_test( - "multi_user_openid_connect_provider_with_custom_logout", - OpenIDConnectMockConfig::enabled(WithRPInitiatedLogout), - ) - .await -} diff --git a/tests/multi_user_openid_connect_provider_with_fallback_logout.rs b/tests/multi_user_openid_connect_provider_with_fallback_logout.rs deleted file mode 100644 index 88fd278a..00000000 --- a/tests/multi_user_openid_connect_provider_with_fallback_logout.rs +++ /dev/null @@ -1,14 +0,0 @@ -#[cfg(all(feature = "ui-tests", feature = "multi-user"))] -mod ui; - -#[tokio::test] -#[cfg(all(feature = "ui-tests", feature = "multi-user"))] -async fn multi_user_openid_connect_provider_with_fallback_logout_test() { - use crate::ui::{OpenIDConnectMockConfig, OpenIDConnectMockMode::*}; - - ui::run_krill_ui_test( - "multi_user_openid_connect_provider_with_fallback_logout", - OpenIDConnectMockConfig::enabled(WithNoLogoutEndpoints), - ) - .await -} diff --git a/tests/multi_user_openid_connect_provider_with_revocation.rs b/tests/multi_user_openid_connect_provider_with_revocation.rs deleted file mode 100644 index 130de679..00000000 --- a/tests/multi_user_openid_connect_provider_with_revocation.rs +++ /dev/null @@ -1,14 +0,0 @@ -#[cfg(all(feature = "ui-tests", feature = "multi-user"))] -mod ui; - -#[tokio::test] -#[cfg(all(feature = "ui-tests", feature = "multi-user"))] -async fn multi_user_openid_connect_provider_with_revocation() { - use crate::ui::{OpenIDConnectMockConfig, OpenIDConnectMockMode::*}; - - ui::run_krill_ui_test( - "multi_user_openid_connect_provider_with_revocation", - OpenIDConnectMockConfig::enabled(WithOAuth2Revocation), - ) - .await -} diff --git a/tests/multi_user_team_based_access.rs b/tests/multi_user_team_based_access.rs deleted file mode 100644 index 8c69fc76..00000000 --- a/tests/multi_user_team_based_access.rs +++ /dev/null @@ -1,12 +0,0 @@ -#[cfg(feature = "ui-tests")] -mod ui; - -#[tokio::test] -#[cfg(all(feature = "ui-tests", feature = "multi-user"))] -async fn multi_user_team_based_access_test() { - ui::run_krill_ui_test( - "multi_user_team_based_access", - ui::OpenIDConnectMockConfig::do_not_start(), - ) - .await -} diff --git a/tests/testbed_ui.rs b/tests/testbed_ui.rs deleted file mode 100644 index 81777681..00000000 --- a/tests/testbed_ui.rs +++ /dev/null @@ -1,8 +0,0 @@ -#[cfg(all(feature = "ui-tests", feature = "multi-user"))] -mod ui; - -#[tokio::test] -#[cfg(all(feature = "ui-tests", feature = "multi-user"))] -async fn testbed_ui_test() { - ui::run_krill_ui_test("testbed_ui", ui::OpenIDConnectMockConfig::do_not_start()).await; -} diff --git a/tests/ui/cypress/plugins/index.js b/tests/ui/cypress/plugins/index.js deleted file mode 100644 index b3de43aa..00000000 --- a/tests/ui/cypress/plugins/index.js +++ /dev/null @@ -1,25 +0,0 @@ -/* eslint-disable arrow-body-style */ -// https://docs.cypress.io/guides/guides/plugins-guide.html - -// if you need a custom webpack configuration you can uncomment the following import -// and then use the `file:preprocessor` event -// as explained in the cypress docs -// https://docs.cypress.io/api/plugins/preprocessors-api.html#Examples - -// /* eslint-disable import/no-extraneous-dependencies, global-require */ -// const webpack = require('@cypress/webpack-preprocessor') - -module.exports = (on, config) => { - // on('file:preprocessor', webpack({ - // webpackOptions: require('@vue/cli-service/webpack.config'), - // watchOptions: {} - // })) - - return Object.assign({}, config, { - fixturesFolder: 'test-resources', - integrationFolder: 'tests/ui/cypress/specs', - screenshotsFolder: 'target/ui/screenshots', - videosFolder: 'target/ui/videos', - supportFile: 'tests/ui/cypress/support/index.js' - }) -} diff --git a/tests/ui/cypress/specs/multi_user_admin_token.js b/tests/ui/cypress/specs/multi_user_admin_token.js deleted file mode 100644 index c5326937..00000000 --- a/tests/ui/cypress/specs/multi_user_admin_token.js +++ /dev/null @@ -1,54 +0,0 @@ -let admin = { u: 'admin-token', p: 'secret' }; - -describe('admin API token', () => { - it('The correct login form is shown', () => { - cy.visit('/') - - // make sure we haven't been redirected away from Krill (as would be the - // case if an OpenID Connect login form were shown) - cy.url().should('include', Cypress.config('baseUrl')) - - // make sure that no user name field exists (as would be the case if the - // built-in config file based local user login form were shown) - cy.contains('Username').should('not.exist') - - // check that a password form input field and the text Password are shown on - // the page - cy.get(':password') - cy.contains('Password') - }) - - it('Cannot login with empty password', () => { - cy.visit('/') - cy.get(':password').clear() - cy.contains('Sign In').click() - cy.contains('Please enter your password') - }) - - it('Cannot login with incorrect password', () => { - cy.visit('/') - cy.get(':password').clear().type('abc') - cy.contains('Sign In').click() - cy.contains('The credentials you specified are wrong') - }) - - it('Can login with correct password', () => { - cy.visit('/') - cy.get(':password').type(admin.p) - cy.contains('Sign In').click() - cy.contains('Sign In').should('not.exist') - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains(admin.u) - }) - - it('Can logout', () => { - cy.visit('/') - cy.get(':password').type(admin.p) - cy.contains('Sign In').click() - cy.contains('Sign In').should('not.exist') - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains(admin.u) - cy.get('.logout').click() - cy.contains('Sign In') - }) -}) \ No newline at end of file diff --git a/tests/ui/cypress/specs/multi_user_config_file.js b/tests/ui/cypress/specs/multi_user_config_file.js deleted file mode 100644 index 518f1a3d..00000000 --- a/tests/ui/cypress/specs/multi_user_config_file.js +++ /dev/null @@ -1,120 +0,0 @@ -// A note about strong password hashing login delays -// ----------------------------------------------------------------------------- -// The strong password hashing on the client and server side when logging in with -// config file users causes the login process to take a few seconds. As such we -// extend the default timeout when checking for Sign In completion, like so: -// -// cy.contains('Sign In', { timeout: 10000 }).should('not.exist') - -let admin = { u: 'admin@krill', p: 'admin_pass' }; -let readonly = { u: 'readonly@krill', p: 'readonly_pass' }; -let readwrite = { u: 'readwrite@krill', p: 'readwrite_pass' }; -let ca_name = 'dummy-ca-name'; - -let login_test_settings = [ - { d: 'empty', u: '', p: '', o: false }, - { d: 'admin token', u: 'secret', p: 'secret', o: false }, - { d: 'incorrect', u: 'wrong_user_name', p: 'wrong_password', o: false }, - { d: 'admin', u: admin.u, p: admin.p, o: true }, - { d: 'readonly', u: readonly.u, p: readonly.p, o: true }, - { d: 'readwrite', u: readwrite.u, p: readwrite.p, o: true }, -]; - -describe('Config File users', () => { - it('The correct login form is shown', () => { - cy.visit('/') - - // make sure we haven't been redirected away from Krill (as would be the - // case if an OpenID Connect login form were shown) - cy.url().should('include', Cypress.config('baseUrl')) - - // make sure that user name field exists (which would not be the case if the - // built-in admin token based login form were shown) - cy.contains('Username') - - // check that a password form input field and the text Password are shown on - // the page - cy.get(':password') - cy.contains('Password') - }) - - login_test_settings.forEach(function (ts) { - it('Login with ' + ts.d + ' credentials should ' + (ts.o ? 'succeed' : 'fail'), () => { - // Work around the "Login with incorrect credentials should fail" test failing with ESOCKETTIMEDOUT by increasing - // the response timeout as mentioned on https://github.com/cypress-io/cypress/issues/7062. This isn't anything to - // do with incorrect credentials as re-ordering the tests causes a different test to fail. Rather, on a 2-vcpu - // GitHub Actions runner Azure VM Krill is apparently busy around the time of the 4th test and takes longer to - // respond. The issue is reproducible on a 1-vcpu AWS t2.small EC2 instance but not on a 2-vcpu AWS EC2 instance. - cy.visit('/', { responseTimeout: 31000 }) - cy.contains('Username') - cy.contains('Password') - - cy.get('input[placeholder="Your username"]').clear() - cy.get(':password').clear() - - if (ts.u != '') cy.get('input[placeholder="Your username"]').type(ts.u) - if (ts.p != '') cy.get(':password').type(ts.p) - - cy.contains('Sign In').click() - - if (ts.u == '') cy.contains('Please enter your username') - if (ts.p == '') cy.contains('Please enter your password') - - if (ts.o) { - cy.contains('Sign In', { timeout: 10000 }).should('not.exist') - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains(ts.u) - } else { - cy.contains('Sign In') - } - }) - }) - - it('Can logout', () => { - cy.visit('/') - cy.get('input[placeholder="Your username"]').type(admin.u) - cy.get(':password').type(admin.p) - cy.contains('Sign In').click() - cy.contains('Sign In', { timeout: 10000 }).should('not.exist') - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains(admin.u) - cy.get('.logout').click() - cy.contains('Sign In') - }) - - it('Should be timed out', () => { - // take manual control of time in the browser - cy.clock() - - // login - cy.visit('/') - cy.get('input[placeholder="Your username"]').type(admin.u) - cy.get(':password').type(admin.p) - cy.contains('Sign In').click() - cy.contains('Sign In', { timeout: 10000 }).should('not.exist') - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains(admin.u) - - // Skip ahead a minute and check that we are still logged in - cy.tick(1 * 60 * 1000) - cy.visit('/') - cy.contains('Sign In').should('not.exist') - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains(admin.u) - - // Skip ahead till just before the idle timeout and check that we are still - // logged in. - cy.tick(28 * 60 * 1000) - cy.visit('/') - cy.contains('Sign In').should('not.exist') - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains(admin.u) - - // Skip ahead another 31 minutes to just beyond the UI 30 minute idle - // timeout threshold and verify that we have been logged out - cy.tick(31 * 60 * 1000) - cy.visit('/') - cy.get('#userinfo').should('not.exist') - cy.contains('Sign In') - }) -}) \ No newline at end of file diff --git a/tests/ui/cypress/specs/multi_user_config_file_with_ta.js b/tests/ui/cypress/specs/multi_user_config_file_with_ta.js deleted file mode 100644 index fc2353d0..00000000 --- a/tests/ui/cypress/specs/multi_user_config_file_with_ta.js +++ /dev/null @@ -1,482 +0,0 @@ -// This demonstrates use of config-file based users with Krill and Lagosta. -// It also demonstrates the custom role-per-ca demo policy because that -// requires multiple CAs and registered parents and repositories to demo -// ability to create ROAs but not to perform other CA "write" operations, -// which is already setup by this demo. - -// A note about difficulty entering XML into Lagosta XML input fields: -// ----------------------------------------------------------------------------- -// Using cy.type() to enter XML into these fields is extremely slow, one -// animated character at a time. I haven't yet found a way to copy-paste into -// them. Setting the text directly can be done but there is a challenge that has -// to be worked around which is that the fields use Prism Editor JS to syntax -// highlight the XML. Prism Editor manages the content as a rich HTML child node -// structure. Just replacing the content with a new text node doesn't work as -// the Lagosta JS code reading the field content doesn't get the content as -// set for some reason. The set text also doesn't get syntax highlighted. What -// seems to work however is causing a keyboard event in the field after the text -// has been set, e.g. pressing the End key. -// -// To summarize, the following works quickly: -// cy.get('... pre[contenteditable="true"]').invoke('text', xml) -// cy.get('... pre[contenteditable="true"]').type('{end}') -// -// This is less hacky but very slow: (even with "type(xml, {delay: 0}))") -// cy.get('... pre[contenteditable="true"]').clear().type(xml) - -// A note about strong password hashing login delays -// ----------------------------------------------------------------------------- -// The strong password hashing on the client and server side when logging in with -// config file users causes the login process to take a few seconds. As such we -// extend the default timeout when checking for Sign In completion, like so: -// -// cy.contains('Sign In', { timeout: 10000 }).should('not.exist') - -let admin = { u: 'admin@krill', p: 'admin' }; -let readonly = { u: 'readonly@krill', p: 'readonly' }; -let readwrite = { u: 'readwrite@krill', p: 'readwrite' }; -let rohelper = { u: 'rohelper@krill', p: 'rohelper' }; -let joe = { u: 'joe', p: 'abc' }; -let sally = { u: 'sally', p: 'abc' }; - -// For the tests below to work these users must only have access to a single CA, -// at the time of CA creation, otherwise only the first user gets to create a CA, -// after that Lagosta doesn't prompt to create a CA as the user can already see -// that one exists. -// -// For the read only user to be able to see the repository and parent management -// UI they must be able to get past the "Welcome to Krill" screen which prompts -// to create a CA, something the read only user cannot do. Therefore the CA for -// the read only user needs to be created for it by another user, and should be -// tested for CA creation failure *before* that CA is created. -let create_ca_test_settings = [ - { d: 'readonly', u: readonly.u, p: readonly.p, o: false, ca: 'ca_readonly' }, - { d: 'readwrite', u: readwrite.u, p: readwrite.p, o: true, ca: 'ca_readwrite' }, - { d: 'admin', u: admin.u, p: admin.p, o: true, ca: 'ca_admin' }, - { d: 'rohelper', u: rohelper.u, p: rohelper.p, o: true, ca: 'ca_readonly' }, // create the CA for the readonly user as they cannot do it themselves -]; - -let register_publisher_test_settings = [ - { d: 'readonly', u: readonly.u, p: readonly.p, o: false, a: 'Register', ca: 'ca_readonly' }, - { d: 'readwrite', u: readwrite.u, p: readwrite.p, o: true, a: 'Register', ca: 'ca_readwrite' }, - { d: 'admin', u: admin.u, p: admin.p, o: true, a: 'Register', ca: 'ca_admin' }, - { d: 'rohelper', u: rohelper.u, p: rohelper.p, o: true, a: 'Unregister', ca: 'ca_readonly' }, // unregister the half-registered publisher created by the readonly user - { d: 'rohelper', u: rohelper.u, p: rohelper.p, o: true, a: 'Register', ca: 'ca_readonly' }, // re-register it properly now -]; - -let register_parent_test_settings = [ - { d: 'readonly', u: readonly.u, p: readonly.p, o: false, a: 'Register', ca: 'ca_readonly' }, - { d: 'readwrite', u: readwrite.u, p: readwrite.p, o: true, a: 'Register', ca: 'ca_readwrite' }, - { d: 'admin', u: admin.u, p: admin.p, o: true, a: 'Register', ca: 'ca_admin' }, - { d: 'rohelper', u: rohelper.u, p: rohelper.p, o: true, a: 'Unregister', ca: 'ca_readonly' }, // unregister the half-registered parent created by the readonly user - { d: 'rohelper', u: rohelper.u, p: rohelper.p, o: true, a: 'Register', ca: 'ca_readonly' }, // re-register it properly now -]; - -let add_roa_test_settings = [ - { d: 'readonly', u: readonly.u, p: readonly.p, o: false, ca: 'ca_readonly' }, - { d: 'readwrite', u: readwrite.u, p: readwrite.p, o: true, ca: 'ca_readwrite' }, - { d: 'admin', u: admin.u, p: admin.p, o: true, ca: 'ca_admin' }, -]; - -let joe_cas = ['ta', 'testbed', 'ca_admin', 'ca_readwrite', 'ca_readonly']; -let sally_cas = ['ca_readwrite', 'ca_readonly']; - -describe('Config File Users with TA', () => { - create_ca_test_settings.forEach(function (ts) { - it('Create CA as ' + ts.d + ' user should ' + (ts.o ? 'succeed' : 'fail'), () => { - // sign in - cy.visit('/') - cy.get('#login_id').type(ts.u) - cy.get('#login_password').type(ts.p) - cy.contains('Sign In').click() - cy.contains('Sign In', { timeout: 10000 }).should('not.exist') - cy.contains(ts.u) - cy.contains('Welcome to Krill') - - // create a CA - cy.contains('CA Handle') - cy.get('form input[type="text"]').type(ts.ca) - cy.contains('Create CA').click() - cy.contains('OK').click() - - // no longer on the welcome page - if (ts.o) { - cy.contains('Welcome to Krill').should('not.exist') - } else { - cy.contains('Welcome to Krill') - } - }) - }) - - register_publisher_test_settings.forEach(function (ts) { - it(ts.a + ' CA ' + ts.ca + ' with repository as ' + ts.d + ' user should ' + (ts.o ? 'succeed' : 'fail'), () => { - if (ts.a == 'Register') { - cy.intercept({ method: 'GET', path: '/api/v1/cas/' + ts.ca + '/id/publisher_request.xml'}).as('getRepoRequestXML') - - // sign in - cy.visit('/') - cy.get('#login_id').type(ts.u) - cy.get('#login_password').type(ts.p) - cy.contains('Sign In').click() - cy.contains('Sign In', { timeout: 10000 }).should('not.exist') - cy.contains(ts.u) - - // wait for Lagosta to finish fetching the repository request XML - cy.wait('@getRepoRequestXML').its('response.statusCode').should('eq', 200) - - // grab the repository tab publisher request XML from the Krill UI - cy.get('div#tab-repo').click() - cy.get('div#pane-repo pre[contenteditable="false"] code').contains(' { - // use the local testbed UI to submit the request to register the publisher - cy.visit("/index.html#/testbed") - - // enter the request XML into the testbed UI edit field - cy.get('div#tab-addPublisher').contains('Register Publisher').click() - cy.get('#addPublisher pre[contenteditable="true"]').invoke('text', pub_req_xml) - cy.get('#addPublisher pre[contenteditable="true"]').type('{end}') - cy.get('#addPublisher button').contains('Register publisher').click() - cy.get('div[role="dialog"] button').contains('OK').click() - cy.contains('has been added to the testbed') - - // note: publisher registration succeeds even for the readonly user - // because for the testbed half of the XML exchange the readonly user is - // automatically promoted for the duration of the request to the - // internal 'testbed' user, so that the testbed is usable without - // requiring user accounts. - - // grab the repository response XML from the testbed UI - cy.get('#addPublisher pre[contenteditable="false"]').contains(' { - // navigate back to Krill - cy.visit("/") - - // enter the response XML into the Krill UI edit field - cy.get('div#tab-repo').click() - cy.get('div#pane-repo pre[contenteditable="true"]').invoke('text', repo_resp_xml) - cy.get('div#pane-repo pre[contenteditable="true"]').type('{end}') - cy.get('div#pane-repo button').contains('Confirm').click() - - if (ts.o) { - cy.contains('Success') - cy.contains('Error').should('not.exist') - } else { - cy.contains('Success').should('not.exist') - cy.contains('Error') - } - }) - }) - } else { - // use the local testbed UI to unregister the publisher - cy.visit("/index.html#/testbed") - - // enter the registered publisher name into the testbed UI edit field - cy.get('div#tab-removePublisher').contains('Unregister Publisher').click() - cy.get('#removePublisher input[placeholder="Enter the Publisher name to remove"]').type(ts.ca) - cy.get('#removePublisher button').contains('Remove publisher').click() - cy.get('div[role="dialog"] button').contains('OK').click() - - if (ts.o) { - cy.contains('has been removed') - } else { - cy.contains('has been removed').should('not.exist') - } - } - }) - }) - - register_parent_test_settings.forEach(function (ts) { - it(ts.a + ' CA ' + ts.ca + ' with parent as ' + ts.d + ' user should ' + (ts.o ? 'succeed' : 'fail'), () => { - if (ts.a == 'Register') { - cy.intercept({ method: 'GET', path: '/api/v1/cas/' + ts.ca + '/id/child_request.xml'}).as('getChildRequestXML') - - // sign in - cy.visit('/') - cy.get('input[placeholder="Your username"]').type(ts.u) - cy.get(':password').type(ts.p) - cy.contains('Sign In').click() - cy.contains('Sign In', { timeout: 10000 }).should('not.exist') - cy.contains(ts.u) - - // wait for Lagosta to finish fetching the repository request XML - cy.wait('@getChildRequestXML').its('response.statusCode').should('eq', 200) - - // grab the parents tab child request XML from the Krill UI - cy.get('div#tab-parents').click() - cy.get('div#pane-parents pre[contenteditable="false"] code').contains(" { - // use the local testbed UI to submit the request to register the child - cy.visit("/index.html#/testbed") - - // enter the request XML into the testbed UI edit field - cy.get('div#tab-addChild').contains('Register CA').click() - cy.get('#addChild pre[contenteditable="true"]').invoke('text', child_req_xml) - cy.get('#addChild pre[contenteditable="true"]').type('{end}') - cy.get('#addChild input[placeholder^="The AS resources"]').type('AS18') - cy.get('#addChild input[placeholder^="The IPv4 resources"]').type('10.0.0.0/24') - cy.get('#addChild button').contains('Register child CA').click() - cy.get('div[role="dialog"] button').contains('OK').click() - cy.contains('has been added to the testbed') - - // grab the parent response XML from the testbed UI - cy.get('#addChild pre[contenteditable="false"]').contains(" { - // navigate back to Krill - cy.visit("/") - - // enter the response XML into the Krill UI edit field - cy.get('div#tab-parents').click() - cy.get('div#pane-parents pre[contenteditable="true"]').invoke('text', parent_resp_xml) - cy.get('div#pane-parents pre[contenteditable="true"]').type('{end}') - cy.get('div#pane-parents button').contains('Confirm').click() - - if (ts.o) { - cy.contains('Success') - cy.contains('Error').should('not.exist') - // wait for the parent registration to complete inside Krill and - // for the details to appear in the Lagosta UI - cy.get('div#tab-parents').click().get('body').contains('Add an additional parent') - } else { - cy.contains('Success').should('not.exist') - cy.contains('Error') - } - }) - }) - } else { - // use the local testbed UI to unregister the parent - cy.visit("/index.html#/testbed") - - // enter the registered parent name into the testbed UI edit field - cy.get('div#tab-removeChild').contains('Unregister CA').click() - cy.get('#removeChild input[placeholder="Enter the CA name to remove"]').type(ts.ca) - cy.get('#removeChild button').contains('Remove child CA').click() - cy.get('div[role="dialog"] button').contains('OK').click() - - if (ts.o) { - cy.contains('has been removed') - } else { - cy.contains('has been removed').should('not.exist') - } - } - }) - }) - - add_roa_test_settings.forEach(function (ts) { - it('Add ROA for CA ' + ts.ca + ' as ' + ts.d + ' user should ' + (ts.o ? 'succeed' : 'fail'), () => { - cy.intercept({ method: 'GET', path: '/api/v1/cas/' + ts.ca + '/routes/analysis/full'}).as('analyzeRoutes') - - // sign in - cy.visit('/') - cy.get('input[placeholder="Your username"]').type(ts.u) - cy.get(':password').type(ts.p) - cy.contains('Sign In').click() - cy.contains('Sign In', { timeout: 10000 }).should('not.exist') - cy.contains(ts.u) - - // add a ROA - cy.get('div#tab-roas').click() - cy.get('body').then(($body) => { - // Check if Krill has issued the resources to the CA yet by seeing if the UI was able to fetch them, if it - // wasn't then it shows a "Click here to refresh" link. If the link exists, don't click it immediately as that - // will just result in the same lack of resources, instead give Krill some time (5 seconds) in this case then - // click the refresh link and then make sure that the link no longer exists (because resources were found). - // Ideally we would not wait 5 seconds but instead keep retrying until the link disappears, but according to - // Cypress docs it explicitly will NOT retry a .click() command. See: - // https://docs.cypress.io/guides/core-concepts/retry-ability.html#Why-are-some-commands-NOT-retried - // https://www.cypress.io/blog/2019/01/22/when-can-the-test-click/ - // The latter suggests to use a 3rd party cypress-pipe plugin and not to use waits. That would be nice, but to - // use a plugin we then need a custom Docker image which is something I'd rather not build, publish and maintain - // the moment. TODO: don't publish an image, instead build it on the test runner just before running the tests? - if ($body.find('#no_resources_click_to_refresh').length > 0) { - cy.get('#no_resources_click_to_refresh').wait(5000).click().get('body').get('#no_resources_click_to_refresh').should('not.exist') - } - }) - - // wait for Lagosta to finish fetching the route analysis details - cy.wait('@analyzeRoutes').its('response.statusCode').should('eq', 200) - - cy.get('div#pane-roas button').contains('Add ROA').click() - cy.get('div[role="dialog"]') - cy.contains('Add ROA') - cy.get('#add_roa_asn').clear().type('AS18') - cy.get('#add_roa_prefix').clear().type('10.0.0.1/32') - cy.get('div[role="dialog"] button').contains('Confirm').click() - - if (ts.o) { - cy.contains('ROA added') - } else { - cy.contains('Your user does not have sufficient rights to perform this action. Please contact your administrator.') - } - }) - }) - - // This test exercises the custom role-per-ca demo policy. - // As Joe should only be able to do write operations to the CA called 'ca_readwrite', so we test: - // - Which CAs can Joe see in the CA dropdown list? Joe should be able to see them all. - // - Can Joe create a ROA on ca_readonly? This should fail. - // - Can Joe create a ROA on ca_readwrite? This should succeed. - // - Can Joe add an additional parent to ca_readwrite? This should succeed. - it('CUSTOM POLICY: Joe can see all CAs but only write to ca_readwrite', () => { - cy.intercept({ method: 'GET', path: '/api/v1/cas/ca_readonly/repo/status'}).as('statusRO') - cy.intercept({ method: 'GET', path: '/api/v1/cas/ca_readwrite/repo/status'}).as('statusRW') - cy.intercept({ method: 'GET', path: '/api/v1/cas/ca_readwrite/id/child_request.xml'}).as('getChildRequestXML') - - // sign in - cy.visit('/') - cy.get('input[placeholder="Your username"]').type(joe.u) - cy.get(':password').type(joe.p) - cy.contains('Sign In').click() - cy.contains('Sign In', { timeout: 10000 }).should('not.exist') - cy.contains(joe.u) - - // the CA drop down should contain all the CAs - // click the dropdown to open it and show the list - cy.get('.switcher > .el-select > .el-input > .el-input__inner').click() - // check that the list contains every CA - joe_cas.forEach(function (ca_name) { - cy.get('.el-select-dropdown__wrap.el-scrollbar__wrap > ul').contains(ca_name) - }) - - // ensure we are working with CA ca_readonly - cy.url().then(($url) => { - if (!$url.includes('#/cas/ca_readonly')) { - // only change the current CA and wait for an update from the backend if the current CA isn't the one we want - cy.get('.el-select-dropdown__wrap.el-scrollbar__wrap > ul').contains('ca_readonly').click() - cy.wait('@statusRO') - } - }) - - // attempting to create a ROA on ca_readonly should fail - cy.get('#tab-roas').click() - cy.contains('Add ROA').click() - cy.get('div[role="dialog"]') - cy.contains('Add ROA') - cy.get('#add_roa_asn').clear().type('AS18') - cy.get('#add_roa_prefix').clear().type('10.0.0.1/32') - cy.get('div[role="dialog"] button').contains('Confirm').click() - cy.contains('Your user does not have sufficient rights to perform this action. Please contact your administrator.') - cy.get('div[role="dialog"] button').contains('Cancel').click() - - // attempting to create a ROA on ca_readwrite should succeed - cy.get('.switcher > .el-select > .el-input > .el-input__inner').click() - cy.get('.el-select-dropdown__wrap.el-scrollbar__wrap > ul').contains('ca_readwrite').click() - cy.wait('@statusRW') - cy.get('#tab-roas').click() - cy.contains('Add ROA').click() - cy.get('div[role="dialog"]') - cy.contains('Add ROA') - cy.get('#add_roa_asn').clear().type('AS19') - cy.get('#add_roa_prefix').clear().type('10.0.0.1/32') - cy.get('div[role="dialog"] button').contains('Confirm').click() - cy.contains('ROA added') - - // attempting to add a parent on ca_readwrite should succeed - cy.get('#tab-parents').click() - cy.contains('Add an additional parent').click() - - // grab the parents tab child request XML from the Krill UI - cy.wait('@getChildRequestXML').its('response.statusCode').should('eq', 200) - cy.get('div#pane-parents pre[contenteditable="false"] code').contains(" { - // use the local testbed UI to submit the request to register the child - cy.visit("/index.html#/testbed") - - // enter the request XML into the testbed UI edit field - cy.get('div#tab-addChild').contains('Register CA').click() - cy.get('#addChild pre[contenteditable="true"]').invoke('text', child_req_xml) - cy.get('#addChild pre[contenteditable="true"]').type('{end}') - cy.get('#addChild input[placeholder^="The AS resources"]').type('AS192') - cy.get('#addChild input[placeholder^="The IPv4 resources"]').type('192.168.0.0/24') - cy.get('#addChild button').contains('Register child CA').click() - cy.get('div[role="dialog"] button').contains('OK').click() - cy.contains('has been added to the testbed') - - // grab the parent response XML from the testbed UI - cy.get('#addChild pre[contenteditable="false"]').contains(" { - // navigate back to Krill - cy.visit("/") - - // enter the response XML into the Krill UI edit field - cy.get('#tab-parents').click() - cy.contains('Add an additional parent').click() - cy.get('div#pane-parents pre[contenteditable="true"]').invoke('text', parent_resp_xml) - cy.get('div#pane-parents pre[contenteditable="true"]').type('{end}') - - // change the default name for the parent as there is already a parent named testbed - // TODO: this CSS selector is unreadable and unreliable, give the input field an ID - // and select that instead - cy.get('.mt-3 > .el-col > .el-input > .el-input__inner').type('otherparent') - - cy.get('div#pane-parents button').contains('Confirm').click() - - cy.contains('Success') - }) - }) - }) - - // This test exercises the custom role-per-ca demo policy. - // As Sally should only be able to see two CAs and only be able to add ROAs to one other CA, we test: - // - Which CAs can Sally see in the CA dropdown list? Sally should only be able to see a specific subset. - // - Can Sally create a ROA on ca_readonly? This should fail. - // - Can Sally create a ROA on ca_readwrite? This should succeed. - // - Can Sally add an additional parent to ca_readwrite? This should fail. - // - // TODO: the CA dropdown box CSS selector is unreadable and unreliable, give the custom dropdown inner input field an - // ID and select that instead. Similarly, the CA title selector is a weak selector, it can easily break later or match - // the wrong thing if the UI design is changed and should alos be given its own ID to match on. - it('CUSTOM POLICY: Sally can only see two CAs and only make ROA changes in one CA', () => { - cy.intercept({ method: 'GET', path: '/api/v1/cas/ca_readonly/repo/status'}).as('statusRO') - cy.intercept({ method: 'GET', path: '/api/v1/cas/ca_readwrite/repo/status'}).as('statusRW') - - // sign in - cy.visit('/') - cy.get('input[placeholder="Your username"]').type(sally.u) - cy.get(':password').type(sally.p) - cy.contains('Sign In').click() - cy.contains('Sign In', { timeout: 10000 }).should('not.exist') - cy.contains(sally.u) - - // the CA drop down should contain all the CAs - // click the dropdown to open it and show the list - cy.get('.switcher > .el-select > .el-input > .el-input__inner').click() - // check that the list contains every CA - sally_cas.forEach(function (ca_name) { - cy.get('.el-select-dropdown__wrap.el-scrollbar__wrap > ul').contains(ca_name) - }) - - // attempting to create a ROA on ca_readonly should fail - cy.get('.el-select-dropdown__wrap.el-scrollbar__wrap > ul').contains('ca_readonly').click() - cy.wait('@statusRO') - cy.get('h3 > strong').contains('ca_readonly') - cy.get('#tab-roas').click() - cy.contains('Add ROA').click() - cy.get('div[role="dialog"]') - cy.contains('Add ROA') - cy.get('#add_roa_asn').clear().type('AS18') - cy.get('#add_roa_prefix').clear().type('10.0.0.1/32') - cy.get('div[role="dialog"] button').contains('Confirm').click() - cy.contains('Your user does not have sufficient rights to perform this action. Please contact your administrator.') - cy.get('div[role="dialog"] button').contains('Cancel').click() - - // attempting to create a ROA on ca_readwrite should succeed - cy.get('.switcher > .el-select > .el-input > .el-input__inner').click() - cy.get('.el-select-dropdown__wrap.el-scrollbar__wrap > ul').contains('ca_readwrite').click() - cy.wait('@statusRW') - cy.get('h3 > strong').contains('ca_readwrite') - cy.get('#tab-roas').click() - cy.contains('Add ROA').click() - cy.get('div[role="dialog"]') - cy.contains('Add ROA') - cy.get('#add_roa_asn').clear().type('AS22') - cy.get('#add_roa_prefix').clear().type('10.0.0.1/32') - cy.get('div[role="dialog"] button').contains('Confirm').click() - cy.contains('ROA added') - - // attempting to add an additional parent on ca_readwrite should fail - cy.get('#tab-parents').click() - cy.contains('Add an additional parent').click() - cy.contains('Confirm').click() - cy.contains('Your user does not have sufficient rights to perform this action. Please contact your administrator.') - }) -}) diff --git a/tests/ui/cypress/specs/multi_user_openid_connect.js b/tests/ui/cypress/specs/multi_user_openid_connect.js deleted file mode 100644 index cf8c1b21..00000000 --- a/tests/ui/cypress/specs/multi_user_openid_connect.js +++ /dev/null @@ -1,424 +0,0 @@ -// Matches daemon::auth::providers::openid_connect::http_client::openid_connect_provider_timeout() when test mode is -// enabled. -const KRILL_TEST_HTTP_CLIENT_TIMEOUT_SECS = 5; - -// The mock OpenID Connect provider only checks usernames, not passwords. -const admin = { u: 'adm@krill' } -const readonly = { u: 'ro@krill' } -const readwrite = { u: 'rw@krill' } -const shorttoken = { u: 'shorttokenwithoutrefresh@krill' } -const shortrefresh = { u: 'shorttokenwithrefresh@krill' } -const badidtoken = { u: 'non-spec-compliant-idtoken-payload' } -const badrole = { u: 'user-with-unknown-role' } -const refreshinvalidrequest = { u: 'user-with-invalid-request-on-refresh' } -const refreshinvalidclient = { u: 'user-with-invalid-client-on-refresh' } -const wrongcsrfstate = { u: 'user-with-wrong-csrf-state-value' } -const ca_name = 'dummy-ca-name' - -// d: description, u: user, o: outcome, fm: failure mode, r: role -const login_test_settings = [ - { d: 'empty', u: '', o: false }, - { d: 'incorrect', u: 'wrong_user_name', o: false, fm: 'unknown_user' }, - { d: 'admin', u: admin.u, o: true, r: 'admin' }, - { d: 'readonly', u: readonly.u, o: true, r: 'readonly' }, - { d: 'readwrite', u: readwrite.u, o: true, r: 'readwrite' }, - { d: 'badidtoken', u: badidtoken.u, o: false, fm: 'malformed_id_token' }, - { d: 'badrole', u: badrole.u, o: false }, - { d: 'wrongcsrfstate', u: wrongcsrfstate.u, o: false, fm: 'wrong_csrf_state' }, -] - -// o: outcome -const short_token_test_settings = [ - { ca: 'some-handle-name', o: true, token_secs: 5, create_ca_after_secs: 0 }, // should succeed with a freshly issued token - { ca: 'some-other-handle-name', o: true, token_secs: 10, create_ca_after_secs: 5 }, // should succeed with a token due to expire but not yet expired - { ca: 'yet-another-handle-name', o: false, token_secs: 5, create_ca_after_secs: 10 }, // should fail after token expiration -] - -// fm: failure mode -const create_ca_settings_401 = [ - 'invalid_request', - 'invalid_grant', - 'invalid_client', - 'http_500', - 'http_503', -].map((fm) => ({ - fm: fm, - responseCode: 401, -})) - -// fm: failure mode -const create_ca_settings_403 = [ - 'unauthorized_client', - 'invalid_scope', - 'unsupported_grant_type', -].map((fm) => ({ - fm: fm, - responseCode: 403, -})) - -describe('OpenID Connect provider with RP-Initiated logout', () => { - it('The correct login form is shown', () => { - // cy.intercept({ method: 'GET', path: '/api/v1/authorized'}).as('isAuthorized') - // cy.intercept({ method: 'GET', path: '/auth/login'}).as('getLoginURL') - // cy.intercept({ method: 'GET', url: /^https:\/\/localhost:1818\/authorize.+/}).as('oidcLoginForm') - cy.visit('/') - // cy.wait(['@isAuthorized', '@getLoginURL', '@oidcLoginForm']) - - // make sure we haven't been redirected away from Krill (as would be the - // case if an OpenID Connect login form were shown) - cy.url().should('not.include', Cypress.config('baseUrl')) - - // make sure that this is our mock OpenID Connect provider - cy.contains('Mock OpenID Connect login form') - - // check that a username input field is shown on the page - cy.get('input[name="username"]') - }) - - login_test_settings.forEach(function (ts) { - it( - 'Login with ' + - ts.d + - ' credentials should ' + - (ts.o ? 'succeed with the expected user info' : 'fail with the expected error'), - () => { - cy.visit('/') - cy.url().should('not.include', Cypress.config('baseUrl')) - cy.contains('Mock OpenID Connect login form') - - // Login, and while doing so specify the behaviour we want the OpenID Connect mock to exhibit for this user - if (ts.u != '') { - cy.get('input[name="username"]').clear().type(ts.u) - } - if (ts.fm) { - // Cause the mock to exhibit the requested failure mode - cy.get('select[name="failure_mode"]').select(ts.fm) - } - if (ts.r) { - // Force the mock to respond with a role attribute for this user - cy.get('input[name="userattr1"]').clear().type('role') - cy.get('input[name="userattrval1"]').clear().type(ts.r) - } - - cy.contains('Sign In').click() - - // We should end up back in the Krill UI - cy.url().should('include', Cypress.config('baseUrl')) - - if (ts.o) { - // A good outcome, i.e. login should have succeeded - cy.contains('Sign In').should('not.exist') - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains(ts.u) - cy.get('#userinfo_table').contains(ts.r) // assumes that ts.r is not a substring of ts.u - - // check the source="config-file" "extra" property claim mapping - // for the only user for which a value is defined in krill.conf: 'admin' - if (ts.d == 'admin') { - cy.get('#userinfo_table').contains('extra_val') - } - } else if (ts.d == 'badidtoken') { - cy.contains('OpenID Connect: Code exchange failed: Failed to parse server response') - cy.contains('return to the login page') - } else if (ts.d == 'badrole') { - cy.contains( - 'Your user does not have sufficient rights to perform this action. Please contact your administrator.' - ) - cy.contains('return to the login page') - } else if (ts.d == 'wrongcsrfstate') { - cy.contains('CSRF token mismatch') - } else { - cy.contains('The supplied login credentials were incorrect') - cy.contains('return to the login page') - } - } - ) - }) - - it('Can logout', () => { - // login - cy.visit('/') - cy.url().should('not.include', Cypress.config('baseUrl')) - cy.contains('Mock OpenID Connect login form') - cy.get('input[name="username"]').clear().type(admin.u) - cy.get('input[name="userattr1"]').clear().type('role') // a role is required to be able to login - cy.get('input[name="userattrval1"]').clear().type('admin') - cy.contains('Sign In').click() - - // verify that we are shown to be logged in to the Krill UI - cy.contains('Sign In').should('not.exist') - cy.url().should('include', Cypress.config('baseUrl')) - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains(admin.u) - - // verify that the mock provider thinks the user is logged in - cy.request({ url: 'https://127.0.0.1:1818/test/is_user_logged_in?username=' + admin.u, failOnStatusCode: false }).its('status').should('eq', 200) - - // logout - cy.intercept({ method: 'GET', url: /^https:\/\/localhost:1818\/logout.+/}).as('oidcLogout') - cy.get('.logout').click() - cy.wait('@oidcLogout').its('response.statusCode').should('eq', 302) - - // verify that the mock provider thinks the user is now logged out - cy.request({ url: 'https://127.0.0.1:1818/test/is_user_logged_in?username=' + admin.u, failOnStatusCode: false }).its('status').should('eq', 400) - - // verify that we are shown the OpenID Connect provider login page - cy.url().should('not.include', Cypress.config('baseUrl')) - cy.contains('Mock OpenID Connect login form') - cy.get('input[name="username"]') - }) - - it('Login with short-lived non-refreshable token and try to refresh page', () => { - // login - cy.visit('/') - cy.url().should('not.include', Cypress.config('baseUrl')) - cy.contains('Mock OpenID Connect login form') - cy.get('input[name="username"]').clear().type(shorttoken.u) - cy.get('input[name="userattr1"]').clear().type('role') // a role is required to be able to login - cy.get('input[name="userattrval1"]').clear().type('readwrite') - cy.get('input[name="refresh"]').uncheck() // prevent issuing of refresh tokens for this user - cy.contains('Sign In').click() - - // verify that we are shown to be logged in to the Krill UI - cy.contains('Sign In').should('not.exist') - cy.url().should('include', Cypress.config('baseUrl')) - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains(shorttoken.u) - - // the token has a lifetime of 5 second and no refresh token - // wait 6 seconds... - // note: a shorter token with a 1 second lifetime doesn't work in the GitHub - // Action runner environment because the token has sometimes already expired - // by the time Krill verifies it! - cy.wait(6000) - - // verify that if we reload the Krill UI we are shown the OpenID Connect - // provider login page - // cy.intercept({ method: 'GET', path: '/auth/login'}).as('getLoginURL') - // cy.intercept({ method: 'GET', url: /^https:\/\/localhost:1818\/authorize.+/}).as('oidcLoginForm') - cy.visit('/') - // cy.wait(['@getLoginURL', '@oidcLoginForm']) - cy.url().should('not.include', Cypress.config('baseUrl')) - cy.contains('Mock OpenID Connect login form') - }) - - short_token_test_settings.forEach((ts) => - it('Login with short-lived non-refreshable token and try to create a CA after ' + ts.create_ca_after_secs + ' out of ' + ts.token_secs + ' secs' + ' should ' + (ts.o ? 'succeed' : 'fail'), () => { - // note: a short token with a 1 second lifetime doesn't work in the GitHub - // Action runner environment because the token has sometimes already expired - // by the time Krill verifies it! And we also want to test that we still have - // rights when less than half the token lifetime is remaining (as at this - // point Krill switches from considering the token to be ACTIVE to NEEDS - // REFRESH), and for a short lifetime like 5 seconds window in which to time - // the test to check after 3 seconds but before 5 seconds is just too small, - // so we use a longer lifetime for this test. - - // login - cy.visit('/') - cy.url().should('not.include', Cypress.config('baseUrl')) - cy.contains('Mock OpenID Connect login form') - cy.get('input[name="username"]').clear().type(shorttoken.u + '_delay_' + ts.create_ca_after_secs) - cy.get('input[name="userattr1"]').clear().type('role') // a role is required to be able to login - cy.get('input[name="userattrval1"]').clear().type('readwrite') - cy.get('input[name="userattr2"]').clear().type('inc_cas') // force the create CA welcome page to show - cy.get('input[name="userattrval2"]').clear().type(ts.ca) // (by making Lagosta think there are no CAs) - cy.get('input[name="refresh"]').uncheck() // prevent issuing of refresh tokens for this user - cy.get('input[name="token_secs"]').clear().type(ts.token_secs) // control the lifetime of the issued access token - cy.contains('Sign In').click() - - // record the approximate time at which the token was issued - let issued_at_ms = Date.now() - - // verify that we are shown to be logged in to the Krill UI - cy.contains('Sign In').should('not.exist') - cy.url().should('include', Cypress.config('baseUrl')) - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains(shorttoken.u) - - // verify that we are shown the CA create page - cy.contains('Welcome to Krill') - - // calculate the remaining time necessary to wait until the - // create_ca_after_secs moment - let time_elapsed_ms = Date.now() - issued_at_ms - let time_remaining_ms = ts.create_ca_after_secs*1000 - time_elapsed_ms - cy.wait(time_remaining_ms) - - // Try to create a CA, by typing in the input, clicking the 'Create CA' button - // and then clicking 'Ok'. This should fail, since the token can't be refreshed. - cy.intercept({ method: 'POST', path: '/api/v1/cas'}).as('createCA') - cy.contains('CA Handle') - cy.get('form input[type="text"]').type(ts.ca) - cy.contains('Create CA').click() - cy.contains('OK').click() - - if (ts.o) { - cy.wait('@createCA').its('response.statusCode').should('eq', 200) - } else { - cy.wait('@createCA').its('response.statusCode').should('eq', 401) - cy.contains('Your login session has expired. Please login again.') - } - }) - ); - - [...create_ca_settings_401, ...create_ca_settings_403].forEach((ts) => - it('Try to create a CA with mock failure mode ' + ts.fm + ' enabled', () => { - let user_name = 'user_' + ts.fm; - let ca_name = 'some-unique-handle-name-' + Date.now(); - - // login - cy.visit('/') - cy.url().should('not.include', Cypress.config('baseUrl')) - cy.contains('Mock OpenID Connect login form') - cy.get('input[name="username"]').clear().type(user_name) - cy.get('input[name="userattr1"]').clear().type('role') // a role is required to be able to login - cy.get('input[name="userattrval1"]').clear().type('readwrite') - cy.get('input[name="userattr2"]').clear().type('inc_cas') // force the create CA welcome page to show - cy.get('input[name="userattrval2"]').clear().type(ca_name) // (by making Lagosta think there are no CAs) - cy.get('select[name="failure_mode"]').select(ts.fm) - cy.get('select[name="failure_endpoint"]').select('token') - cy.contains('Sign In').click() - - // verify that we are shown to be logged in to the Krill UI - cy.contains('Sign In').should('not.exist') - cy.url().should('include', Cypress.config('baseUrl')) - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains(user_name) - - // verify that we are shown the create CA welcome page - cy.contains('Welcome to Krill') - - // the token has a lifetime of 5 second and no refresh token - // wait 6 seconds... - // note: a shorter token with a 1 second lifetime doesn't work in the GitHub - // Action runner environment because the token has sometimes already expired - // by the time Krill verifies it! - cy.wait(6000) - - // Try to create a CA, by typing in the input, clicking the 'Create CA' button - // and then clicking 'Ok'. This should fail, since the mock server should return a - // exhibit the undesirable behaviour we configured which should result in an - // error from Krill. - cy.intercept({ method: 'POST', path: '/api/v1/cas'}).as('createCA') - cy.contains('CA Handle') - cy.get('form input[type="text"]').type(ca_name) - cy.contains('Create CA').click() - cy.contains('OK').click() - - cy.wait('@createCA').its('response.statusCode').should('eq', ts.responseCode) - }) - ) - - it('Login with short-lived refreshable token and try to refresh page', () => { - let token_secs = 2; - - // login - cy.visit('/') - cy.url().should('not.include', Cypress.config('baseUrl')) - cy.contains('Mock OpenID Connect login form') - cy.get('input[name="username"]').clear().type(shortrefresh.u) - cy.get('input[name="userattr1"]').clear().type('role') // a role is required to be able to login - cy.get('input[name="userattrval1"]').clear().type('readonly') - cy.get('input[name="token_secs"]').clear().type(token_secs) // control the lifetime of the issued access token - cy.contains('Sign In').click() - - // verify that we are shown to be logged in to the Krill UI - cy.contains('Sign In').should('not.exist') - cy.url().should('include', Cypress.config('baseUrl')) - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains(shortrefresh.u) - - for (let i = 0; i < 5; i++) { - // the token has a lifetime of 2 seconds and has a refresh token - // wait 3 seconds.. - // note: a shorter token with a 1 second lifetime doesn't work in the - // GitHub Action runner environment because the token has sometimes - // already expired by the time Krill verifies it! - cy.wait(1000 * (token_secs + 1)) - - // verify that we are still logged in to Krill - cy.visit('/') - cy.url().should('include', Cypress.config('baseUrl')) - cy.contains('Sign In').should('not.exist') - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains(shortrefresh.u) - } - }); - - [-2, +2].forEach((timeout_adjust_secs) => - it('Slow provider response (' + (timeout_adjust_secs < 0 ? 'within' : 'beyond') + ' Krill HTTP client timeout) is handled correctly', () => { - let name_prefix = 'slow-response-'; - let name_postfix = (timeout_adjust_secs < 0 ? 'within' : 'beyond') + '-krill-max'; - let user_name = name_prefix + name_postfix; - let ca_name = name_prefix + 'ca-' + name_postfix; - let delay_secs = KRILL_TEST_HTTP_CLIENT_TIMEOUT_SECS + timeout_adjust_secs; - - // Pick a token expiration time that is not too long so we don't have to wait unnecessarily, but not too short as - // on a slow system like GitHub Actions it can take a few seconds just for login to complete and then one of the - // static asset fetches from the browser to Krill causes the token refresh attempt to occur already (and we don't - // want it to occur until we try to create a CA). - let token_secs = 5; - - // login - cy.visit('/') - cy.url().should('not.include', Cypress.config('baseUrl')) - cy.contains('Mock OpenID Connect login form') - cy.get('input[name="username"]').clear().type(user_name) - cy.get('input[name="userattr1"]').clear().type('role') // a role is required to be able to login - cy.get('input[name="userattrval1"]').clear().type('readwrite') - cy.get('input[name="userattr2"]').clear().type('inc_cas') // force the create CA welcome page to show - cy.get('input[name="userattrval2"]').clear().type(ca_name) // (by making Lagosta think there are no CAs) - cy.get('select[name="failure_mode"]').select('slow_response') - cy.get('select[name="failure_endpoint"]').select('token') - cy.get('input[name="failure_param"]').clear().type(delay_secs) // control the delay at the provider - cy.get('input[name="token_secs"]').clear().type(token_secs) // control the lifetime of the issued access token - cy.contains('Sign In').click() - - // record the approximate time at which the token was issued - let issued_at_ms = Date.now() - - // verify that we are shown to be logged in to the Krill UI - cy.contains('Sign In').should('not.exist') - cy.url().should('include', Cypress.config('baseUrl')) - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains(user_name) - - // verify that we are shown the create CA welcome page - cy.contains('Welcome to Krill') - - // wait for the access token issued to Krill to expire so that it is forced to use the provider token endpoint to - // exchange the refresh token for a new access token - let time_elapsed_ms = Date.now() - issued_at_ms - let time_till_after_expiration_ms = (token_secs * 1000) - time_elapsed_ms + 1000 - cy.log('Waiting ' + time_till_after_expiration_ms + 'ms until the Krill access token ' + token_secs*1000 + 'ms expiration point should have passed') - cy.wait(time_till_after_expiration_ms) - - // Try to create a CA, by typing in the input, clicking the 'Create CA' button and then clicking 'Ok'. - cy.intercept({ method: 'POST', path: '/api/v1/cas'}).as('createCA') - cy.contains('CA Handle') - cy.get('form input[type="text"]').type(ca_name) - cy.contains('Create CA').click() - cy.contains('OK').click() - - // Verify that the attempt to create the CA occurred. - // - // In the case where we configure the provider to respond slowly, but still within the Krill HTTP client timeout, - // the CA creation attempt should be successful, and the response should have a new bearer token piggybacked on it - // (which resulted from the token refresh attempt). - // - // In the case where we configure the provider to take longer to respond than Krill will wait, the CA creation - // attempt should fail because Krill should have been unable to refresh its expired access token and thus should - // deny the CA creation request. - let expected_status_code = (timeout_adjust_secs < 0 ? 200 : 401); - let time_till_after_provider_delay_is_over_ms = delay_secs * 1000; - let time_to_wait_ms = time_till_after_provider_delay_is_over_ms + 3000; - if (timeout_adjust_secs < 0) { - cy.log('Expecting within ' + time_till_after_provider_delay_is_over_ms + 'ms the provider to finish delaying and for Krill to create the CA') - } else { - cy.log('Expecting Krill to timeout the provider before the ' + time_till_after_provider_delay_is_over_ms + 'ms remaining provider delay elapses') - } - cy.log('Waiting max ' + time_to_wait_ms + 'ms for Krill to respond to the CA create request') - cy.wait('@createCA', { responseTimeout: time_to_wait_ms }).its('response.statusCode').should('eq', expected_status_code) - }) - ) -}) diff --git a/tests/ui/cypress/specs/multi_user_openid_connect_provider_not_available.js b/tests/ui/cypress/specs/multi_user_openid_connect_provider_not_available.js deleted file mode 100644 index c744419d..00000000 --- a/tests/ui/cypress/specs/multi_user_openid_connect_provider_not_available.js +++ /dev/null @@ -1,61 +0,0 @@ -describe('OpenID Connect provider connection issues are tolerated', () => { - it('The login form should not be available', () => { - cy.request('POST', 'https://127.0.0.1:1818/test/disable') - cy.wait(500) - - cy.visit('/') - cy.url().should('include', Cypress.config('baseUrl')) - cy.contains('Mock OpenID Connect login form').should('not.exist') - cy.contains('An error occurred while logging you in: OpenID Connect: Cannot get login URL: Failed to connect to provider') - }) - - it('Login and logout should succeed', () => { - cy.request('POST', 'https://127.0.0.1:1818/test/enable') - cy.wait(500) - - // Login - cy.visit('/') - cy.url().should('not.include', Cypress.config('baseUrl')) - cy.contains('Mock OpenID Connect login form') - cy.get('input[name="username"]').clear().type('admin') - cy.get('input[name="userattr1"]').clear().type('role') // a role is required to be able to login - cy.get('input[name="userattrval1"]').clear().type('admin') - cy.contains('Sign In').click() - - // verify that we are shown to be logged in to the Krill UI - cy.contains('Sign In').should('not.exist') - cy.url().should('include', Cypress.config('baseUrl')) - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains('admin') - - // verify that the mock provider thinks the user is logged in - cy.request({ url: 'https://127.0.0.1:1818/test/is_user_logged_in?username=admin', failOnStatusCode: false }).its('status').should('eq', 200) - - // logout - cy.intercept({ method: 'GET', url: /^https:\/\/localhost:1818\/logout.+/}).as('oidcLogout') - cy.get('.logout').click() - cy.wait('@oidcLogout').its('response.statusCode').should('eq', 302) - - // verify that the mock provider thinks the user is now logged out - cy.request({ url: 'https://127.0.0.1:1818/test/is_user_logged_in?username=admin', failOnStatusCode: false }).its('status').should('eq', 400) - - // verify that we are shown the OpenID Connect provider login page - cy.url().should('not.include', Cypress.config('baseUrl')) - cy.contains('Mock OpenID Connect login form') - cy.get('input[name="username"]') - }) - - it('Login should fail to redirect to the discovered but unavailable login page', () => { - cy.request('POST', 'https://127.0.0.1:1818/test/disable') - cy.wait(500) - cy.visit('/') - }) - - it('The login page should be reachable again', () => { - cy.request('POST', 'https://127.0.0.1:1818/test/enable') - cy.wait(500) - cy.visit('/') - cy.url().should('not.include', Cypress.config('baseUrl')) - cy.contains('Mock OpenID Connect login form') - }) -}) \ No newline at end of file diff --git a/tests/ui/cypress/specs/multi_user_openid_connect_provider_with_custom_logout.js b/tests/ui/cypress/specs/multi_user_openid_connect_provider_with_custom_logout.js deleted file mode 100644 index ae7ace43..00000000 --- a/tests/ui/cypress/specs/multi_user_openid_connect_provider_with_custom_logout.js +++ /dev/null @@ -1,35 +0,0 @@ -let username = 'admin@krill'; - -describe('OpenID Connect provider with custom logout URL', () => { - it('Logout when logged in behaves as expected', () => { - cy.visit('/') - cy.url().should('not.include', Cypress.config('baseUrl')) - cy.contains('Mock OpenID Connect login form') - cy.get('input[name="username"]').clear().type(username) - cy.get('input[name="userattr1"]').clear().type('role') // a role is required to be able to login - cy.get('input[name="userattrval1"]').clear().type('admin') - cy.contains('Sign In').click() - - // We should end up back in the Krill UI - cy.url().should('include', Cypress.config('baseUrl')) - cy.contains('Sign In').should('not.exist') - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains(username) - cy.get('#userinfo_table').contains("role") - - // verify that the mock provider thinks the user is logged in - cy.request('https://127.0.0.1:1818/test/is_user_logged_in?username=' + username).its('status').should('eq', 200) - - // logout - cy.intercept('https://example.net/', 'custom logout page requested').as('getCustomLogoutURL') - cy.get('.logout').click() - - // verify that we are directed to the custom logout URL stub - cy.wait('@getCustomLogoutURL').its('response.statusCode').should('eq', 200) - cy.url().should('eq', 'https://example.net/') - - // verify that the mock provider thinks the user is STILL logged in because due to the use of a custom logout URL - // we deliberately did NOT tell the OpenID Connect mock provider that the user should be logged out - cy.request('https://127.0.0.1:1818/test/is_user_logged_in?username=' + username).its('status').should('eq', 200) - }) -}) \ No newline at end of file diff --git a/tests/ui/cypress/specs/multi_user_openid_connect_provider_with_fallback_logout.js b/tests/ui/cypress/specs/multi_user_openid_connect_provider_with_fallback_logout.js deleted file mode 100644 index 6392d4dc..00000000 --- a/tests/ui/cypress/specs/multi_user_openid_connect_provider_with_fallback_logout.js +++ /dev/null @@ -1,40 +0,0 @@ -let username = 'admin@krill'; - -describe('OpenID Connect provider with fallback logout URL', () => { - it('Logout when logged in behaves as expected', () => { - cy.visit('/') - cy.url().should('not.include', Cypress.config('baseUrl')) - cy.contains('Mock OpenID Connect login form') - cy.get('input[name="username"]').clear().type(username) - cy.get('input[name="userattr1"]').clear().type('role') // a role is required to be able to login - cy.get('input[name="userattrval1"]').clear().type('admin') - cy.contains('Sign In').click() - - // We should end up back in the Krill UI - cy.url().should('include', Cypress.config('baseUrl')) - cy.contains('Sign In').should('not.exist') - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains(username) - cy.get('#userinfo_table').contains("role") - - // verify that the mock provider thinks the user is logged in - cy.request('https://127.0.0.1:1818/test/is_user_logged_in?username=' + username).its('status').should('eq', 200) - - // logout - cy.intercept({ method: 'POST', path: '/auth/logout'}).as('getLogoutURL') - cy.intercept({ method: 'GET', path: '/index.html'}).as('getLoginForm') - cy.get('.logout').click() - - // verify that we are shown the OpenID Connect provider login page - cy.wait('@getLogoutURL').its('response.statusCode').should('eq', 200) - cy.wait('@getLoginForm').its('response.statusCode').should('eq', 200) - cy.url().should('not.include', Cypress.config('baseUrl')) - cy.contains('Mock OpenID Connect login form') - cy.get('input[name="username"]') - - // verify that the mock provider thinks the user is STILL logged in because due to the OpenID Connect mock being - // configured to NOT support end_session_endpoint or revocation_endpoint there is no way to tell the mock that we - // are logging the user out - cy.request('https://127.0.0.1:1818/test/is_user_logged_in?username=' + username).its('status').should('eq', 200) - }) -}) \ No newline at end of file diff --git a/tests/ui/cypress/specs/multi_user_openid_connect_provider_with_revocation.js b/tests/ui/cypress/specs/multi_user_openid_connect_provider_with_revocation.js deleted file mode 100644 index 3c6d94e0..00000000 --- a/tests/ui/cypress/specs/multi_user_openid_connect_provider_with_revocation.js +++ /dev/null @@ -1,61 +0,0 @@ -let login_test_settings = [ - { u: 'shorttokenwithrefresh@krill', o: true, refresh: true }, - { u: 'shorttokenwithoutrefresh@krill', o: false, refresh: false } -]; - -describe('OpenID Connect provider with OAuth 2 revocation', () => { - login_test_settings.forEach(function (ts) { - it('Logout when logged in as user ' + ts.u + ' should ' + (ts.o ? 'successfully' : 'fail to') + ' revoke the token', () => { - cy.intercept({ url: /^https:\/\/localhost:1818\/authorize/ }).as('getLoginForm') - cy.intercept({ url: /^https:\/\/localhost:1818\/login_form_submit/ }).as('submitLoginForm') - cy.intercept({ url: /^https:\/\/localhost:3000\/auth\/callback/ }).as('completeTheLoginInKrill') - cy.intercept({ url: /^https:\/\/localhost:3000\/index\.html/ }).as('afterLoginCompleteInKrill') - - cy.visit('/') - cy.url().should('not.include', Cypress.config('baseUrl')) - cy.contains('Mock OpenID Connect login form') - cy.get('input[name="username"]').clear().type(ts.u) - cy.get('input[name="userattr1"]').clear().type('role') // a role is required to be able to login - cy.get('input[name="userattrval1"]').clear().type('readonly') - if (ts.refresh) { - cy.get('input[name="refresh"]').check() // ensure issuing of refresh tokens for this user - } else { - cy.get('input[name="refresh"]').uncheck() // prevent issuing of refresh tokens for this user - } - cy.contains('Sign In').click() - - cy.wait(['@getLoginForm', '@submitLoginForm', '@completeTheLoginInKrill', '@afterLoginCompleteInKrill']) - - // We should end up back in the Krill UI - cy.url().should('include', Cypress.config('baseUrl')) - cy.contains('Sign In').should('not.exist') - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains(ts.u) - cy.get('#userinfo_table').contains("role") - - // verify that the mock provider thinks the user is logged in - cy.request({ url: 'https://127.0.0.1:1818/test/is_user_logged_in?username=' + ts.u, failOnStatusCode: false }).its('status').should('eq', 200) - - // logout, and thus trigger the invocation of the OAuth 2.0 token revocation endpoint - // for users with both a refresh token and an access token first Krill will try to revoke the refresh token - // then will retry if that fails with the access token - cy.intercept({ url: /^https:\/\/localhost:3000\/auth\/logout/ }).as('getLogoutURL') - cy.get('.logout').click() - - // verify that we are shown the OpenID Connect provider login page - cy.wait('@getLogoutURL').its('response.statusCode').should('eq', 200) - cy.url().should('not.include', Cypress.config('baseUrl')) - cy.contains('Mock OpenID Connect login form') - cy.get('input[name="username"]') - - if (ts.o) { - // verify that the mock provider thinks the user is now logged out - cy.request({ url: 'https://127.0.0.1:1818/test/is_user_logged_in?username=' + ts.u, failOnStatusCode: false }).its('status').should('eq', 400) - } else { - // verify that the mock provider thinks the user is still logged in (because it only supports revocation by - // refresh token, not by access token) - cy.request({ url: 'https://127.0.0.1:1818/test/is_user_logged_in?username=' + ts.u, failOnStatusCode: false }).its('status').should('eq', 200) - } - }) - }) -}) \ No newline at end of file diff --git a/tests/ui/cypress/specs/multi_user_team_based_access.js b/tests/ui/cypress/specs/multi_user_team_based_access.js deleted file mode 100644 index b3a7842d..00000000 --- a/tests/ui/cypress/specs/multi_user_team_based_access.js +++ /dev/null @@ -1,56 +0,0 @@ -// Team names and CAs they can access are defined in doc/policies/team-based-access-demo.polar. -// Team memberships and user roles within teams are defined in test-resources/ui/multi_user_team_based_access.conf. -// This test verifies that team roles and team CA rights work as expected, as defined in those files. - -// A note about strong password hashing login delays -// ----------------------------------------------------------------------------- -// The strong password hashing on the client and server side when logging in with -// config file users causes the login process to take a few seconds. As such we -// extend the default timeout when checking for Sign In completion, like so: -// -// cy.contains('Sign In', { timeout: 10000 }).should('not.exist') - -let t1ro = { u: 'team1ro@krill', p: 'team1ro' }; -let t1rw = { u: 'team1rw@krill', p: 'team1rw' }; -let t2ro = { u: 'team2ro@krill', p: 'team2ro' }; -let t2rw = { u: 'team2rw@krill', p: 'team2rw' }; - -let create_ca_test_settings = [ - { d: 't1ro', u: t1ro.u, p: t1ro.p, o: false, ca: 'ca1', t: 'Red Team', tr: 'Read Only' }, - { d: 't1rw', u: t1rw.u, p: t1rw.p, o: true, ca: 'ca1', t: 'Red Team', tr: 'Read Write' }, - { d: 't2ro', u: t2ro.u, p: t2ro.p, o: false, ca: 'ca2', t: 'Blue Team', tr: 'Read Only' }, - { d: 't2rw', u: t2rw.u, p: t2rw.p, o: true, ca: 'ca2', t: 'Blue Team', tr: 'Read Write' }, -]; - -describe('Config File users with custom team policy', () => { - create_ca_test_settings.forEach(function (ts) { - it('Create CA as ' + ts.d + ' user should ' + (ts.o ? 'succeed' : 'fail'), () => { - cy.visit('/') - cy.get('#login_id').type(ts.u) - cy.get('#login_password').type(ts.p) - cy.contains('Sign In').click() - cy.contains('Sign In', { timeout: 10000 }).should('not.exist') - cy.contains(ts.u) - cy.contains('Welcome to Krill') - - // verify our team and role - cy.get('#userinfo') - cy.get('#userinfo').click() - cy.get('#userinfo_table').contains(ts.t) - cy.get('#userinfo_table').contains(ts.tr) - - // create a CA - cy.contains('CA Handle') - cy.get('form input[type="text"]').type(ts.ca) - cy.contains('Create CA').click() - cy.contains('OK').click() - - // no longer on the welcome page - if (ts.o) { - cy.contains('Welcome to Krill').should('not.exist') - } else { - cy.contains('Welcome to Krill') - } - }) - }) -}) \ No newline at end of file diff --git a/tests/ui/cypress/specs/testbed_ui.js b/tests/ui/cypress/specs/testbed_ui.js deleted file mode 100644 index 5840438c..00000000 --- a/tests/ui/cypress/specs/testbed_ui.js +++ /dev/null @@ -1,99 +0,0 @@ -// Difficulty entering XML into Lagosta XML input fields: -// ------------------------------------------------------ -// Using cy.type() to enter XML into these fields is extremely slow, one -// animated character at a time. I haven't yet found a way to copy-paste into -// them. Setting the text directly can be done but there is a challenge that has -// to be worked around which is that the fields use Prism Editor JS to syntax -// highlight the XML. Prism Editor manages the content as a rich HTML child node -// structure. Just replacing the content with a new text node doesn't work as -// the Lagosta JS code reading the field content doesn't get the content as -// set for some reason. The set text also doesn't get syntax highlighted. What -// seems to work however is causing a keyboard event in the field after the text -// has been set, e.g. pressing the End key. -// -// To summarize, the following works quickly: -// cy.get('... pre[contenteditable="true"]').invoke('text', xml) -// cy.get('... pre[contenteditable="true"]').type('{end}') -// -// This is less hacky but very slow: (even with "type(xml, {delay: 0}))") -// cy.get('... pre[contenteditable="true"]').clear().type(xml) - -let publisher_request_test_settings = [ - { desc: 'Compact publisher request XML is accepted', fixture: 'testbed/publisher_request_compact.xml', httpCode: 200 }, - { desc: 'Publisher request with whitespace is accepted', fixture: 'testbed/publisher_request_with_whitespace.xml', httpCode: 200 }, - { desc: 'Publisher request with invalid Base64 certificate is rejected by Lagosta', fixture: 'testbed/publisher_request_invalid_base64.xml', httpCode: 'n/a', errMsg: 'Element must contain a correctly Base64 encoded self-signed X.509 BPKI certificate' }, - { desc: 'Publisher request with unicode space char is rejected by Lagosta', fixture: 'testbed/publisher_request_with_unicode_space_char.xml', httpCode: 'n/a', errMsg: 'Element cannot contain non-ASCII characters' }, - { desc: 'Publisher request with unicode space entity reference is rejected by Lagosta', fixture: 'testbed/publisher_request_with_unicode_space_entity_reference.xml', httpCode: 'n/a', errMsg: 'Element cannot contain non-ASCII characters' }, - { desc: 'Publisher request with unicode space entity reference in handle is rejected by Krill', fixture: 'testbed/publisher_request_with_unicode_space_entity_reference_in_handle.xml', httpCode: 400, errMsg: 'Input contains non-ASCII chars (maybe whitespace?)' }, -]; - -let child_request_test_settings = [ - { desc: 'Compact child request XML is accepted', fixture: 'testbed/child_request_compact.xml', httpCode: 200 }, - { desc: 'Child request with whitespace is accepted', fixture: 'testbed/child_request_with_whitespace.xml', httpCode: 200 }, - { desc: 'Child request with invalid Base64 certificate is rejected by Lagosta', fixture: 'testbed/child_request_invalid_base64.xml', httpCode: 'n/a', errMsg: 'Element must contain a correctly Base64 encoded self-signed X.509 BPKI certificate' }, - { desc: 'Child request with unicode space char is rejected by Lagosta', fixture: 'testbed/child_request_with_unicode_space_char.xml', httpCode: 'n/a', errMsg: 'Element cannot contain non-ASCII characters' }, - { desc: 'Child request with unicode space entity reference is rejected by Lagosta', fixture: 'testbed/child_request_with_unicode_space_entity_reference.xml', httpCode: 'n/a', errMsg: 'Element cannot contain non-ASCII characters' }, - { desc: 'Child request with unicode space entity reference in handle is rejected by Krill', fixture: 'testbed/child_request_with_unicode_space_entity_reference_in_handle.xml', httpCode: 400, errMsg: 'Input contains non-ASCII chars (maybe whitespace?)' }, -]; - -describe('Testbed UI test', () => { - publisher_request_test_settings.forEach(function (ts) { - it(ts.desc, () => { - cy.fixture(ts.fixture).then((xml) => { - // use the local testbed UI to submit the request to register the publisher - cy.visit("/index.html#/testbed") - - // verify that the register child tab is active by default - cy.get('#addChild').contains('Child Request XML').should('be.visible') - - // enter the request XML into the testbed UI edit field - cy.get('div#tab-addPublisher').contains('Register Publisher').click() - cy.get('#addPublisher pre[contenteditable="true"]').invoke('text', xml) - cy.get('#addPublisher pre[contenteditable="true"]').type('{end}') - - cy.intercept({ method: 'POST', path: '/testbed/publishers'}).as('addPublisher') - cy.get('#addPublisher button').contains('Register publisher').click() - - if (ts.httpCode != 'n/a') { - cy.get('div[role="dialog"] button').contains('OK').click() - cy.wait('@addPublisher').its('response.statusCode').should('eq', ts.httpCode) - } - - if (ts.httpCode == 200) { - cy.contains('has been added to the testbed') - } else { - cy.contains(ts.errMsg) - } - }) - }) - }) - - child_request_test_settings.forEach(function (ts) { - it(ts.desc, () => { - cy.fixture(ts.fixture).then((xml) => { - // use the local testbed UI to submit the request to register the child - cy.visit("/index.html#/testbed") - - // enter the request XML into the testbed UI edit field - cy.get('div#tab-addChild').contains('Register CA').click() - cy.get('#addChild pre[contenteditable="true"]').invoke('text', xml) - cy.get('#addChild pre[contenteditable="true"]').type('{end}') - cy.get('#addChild input[placeholder^="The AS resources"]').type('AS18') - cy.get('#addChild input[placeholder^="The IPv4 resources"]').type('10.0.0.0/24') - - cy.intercept({ method: 'POST', path: '/testbed/children'}).as('addChild') - cy.get('#addChild button').contains('Register child CA').click() - - if (ts.httpCode != 'n/a') { - cy.get('div[role="dialog"] button').contains('OK').click() - cy.wait('@addChild').its('response.statusCode').should('eq', ts.httpCode) - } - if (ts.httpCode == 200) { - cy.contains('has been added to the testbed') - } else { - cy.contains(ts.errMsg) - } - }) - }) - }) -}) \ No newline at end of file diff --git a/tests/ui/cypress/support/index.js b/tests/ui/cypress/support/index.js deleted file mode 100644 index 8bc32991..00000000 --- a/tests/ui/cypress/support/index.js +++ /dev/null @@ -1,58 +0,0 @@ -// This file is loaded by Cypress because cypress.js (in the root of the Krill -// repository) sets "supportFile" to point to this file. -// -// As advised by Cypress *1, prevent Cypress sometimes failing tests due to -// error "ResizeObserver loop limit exceeded" errors. -// -// *1: jennifer@cypress.io aka https://github.com/jennifer-shehane who wrote -// the following at *2 which was linked from *3: -// -// const resizeObserverLoopErrRe = /^ResizeObserver loop limit exceeded/ -// -// Cypress.on('uncaught:exception', (err) => { -// if (resizeObserverLoopErrRe.test(err.message)) { -// // returning false here prevents Cypress from -// // failing the test -// return false -// } -// }) -// -// *2: https://github.com/quasarframework/quasar/issues/2233#issuecomment-492975745 -// *3: https://github.com/WICG/resize-observer/issues/38#issuecomment-493014026 -// -// See also: -// - https://github.com/cypress-io/cypress-example-recipes/blob/master/examples/fundamentals__errors/cypress/integration/app-error.js -// - https://docs.cypress.io/api/events/catalog-of-events.html#Uncaught-Exceptions -// - https://docs.cypress.io/guides/core-concepts/writing-and-organizing-tests.html#Support-file -// - https://stackoverflow.com/questions/49384120/resizeobserver-loop-limit-exceeded/63519375#63519375 -// - https://github.com/WICG/resize-observer/issues/38 - -// Define a custom uncaught exception handling policy for Cypress. -// Returning false prevents Cypress from failing the test. -Cypress.on('uncaught:exception', (err, runnable, promise) => { - console.log("Krill UI Test: Examining uncaught exception..") - console.log("Krill UI Test: err: ", err) - - if (promise) { - console.log("Krill UI Test: Ignoring unhandled promise rejection.") - return false - } - - if (err.message) { - if (err.message.includes('ResizeObserver loop limit exceeded')) { - console.log("Krill UI Test: Ignoring 'ResizeObserver loop limit exceeded' exception") - return false - } - if (err.message.includes('Redirected when going from')) { - // This happens when going from "/onboarding" to "/interstitial" via a navigation guard and is triggered - // when logging out of Krill. - // TODO: Is it safe to ignore this or is this pointing to a real bug in Lagosta? - console.log("Krill UI Test: Ignoring 'Redirected when going from' exception") - return false - } - } - - // on any other error message the test fails - console.log("Krill UI Test: Failing the test") -}) - diff --git a/tests/ui/mod.rs b/tests/ui/mod.rs deleted file mode 100644 index 97ab6a30..00000000 --- a/tests/ui/mod.rs +++ /dev/null @@ -1,175 +0,0 @@ -#[cfg(feature = "multi-user")] -mod openid_connect_mock; - -use tokio::task; -use OpenIDConnectMockMode::NotStarted; - -use std::process::Command; -use std::{env, process::ExitStatus}; - -use krill::daemon::config::Config; -use krill::test::*; - -#[allow(dead_code)] -#[derive(Copy, Clone)] -pub enum OpenIDConnectMockMode { - NotStarted, - WithRPInitiatedLogout, - WithOAuth2Revocation, - WithNoLogoutEndpoints, -} - -pub struct OpenIDConnectMockConfig { - mode: OpenIDConnectMockMode, - enabled_on_startup: bool, -} - -#[allow(dead_code)] -impl OpenIDConnectMockConfig { - /// Don't start the OpenID Connect mock. - pub fn do_not_start() -> OpenIDConnectMockConfig { - Self { - mode: NotStarted, - enabled_on_startup: false, - } - } - - /// Start the OpenID Mock and enable it ready for use. - pub fn enabled(mode: OpenIDConnectMockMode) -> OpenIDConnectMockConfig { - Self { - mode, - enabled_on_startup: true, - } - } - - /// Start the OpenID Mock initially disabled. This can be useful to prevent initial OpenID Connect Discovery - /// succeeding before the first test runs. - pub fn disabled(mode: OpenIDConnectMockMode) -> OpenIDConnectMockConfig { - Self { - mode, - enabled_on_startup: false, - } - } - - pub fn mode(&self) -> OpenIDConnectMockMode { - self.mode - } - - pub fn enabled_on_startup(&self) -> bool { - self.enabled_on_startup - } -} - -#[cfg(not(feature = "multi-user"))] -pub async fn run_krill_ui_test(test_name: &str, _: OpenIDConnectMockConfig) { - assert!(do_run_krill_ui_test(test_name).await); -} - -#[cfg(feature = "multi-user")] -pub async fn run_krill_ui_test(test_name: &str, openid_connect_mock_config: OpenIDConnectMockConfig) { - let op_handle = match openid_connect_mock_config.mode() { - NotStarted => None, - _ => Some(openid_connect_mock::start(openid_connect_mock_config, 1).await), - }; - - let test_result = do_run_krill_ui_test(test_name).await; - - if let Some(handle) = op_handle { - openid_connect_mock::stop(handle).await; - } - - assert!(test_result); -} - -struct CypressRunner { - status: ExitStatus, -} -impl CypressRunner { - pub async fn run(test_name: &str) -> Self { - let test_name = test_name.to_string(); - - ctrlc::set_handler(move || { - // If `cargo test` is stopped with CTRL-C the background Cypress Docker container continues to run. This - // prevents the next run of `cargo test` from working as the container unexpectedly already exists. Tell - // Docker to kill it to avoid leaving it lying around. - Command::new("docker") - .arg("kill") - .arg("cypress") - .spawn() - .expect("Failed to kill Cypress Docker container"); - }) - .expect("Error setting Ctrl-C handler"); - - let task = task::spawn_blocking(move || { - // NOTE: the directory mentioned here must be the same as the directory - // mentioned in the tests/ui/cypress/plugins/index.js file in the - // "integrationFolder" property otherwise Cypress mysteriously complains - // that it cannot find the spec file. - let cypress_spec_path = format!("tests/ui/cypress/specs/{}.js", test_name); - - let mut cmd = Command::new("docker"); - - cmd.arg("run") - .arg("--name") - .arg("cypress") - .arg("--rm") - .arg("--net=host") - .arg("--ipc=host") - .arg("-v") - .arg(format!("{}:/e2e", env::current_dir().unwrap().display())) - .arg("-w") - .arg("/e2e"); - - if let Ok(debug_level) = std::env::var("CYPRESS_DEBUG") { - // Example values: - // - To get LOTS of Cypress logging: CYPRESS_DEBUG=cypress:* - // - To get logging relating to HTTP requests: CYPRESS_DEBUG=cypress:proxy:http:* - cmd.arg("-e").arg(format!("DEBUG={}", debug_level)); - } - - if std::env::var("CYPRESS_INTERACTIVE").is_ok() { - // After running `cargo test` a Chrome browser should open from the Cypress Docker container on your local - // X server. For this to work you might need to run this command in your shell prior to `cargo test`: - // xhost + - cmd.arg("-v") - .arg("/tmp/.X11-unix:/tmp/.X11-unix") - .arg("-e") - .arg("DISPLAY") - .arg("--entrypoint") - .arg("cypress"); - } - - cmd.arg("cypress/included:8.1.0"); - - if std::env::var("CYPRESS_INTERACTIVE").is_ok() { - cmd.arg("open").arg("--project").arg("."); - } else { - cmd.arg("--spec").arg(cypress_spec_path); - } - - cmd.arg("--browser") - .arg("chrome") - .status() - .expect("Failed to run Cypress Docker UI test suite") - }) - .await; - - Self { status: task.unwrap() } - } - - pub fn success(self) -> bool { - self.status.success() - } -} - -async fn do_run_krill_ui_test(test_name: &str) -> bool { - krill::constants::enable_test_mode(); - let config_path = &format!("test-resources/ui/{}.conf", test_name); - let config = Config::read_config(config_path).unwrap(); - - // Start Krill as a Tokio task in the background and wait just until we can tell that it has started. - start_krill_with_custom_config(config).await; - - // Run the specified Cypress UI test suite and wait for it to finish - CypressRunner::run(test_name).await.success() -} diff --git a/tests/ui/openid_connect_mock.rs b/tests/ui/openid_connect_mock.rs deleted file mode 100644 index 912f9d34..00000000 --- a/tests/ui/openid_connect_mock.rs +++ /dev/null @@ -1,1354 +0,0 @@ -//! A mock implementation of an OpenID Connect 1.0 provider (OP) with support for the following specifications: -//! -//! - [The OAuth 2.0 Authorization Framework RFC 6749][rfc6749] -//! - [OAuth 2.0 Token Revocation RFC 7009][rfc7009] -//! - [OpenID Connect Core 1.0 incorporating errata set 1][openid-connect-core-1_0] -//! - [OpenID Connect Discovery 1.0 incorporating errata set 1][openid-connect-discovery-1_0] -//! - [OpenID Connect RP-Initiated Logout 1.0 - draft 01][openid-connect-rpinitiated-1_0] -//! -//! [rfc6749]: https://tools.ietf.org/html/rfc6749 -//! [rfc7009]: https://tools.ietf.org/html/rfc7009 -//! [openid-connect-core-1_0]: https://openid.net/specs/openid-connect-core-1_0.html -//! [openid-connect-discovery-1_0]: https://openid.net/specs/openid-connect-discovery-1_0.html -//! [openid-connect-rpinitiated-1_0]: https://openid.net/specs/openid-connect-rpinitiated-1_0.html -use log::{error, info, trace, warn}; -use openidconnect::core::*; -use openidconnect::PrivateSigningKey; -use openidconnect::*; -use openssl::rsa::Rsa; -use serde::ser::{Serialize as SerdeSerialize, SerializeStruct, Serializer as SerdeSerializer}; -use serde::{Deserialize, Serialize}; -use serde_json::json; -use tiny_http::{Header, Method, Request, Response, Server, StatusCode}; -use urlparse::{parse_qs, urlparse, GetQuery, Query, Url}; - -use tokio::task; -use tokio::time::sleep; - -use krill::commons::error::Error; - -use std::collections::HashMap; -use std::str::FromStr; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::thread; -use std::time::Duration; - -use crate::ui::{ - OpenIDConnectMockConfig, - OpenIDConnectMockMode::{self, *}, -}; - -#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] -pub struct CustomAdditionalMetadata { - end_session_endpoint: Option, - revocation_endpoint: Option, -} -impl AdditionalProviderMetadata for CustomAdditionalMetadata {} - -#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] -pub struct CustomAdditionalClaims { - role: Option, - inc_cas: Option, - exc_cas: Option, -} -impl AdditionalClaims for CustomAdditionalClaims {} - -// use the CustomAdditionalMetadata type -type CustomProviderMetadata = ProviderMetadata< - CustomAdditionalMetadata, - CoreAuthDisplay, - CoreClientAuthMethod, - CoreClaimName, - CoreClaimType, - CoreGrantType, - CoreJweContentEncryptionAlgorithm, - CoreJweKeyManagementAlgorithm, - CoreJwsSigningAlgorithm, - CoreJsonWebKeyType, - CoreJsonWebKeyUse, - CoreJsonWebKey, - CoreResponseMode, - CoreResponseType, - CoreSubjectIdentifierType, ->; - -// use the CustomAdditionalClaims type, has to be cascaded down a few nesting -// levels of OIDC crate types... -type CustomIdTokenClaims = IdTokenClaims; - -type CustomIdToken = IdToken< - CustomAdditionalClaims, - CoreGenderClaim, - CoreJweContentEncryptionAlgorithm, - CoreJwsSigningAlgorithm, - CoreJsonWebKeyType, ->; - -type CustomIdTokenFields = IdTokenFields< - CustomAdditionalClaims, - EmptyExtraTokenFields, - CoreGenderClaim, - CoreJweContentEncryptionAlgorithm, - CoreJwsSigningAlgorithm, - CoreJsonWebKeyType, ->; - -type CustomTokenResponse = StandardTokenResponse; -// end cascade - -#[derive(Clone, Debug)] -enum FailureMode { - // These are various generic failure modes, - // without Oauth/OpenID Connect specific errors - SlowResponse { - rel_path_prefix: String, - duration: Duration, - }, - Error500Response { - rel_path_prefix: String, - }, - Error503Response { - rel_path_prefix: String, - }, - WrongCSRFState, - MalformedIDToken, - // These are the RFC 6749 5.2 Errors - InvalidRequestErrorResponse, - InvalidClientErrorResponse, - InvalidGrantErrorResponse, - InvalidScopeErrorResponse, - UnauthorizedClientErrorResponse, - UnsupportedGrantTypeErrorResponse, -} - -impl SerdeSerialize for FailureMode { - fn serialize(&self, serializer: S) -> Result - where - S: SerdeSerializer, - { - let mut state = serializer.serialize_struct("Error", 0)?; - match self { - FailureMode::InvalidRequestErrorResponse => state.serialize_field("error", "invalid_request")?, - FailureMode::InvalidClientErrorResponse => state.serialize_field("error", "invalid_client")?, - FailureMode::InvalidGrantErrorResponse => state.serialize_field("error", "invalid_grant")?, - FailureMode::UnauthorizedClientErrorResponse => state.serialize_field("error", "unauthorized_client")?, - FailureMode::InvalidScopeErrorResponse => state.serialize_field("error", "invalid_scope")?, - FailureMode::UnsupportedGrantTypeErrorResponse => { - state.serialize_field("error", "unsupported_grant_type")? - } - _ => unreachable!(), - } - state.end() - } -} - -#[derive(Clone, Debug, Default)] -struct KnownUser { - attributes: HashMap, - token_secs: Option, - refresh: bool, - failure_mode: Option, -} - -struct TempAuthzCodeDetails { - client_id: String, - nonce: String, - username: String, -} - -#[derive(Clone, Debug)] -struct LoginSession { - id: KnownUserId, - id_token: Option, -} - -type TempAuthzCode = String; -type TempAuthzCodes = HashMap; - -type LoggedInAccessToken = String; -type LoginSessions = HashMap; - -type KnownUserId = String; -type KnownUsers = HashMap; - -const DEFAULT_TOKEN_DURATION_SECS: u32 = 3600; -static MOCK_OPENID_CONNECT_SERVER_RUNNING_FLAG: AtomicBool = AtomicBool::new(false); - -// This function is not used by the integration tests which are the main users of this code, but sometimes it's helpful -// to be able to spin up the mock outside of an integration test which is why this main() fn exists. If we don't allow -// dead_code then cargo test spams the output with function is never used warnings. -#[allow(dead_code)] -#[tokio::main] -pub async fn main() { - // Log to stdout. - let _logger = fern::Dispatch::new() - .format(move |out, message, record| { - out.finish(format_args!( - "{} [{}] {}", - chrono::Local::now().format("%Y-%m-%d %H:%M:%S"), - record.level(), - message - )) - }) - .level(log::LevelFilter::Trace) - .chain(std::io::stdout()) - .apply() - .map_err(|e| format!("Failed to init stderr logging: {}", e)); - - start(OpenIDConnectMockConfig::enabled(WithRPInitiatedLogout), 2500).await; -} - -pub async fn start(config: OpenIDConnectMockConfig, delay_secs: u64) -> task::JoinHandle<()> { - let join_handle = task::spawn_blocking(move || { - run_mock_openid_connect_server(config); - }); - - // wait for the mock OpenID Connect server to be up before continuing - // otherwise Krill might fail to query its discovery endpoint - while !MOCK_OPENID_CONNECT_SERVER_RUNNING_FLAG.load(Ordering::Relaxed) { - info!("Waiting for mock OpenID Connect server to start"); - sleep(Duration::from_secs(delay_secs)).await; - } - - join_handle -} - -pub async fn stop(join_handle: task::JoinHandle<()>) { - info!("Signalling the OpenID Connect server to stop"); - MOCK_OPENID_CONNECT_SERVER_RUNNING_FLAG.store(false, Ordering::Relaxed); - join_handle.await.unwrap(); -} - -fn run_mock_openid_connect_server(config: OpenIDConnectMockConfig) { - let mut enabled = config.enabled_on_startup(); - let mut authz_codes = TempAuthzCodes::new(); - let mut login_sessions = LoginSessions::new(); - let mut known_users = KnownUsers::new(); - - let logout_metadata = match config.mode() { - WithRPInitiatedLogout => CustomAdditionalMetadata { - end_session_endpoint: Some(String::from("https://localhost:1818/logout")), - revocation_endpoint: None, - }, - WithOAuth2Revocation => CustomAdditionalMetadata { - end_session_endpoint: None, - revocation_endpoint: Some(String::from("https://localhost:1818/revoke")), - }, - WithNoLogoutEndpoints => CustomAdditionalMetadata { - end_session_endpoint: None, - revocation_endpoint: None, - }, - NotStarted => { - unreachable!() - } - }; - - let provider_metadata: CustomProviderMetadata = ProviderMetadata::new( - IssuerUrl::new("https://localhost:1818".to_string()).unwrap(), - AuthUrl::new("https://localhost:1818/authorize".to_string()).unwrap(), - JsonWebKeySetUrl::new("https://localhost:1818/jwk".to_string()).unwrap(), - vec![ResponseTypes::new(vec![CoreResponseType::Code])], - vec![CoreSubjectIdentifierType::Pairwise], - vec![CoreJwsSigningAlgorithm::RsaSsaPssSha256], - logout_metadata, - ) - .set_token_endpoint(Some(TokenUrl::new("https://localhost:1818/token".to_string()).unwrap())) - .set_userinfo_endpoint(Some( - UserInfoUrl::new("https://localhost:1818/userinfo".to_string()).unwrap(), - )) - .set_scopes_supported(Some(vec![ - Scope::new("openid".to_string()), - Scope::new("email".to_string()), - Scope::new("profile".to_string()), - ])) - .set_response_modes_supported(Some(vec![CoreResponseMode::Query])) - .set_id_token_signing_alg_values_supported(vec![CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha256]) - .set_claims_supported(Some(vec![CoreClaimName::new("email".to_string())])); - - let rsa_key = Rsa::generate(2048).unwrap().private_key_to_pem().unwrap(); - let rsa_pem = std::str::from_utf8(&rsa_key).unwrap(); - let signing_key = CoreRsaPrivateSigningKey::from_pem(rsa_pem, Some(JsonWebKeyId::new("key1".to_string()))) - .expect("Invalid RSA private key"); - - let jwks = CoreJsonWebKeySet::new(vec![ - // RSA keys may also be constructed directly using CoreJsonWebKey::new_rsa(). Providers - // aiming to support other key types may provide their own implementation of the - // JsonWebKey trait or submit a PR to add the desired support to this crate. - signing_key.as_verification_key(), - ]); - - let discovery_doc = serde_json::to_string(&provider_metadata) - .map_err(|err| Error::custom(format!("Error while building discovery JSON response: {}", err))) - .unwrap(); - let jwks_doc = serde_json::to_string(&jwks) - .map_err(|err| Error::custom(format!("Error while building jwks JSON response: {}", err))) - .unwrap(); - let login_doc = std::str::from_utf8(include_bytes!("../../test-resources/ui/oidc_login.html")).unwrap(); - - fn make_random_value() -> Result { - let mut access_token_bytes: [u8; 4] = [0; 4]; - openssl::rand::rand_bytes(&mut access_token_bytes) - .map_err(|err: openssl::error::ErrorStack| Error::custom(format!("Rand error: {}", err)))?; - Ok(base64::encode(access_token_bytes)) - } - - fn make_access_token() -> Result { - Ok(AccessToken::new(make_random_value()?)) - } - - fn make_refresh_token() -> Result { - Ok(RefreshToken::new(make_random_value()?)) - } - - fn get_user_for_session(session: &LoginSession, known_users: &KnownUsers) -> Result { - known_users - .get(&session.id) - .cloned() - .ok_or_else(|| Error::custom(format!("Internal error, unknown user: {}", session.id))) - } - - fn get_token_duration_for_user(user: &KnownUser) -> Result { - let token_duration = user.token_secs.unwrap_or(DEFAULT_TOKEN_DURATION_SECS); - - if token_duration != DEFAULT_TOKEN_DURATION_SECS { - info!( - "Issuing token with non-default expiration time of {} seconds", - &token_duration - ); - } - - Ok(token_duration) - } - - fn make_id_token_response( - signing_key: &CoreRsaPrivateSigningKey, - client_id: String, - nonce: String, - session: &LoginSession, - known_users: &KnownUsers, - ) -> Result { - let user = get_user_for_session(session, known_users)?; - let token_duration = get_token_duration_for_user(&user)?; - let access_token = make_access_token()?; - - let id_token = CustomIdToken::new( - CustomIdTokenClaims::new( - // Specify the issuer URL for the OpenID Connect Provider. - IssuerUrl::new("https://localhost:1818".to_string()).unwrap(), - // The audience is usually a single entry with the client ID of the client for whom - // the ID token is intended. This is a required claim. - vec![Audience::new(client_id)], - // The ID token expiration is usually much shorter than that of the access or refresh - // tokens issued to clients. Our client only keeps the access/refresh token and the - // access token expiration time, so this isn't used. - chrono::Utc::now() + chrono::Duration::seconds(token_duration.into()), - // The issue time is usually the current time. - chrono::Utc::now(), - // Set the standard claims defined by the OpenID Connect Core spec. - StandardClaims::new( - // Stable subject identifiers are recommended in place of e-mail addresses or other - // potentially unstable identifiers. This is the only required claim. - SubjectIdentifier::new(session.id.to_string()), - ), - CustomAdditionalClaims { - role: user.attributes.get("role").map(|v| v.to_string()), - inc_cas: user.attributes.get("inc_cas").map(|v| v.to_string()), - exc_cas: user.attributes.get("exc_cas").map(|v| v.to_string()), - }, - ) - // Optional: specify the user's e-mail address. This should only be provided if the - // client has been granted the 'profile' or 'email' scopes. - .set_email(Some(EndUserEmail::new(session.id.to_string()))) - // Optional: specify whether the provider has verified the user's e-mail address. - .set_email_verified(Some(true)) - // OpenID Connect Providers may supply custom claims by providing a struct that - // implements the AdditionalClaims trait. This requires manually using the - // generic IdTokenClaims struct rather than the CoreIdTokenClaims type alias, - // however. - .set_nonce(Some(Nonce::new(nonce))), - // The private key used for signing the ID token. For confidential clients (those able - // to maintain a client secret), a CoreHmacKey can also be used, in conjunction - // with one of the CoreJwsSigningAlgorithm::HmacSha* signing algorithms. When using an - // HMAC-based signing algorithm, the UTF-8 representation of the client secret should - // be used as the HMAC key. - signing_key, - // Uses the RS256 signature algorithm. This crate supports any RS*, PS*, or HS* - // signature algorithm. - CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha256, - // When returning the ID token alongside an access token (e.g., in the Authorization Code - // flow), it is recommended to pass the access token here to set the `at_hash` claim - // automatically. - Some(&access_token), - // When returning the ID token alongside an authorization code (e.g., in the implicit - // flow), it is recommended to pass the authorization code here to set the `c_hash` claim - // automatically. - None, - ) - .unwrap(); - - let mut token_response = CustomTokenResponse::new( - access_token, - CoreTokenType::Bearer, - CustomIdTokenFields::new(Some(id_token), EmptyExtraTokenFields {}), - ); - - token_response.set_expires_in(Some(&Duration::from_secs(token_duration.into()))); - - if user.refresh { - let refresh_token = make_refresh_token()?; - token_response.set_refresh_token(Some(refresh_token)); - } - - Ok(token_response) - } - - fn base64_decode(encoded: String) -> Result { - String::from_utf8( - base64::decode(encoded) - .map_err(|err: base64::DecodeError| Error::custom(format!("Base64 decode error: {}", err)))?, - ) - .map_err(|err: std::string::FromUtf8Error| Error::custom(format!("UTF8 decode error: {}", err))) - } - - fn url_encode(decoded: String) -> Result { - urlparse::quote(decoded, b"") - .map_err(|err: std::string::FromUtf8Error| Error::custom(format!("UTF8 decode error: {}", err))) - } - - fn require_query_param(query: &Query, param: &str) -> Result { - // TODO: ensure that such errors actually result in a https://tools.ietf.org/html/rfc6749#section-5.2 - // compliant { "error": "invalid_request" } JSON error response. - query - .get_first_from_str(param) - .ok_or_else(|| Error::custom(format!("Missing query parameter '{}'", param))) - } - - fn handle_discovery_request(request: Request, discovery_doc: &str) -> Result<(), Error> { - request - .respond( - Response::empty(StatusCode(200)) - .with_header(Header::from_str("Content-Type: application/json").unwrap()) - .with_data(discovery_doc.as_bytes(), None), - ) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err))) - } - - fn handle_jwks_request(request: Request, jwks_doc: &str) -> Result<(), Error> { - request - .respond( - Response::empty(StatusCode(200)) - .with_header(Header::from_str("Content-Type: application/json").unwrap()) - .with_data(jwks_doc.as_bytes(), None), - ) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err))) - } - - fn handle_authorize_request(request: Request, url: Url, login_doc: &str) -> Result<(), Error> { - let query = url - .get_parsed_query() - .ok_or_else(|| Error::custom("Missing query parameters"))?; - let client_id = require_query_param(&query, "client_id")?; - let nonce = require_query_param(&query, "nonce")?; - let state = require_query_param(&query, "state")?; - let redirect_uri = require_query_param(&query, "redirect_uri")?; - - request - .respond( - Response::empty(StatusCode(200)) - .with_header(Header::from_str("Content-Type: text/html").unwrap()) - .with_data( - login_doc - .replace("", &base64::encode(nonce)) - .replace("", &base64::encode(state)) - .replace("", &base64::encode(redirect_uri)) - .replace("", &base64::encode(client_id)) - .as_bytes(), - None, - ), - ) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err))) - } - - fn handle_login_request( - request: Request, - url: Url, - authz_codes: &mut TempAuthzCodes, - known_users: &mut KnownUsers, - ) -> Result<(), Error> { - let query = url - .get_parsed_query() - .ok_or_else(|| Error::custom("Missing query parameters"))?; - let redirect_uri = require_query_param(&query, "redirect_uri")?; - let redirect_uri = base64_decode(redirect_uri)?; - - fn bool_query_param(query: &Query, param: &str) -> bool { - match query.get_first_from_str(param) { - Some(value) => bool::from_str(&value).unwrap_or(false), - None => false, - } - } - - fn with_redirect_uri( - redirect_uri: String, - query: Query, - authz_codes: &mut TempAuthzCodes, - known_users: &mut KnownUsers, - ) -> Result<(KnownUser, Response), Error> { - let username = require_query_param(&query, "username")?; - let failure_mode = query.get_first_from_str("failure_mode"); - - let user = match known_users.get(username.as_str()) { - Some(user) => user, - None if (username.trim().is_empty() || failure_mode == Some("unknown_user".to_string())) => { - return Err(Error::custom(format!("Unknown username '{}'", username))) - } - None => { - // Create the user on the fly - - // What attributes should the user have? - let mut attributes: HashMap = HashMap::new(); - for i in 1..=5 { - if let Some(attr_name) = query.get_first_from_str(&format!("userattr{}", i)) { - if let Some(attr_val) = query.get_first_from_str(&format!("userattrval{}", i)) { - attributes.insert(attr_name, attr_val); - } - } - } - - // How long should the issued access token be valid for? - let token_secs = Some(u32::from_str(&require_query_param(&query, "token_secs")?).map_err( - |err| Error::custom(format!("Failed to parse token_secs query parameter: {}", err)), - )?); - - // Should the user be issued a refresh token? - let refresh = bool_query_param(&query, "refresh"); - - fn duration_failure_param(query: &Query) -> Result { - let secs: String = require_query_param(query, "failure_param")?; - let secs: u64 = u64::from_str(&secs).map_err(|err| { - Error::custom(format!("Failed to parse failure_param query parameter: {}", err)) - })?; - Ok(Duration::from_secs(secs)) - } - - // Should we exhibit some sort of failure for this user? - let mut failure_mode = None; - if let Some(mode) = query.get_first_from_str("failure_mode") { - if let Some(endpoint) = query.get_first_from_str("failure_endpoint") { - failure_mode = match (&mode[..], &endpoint[..]) { - ("none", "none") => None, - ("slow_response", endpoint) => Some(FailureMode::SlowResponse { - rel_path_prefix: format!("/{}", endpoint), - duration: duration_failure_param(&query)?, - }), - ("http_500", endpoint) => Some(FailureMode::Error500Response { - rel_path_prefix: format!("/{}", endpoint), - }), - ("http_503", endpoint) => Some(FailureMode::Error503Response { - rel_path_prefix: format!("/{}", endpoint), - }), - ("invalid_request", _) => Some(FailureMode::InvalidRequestErrorResponse), - ("invalid_client", _) => Some(FailureMode::InvalidClientErrorResponse), - ("invalid_grant", _) => Some(FailureMode::InvalidGrantErrorResponse), - ("unauthorized_client", _) => Some(FailureMode::UnauthorizedClientErrorResponse), - ("invalid_scope", _) => Some(FailureMode::InvalidScopeErrorResponse), - ("unsupported_grant_type", _) => Some(FailureMode::UnsupportedGrantTypeErrorResponse), - ("wrong_csrf_state", _) => Some(FailureMode::WrongCSRFState), - ("malformed_id_token", _) => Some(FailureMode::MalformedIDToken), - (err_mode, err_endpoint) => { - return Err(Error::custom(format!( - "Unknown failure mode '{}' or endpoint '{:?}'", - err_mode, err_endpoint - ))); - } - }; - } - } - - let user = KnownUser { - attributes, - token_secs, - refresh, - failure_mode, - }; - - trace!("Creating mock user '{}': {:?}", &username, &user); - - known_users.insert(username.clone(), user); - - known_users.get(username.as_str()).unwrap() - } - }; - - let client_id = base64_decode(require_query_param(&query, "client_id")?)?; - let nonce = base64_decode(require_query_param(&query, "nonce")?)?; - let state = if matches!(user.failure_mode, Some(FailureMode::WrongCSRFState)) { - info!("Deliberately returning the wrong CSRF state value to the client"); - "some-wrong-csrf-value".to_string() - } else { - base64_decode(require_query_param(&query, "state")?)? - }; - - let mut code_bytes: [u8; 4] = [0; 4]; - openssl::rand::rand_bytes(&mut code_bytes) - .map_err(|err: openssl::error::ErrorStack| Error::custom(format!("Rand error: {}", err)))?; - let code = base64::encode(code_bytes); - - authz_codes.insert( - code.clone(), - TempAuthzCodeDetails { - client_id, - nonce: nonce.clone(), - username, - }, - ); - - let urlsafe_code = url_encode(code)?; - let urlsafe_state = url_encode(state)?; - let urlsafe_nonce = url_encode(nonce)?; - - Ok(( - user.clone(), - Response::empty(StatusCode(302)).with_header( - Header::from_str(&format!( - "Location: {}?code={}&state={}&nonce={}", - redirect_uri, urlsafe_code, urlsafe_state, urlsafe_nonce - )) - .map_err(|err| { - Error::custom(format!("Error while constructing HTTP Location header: {:?}", err)) - })?, - ), - )) - } - - // per RFC 6749 and OpenID Connect Core 1.0 section 3.1.26 - // Authentication Error Response we should still return a - // redirect on error but with query params describing the error. - let (user, response) = match with_redirect_uri(redirect_uri.clone(), query, authz_codes, known_users) { - Ok((user, response)) => (Some(user), response), - Err(err) => ( - None, - Response::empty(StatusCode(302)).with_header( - Header::from_str(&format!( - "Location: {}?error={}", - redirect_uri, - url_encode(format!("{}", err))? - )) - .map_err(|err| { - Error::custom(format!("Error while constructing HTTP Location header: {:?}", err)) - })?, - ), - ), - }; - - let request = simulate_server_failure(request, user, &url)?; - - request - .respond(response) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err))) - } - - /// Implement [OpenID Connect RP-Initiated Logout 1.0 - draft 01][openid-connect-rpinitiated-1_0] - /// - /// [openid-connect-rpinitiated-1_0]: https://openid.net/specs/openid-connect-rpinitiated-1_0.htmlc - fn handle_logout_request( - request: Request, - known_users: &KnownUsers, - login_sessions: &mut LoginSessions, - url: Url, - ) -> Result<(), Error> { - let query = url - .get_parsed_query() - .ok_or_else(|| Error::custom("Missing query parameters"))?; - let redirect_uri = require_query_param(&query, "post_logout_redirect_uri")?; - let id_token_hint = require_query_param(&query, "id_token_hint")?; - - let mut found_user_id: Option = None; - login_sessions.retain(|_k, v| { - // return false if the id token matches the one we are looking for so that retain() will discard this - // login session - if let Some(id_token) = &v.id_token { - let r = *id_token != id_token_hint; - if !r { - info!( - "Logout of id token '{}' terminates session for user '{}' with access/refresh token '{}'", - id_token_hint, v.id, _k - ); - if found_user_id.is_none() { - found_user_id = Some(v.id.clone()); - } - } - return r; - } - - warn!("While handling a logout request a login session without an ID token was discovered!"); - true - }); - - match found_user_id { - Some(user_id) => { - let request = simulate_server_failure(request, known_users.get(&user_id).cloned(), &url)?; - - remove_related_login_sessions(login_sessions, &user_id); - - let response = Response::empty(StatusCode(302)).with_header( - Header::from_str(&format!("Location: {}", redirect_uri)).map_err(|err| { - Error::custom(format!("Error while constructing HTTP Location header: {:?}", err)) - })?, - ); - - request - .respond(response) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err))) - } - None => Err(Error::custom("Error while logging out: no login session found")), - } - } - - fn remove_related_login_sessions(login_sessions: &mut LoginSessions, user_id: &str) { - // remove all login sessions for the found user id, not just the one with the given token - // this helps in UI tests where previous tests logged a user in but didn't log them out and their token - // hasn't expired yet, and then the test calls /test/is_user_logged_in with a user id to see if they are - // logged in and finds they are, even if they had just been logged out using the id_token_hint... - login_sessions.retain(|access_or_refresh_token, login_session| { - // return false if the user id matches the one we are looking for so that retain() will discard this - // login session - let r = login_session.id != user_id; - if !r { - info!( - "Terminating login session for user '{}' with access/refresh token '{}'", - login_session.id, access_or_refresh_token - ); - } - r - }); - } - - /// Implement [OAuth 2.0 Token Revocation][rfc7009] - /// - /// [rfc7009]: https://tools.ietf.org/html/rfc7009 - fn handle_oauth2_revocation_request( - mut request: Request, - login_sessions: &mut LoginSessions, - known_users: &KnownUsers, - url: Url, - ) -> Result<(), Error> { - // TODO: handle both access and refresh tokens - let mut body = String::new(); - request - .as_reader() - .read_to_string(&mut body) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err)))?; - - let query_params = parse_qs(body); - let token = require_query_param(&query_params, "token")?; - let token_type_hint = query_params.get_first_from_str("token_type_hint"); - - // https://tools.ietf.org/html/rfc7009#section-2.2.1: - // unsupported_token_type: The authorization server does not support - // the revocation of the presented token type. That is, the - // client tried to revoke an access token on a server not - // supporting this feature. - if matches!(token_type_hint, Some(hint_str) if hint_str == "access_token") { - let err_body = json!({ - "error": "unsupported_token_type", - "error_description": "This mock OpenID Connect server only supports revocation of refresh tokens, not access tokens" - }) - .to_string(); - request - .respond( - Response::empty(StatusCode(400)) - .with_header(Header::from_str("Content-Type: application/json").unwrap()) - .with_data(err_body.as_bytes(), None), - ) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err))) - } else { - let user = get_requesting_user(&request, known_users, login_sessions).ok(); - let request = simulate_server_failure(request, user, &url)?; - - match login_sessions.remove(&token) { - None => { - warn!("Token '{}' could NOT be revoked: token is NOT known", &token); - // From https://tools.ietf.org/html/rfc7009#section-2.2: - // Note: invalid tokens do not cause an error response since the client - // cannot handle such an error in a reasonable way. Moreover, the - // purpose of the revocation request, invalidating the particular token, - // is already achieved. - } - Some(session) => { - info!( - "Logout of refresh token '{}' terminates session for user '{}'", - token, session.id - ); - remove_related_login_sessions(login_sessions, &session.id); - } - }; - - request - .respond(Response::empty(StatusCode(200))) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err))) - } - } - - fn handle_control_is_user_logged_in_request( - request: Request, - url: Url, - login_sessions: &LoginSessions, - ) -> Result<(), Error> { - let query = url - .get_parsed_query() - .ok_or_else(|| Error::custom("Missing query parameters"))?; - let username = require_query_param(&query, "username")?; - - match login_sessions.iter().find(|(_, session)| session.id == username) { - Some((access_token, session)) => { - info!( - "Login session found for user '{}' with access_token={:?} and id_token={:?}", - &username, access_token, session.id_token - ); - request - .respond(Response::empty(StatusCode(200))) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err))) - } - None => { - info!("No login session found for user '{}'", &username); - request - .respond(Response::empty(StatusCode(400))) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err))) - } - } - } - - fn handle_token_request( - mut request: Request, - signing_key: &CoreRsaPrivateSigningKey, - authz_codes: &mut TempAuthzCodes, - login_sessions: &mut LoginSessions, - known_users: &KnownUsers, - url: Url, - ) -> Result<(), Error> { - let mut body = String::new(); - request - .as_reader() - .read_to_string(&mut body) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err)))?; - - let query_params = parse_qs(body); - let mut new_keys: Vec = Vec::new(); - let mut new_session: Option = None; - - // we skip over verifying the Authorization HTTP header but perhaps - // we should make sure the client is sending that correctly? - trace!("grant: {:?}", &query_params.get("grant_type")); - - let r = match query_params.get("grant_type") { - Some(grant_type) if &grant_type[0] == "authorization_code" => { - if let Some(code) = query_params.get("code") { - let code = &code[0]; - if let Some(authz_code) = authz_codes.remove(code) { - trace!("client_id: {:?}", &authz_code.client_id); - trace!("username: {:?}", &authz_code.username); - - // find static user id - let mut session = LoginSession { - id: known_users - .keys() - .find(|k| k.to_string() == authz_code.username) - .ok_or_else(|| { - Error::custom(format!("Internal error, unknown user '{}'", authz_code.username)) - })? - .clone(), - id_token: None, // updated below after the token is generated - }; - - let issue_bad_token = if let Some(user) = known_users.get(&session.id) { - matches!(user.failure_mode, Some(FailureMode::MalformedIDToken)) - } else { - false - }; - let (token_doc, id_token) = if issue_bad_token { - // This represents an ID Token with an illegal "acr" value that is not a string but - // rather a nested structure. This will be rejected by the Rust OpenID Connect crate. - // We've seen this problem with at least one real OpenID Connect provider deployment. - let dummy_access_token = String::from("*****"); - let id_token_with_invalid_acr = String::from("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tL3NvbWUvdXJsIiwic3ViIjoiYmxhaCIsImF1ZCI6ImJsYWgiLCJleHAiOjE2MTcxNDkxMTMsImlhdCI6MTYwNjE2NjA1Mywibm9uY2UiOiJibGFoIiwiYWNyIjp7InZhbHVlcyI6WyJodHRwczovL2V4YW1wbGUuY29tL3NvbWUvdXJsIl19LCJqdGkiOiI5MTgxMGU1Yi01ZDQ2LTRkZGQtYjJiMi01ZjU2MjliMTUyNDAifQ.ZnQvUMKDEcaCI-C9xMdzRB-sEyB9HTZ8sj2nGnMjAQg"); - let token_doc = format!( - r#"{{ - "access_token":"{}", - "token_type":"bearer", - "expires_in":299, - "id_token":"{}" - }}"#, - dummy_access_token, id_token_with_invalid_acr - ); - - new_keys.push(dummy_access_token); - - (token_doc, id_token_with_invalid_acr) - } else { - let token_response = make_id_token_response( - signing_key, - authz_code.client_id.clone(), - authz_code.nonce, - &session, - known_users, - )?; - let token_doc = serde_json::to_string(&token_response).map_err(|err| { - Error::custom(format!("Error while building ID Token JSON response: {}", err)) - })?; - if let Some(token) = token_response.refresh_token() { - new_keys.push(token.secret().clone()); - } - - new_keys.push(token_response.access_token().secret().clone()); - - let id_token = token_response - .extra_fields() - .id_token() - .expect("Missing id_token") - .to_string(); - - (token_doc, id_token) - }; - - session.id_token = Some(id_token); - new_session = Some(session); - - request - .respond( - Response::empty(StatusCode(200)) - .with_header(Header::from_str("Content-Type: application/json").unwrap()) - .with_data(token_doc.as_bytes(), None), - ) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err))) - } else { - Err(Error::custom(format!( - "Unknown temporary authorization code '{}'", - &code - ))) - } - } else { - Err(Error::custom("Missing query parameter 'code'")) - } - } - Some(grant_type) if &grant_type[0] == "refresh_token" => { - // we skip over verifying the Authorization HTTP header but perhaps - // we should make sure the client is sending that correctly? - info!("client_id refreshing: {:?}", query_params); - if let Some(refresh_token) = query_params.get("refresh_token") { - let refresh_token = &refresh_token[0]; - if let Some(mut session) = login_sessions.get_mut(refresh_token) { - let user = get_user_for_session(session, known_users)?; - trace!("session: {:?}", &session.id); - // Check the intentional failure responses we might want to - // impose on users and return the apprioriate HTTP response. - - let request = simulate_server_failure(request, Some(user.clone()), &url)?; - - let failure_json_str = if let Some(ref failure_mode) = user.failure_mode { - match failure_mode { - FailureMode::InvalidRequestErrorResponse - | FailureMode::InvalidClientErrorResponse - | FailureMode::InvalidGrantErrorResponse - | FailureMode::InvalidScopeErrorResponse - | FailureMode::UnauthorizedClientErrorResponse - | FailureMode::UnsupportedGrantTypeErrorResponse => { - Some(json!(failure_mode).to_string()) - } - _ => None, - } - } else { - None - }; - - if let Some(json_str) = failure_json_str { - warn!( - "Simulating refresh failure: Responding with HTTP 400 error '{}' for user '{}'", - json_str, &session.id - ); - return request - .respond( - Response::empty(StatusCode(400)) - .with_header(Header::from_str("Content-Type: application/json").unwrap()) - .with_data(json_str.as_bytes(), None), - ) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err))); - } else if user.refresh { - let token_response = make_id_token_response( - signing_key, - String::from("dummy_client_id"), - String::from("dummy_nonce"), - session, - known_users, - )?; - - let token_doc = serde_json::to_string(&token_response).map_err(|err| { - Error::custom(format!("Error while building ID Token JSON response: {}", err)) - })?; - if let Some(token) = token_response.refresh_token() { - new_keys.push(token.secret().clone()); - } - - new_keys.push(token_response.access_token().secret().clone()); - - let id_token = token_response - .extra_fields() - .id_token() - .expect("Missing id_token") - .to_string(); - - session.id_token = Some(id_token); - new_session = Some(session.clone()); - - request - .respond( - Response::empty(StatusCode(200)) - .with_header(Header::from_str("Content-Type: application/json").unwrap()) - .with_data(token_doc.as_bytes(), None), - ) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err))) - } else { - trace!("Internal error for user session.id={} user={:?}", session.id, &user); - Err(Error::custom(format!("Internal error: cowardly refusing to generate a new token for user '{}' that should not get refresh tokens", session.id))) - } - } else { - warn!("Invalid refresh token: Responding with HTTP 400 'invalid_grant'"); - request - .respond( - Response::empty(StatusCode(400)) - .with_header(Header::from_str("Content-Type: application/json").unwrap()) - .with_data(json!({"error":"invalid_grant"}).to_string().as_bytes(), None), - ) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err))) - } - } else { - warn!("Missing query parameter 'refresh_token': Responding with HTTP 400 'invalid_request'"); - request - .respond( - Response::empty(StatusCode(400)) - .with_header(Header::from_str("Content-Type: application/json").unwrap()) - .with_data(json!({"error":"invalid_request"}).to_string().as_bytes(), None), - ) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err))) - } - } - Some(grant_type) => { - warn!( - "Unsupported grant type: {:?}. Responding with HTTP 400 'unsupported_grant_type'", - grant_type - ); - request - .respond( - Response::empty(StatusCode(400)) - .with_header(Header::from_str("Content-Type: application/json").unwrap()) - .with_data(json!({"error":"unsupported_grant_type"}).to_string().as_bytes(), None), - ) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err))) - } - None => { - warn!("Missing query parameter 'grant_type': Responding with HTTP 400 'invalid_request'"); - request - .respond( - Response::empty(StatusCode(400)) - .with_header(Header::from_str("Content-Type: application/json").unwrap()) - .with_data(json!({"error":"invalid_request"}).to_string().as_bytes(), None), - ) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err))) - } - }; - - // do this out here to avoid having both a mutable and immutable reference to login_sessions at the same - // time, which isn't permitted by the Rust borrow checker. The key could be either an access token or a - // refresh token, we don't distinguish between the two. - if let Some(session) = new_session { - for key in new_keys { - login_sessions.insert(key, session.clone()); - } - } - - r - } - - fn get_requesting_user( - request: &Request, - known_users: &KnownUsers, - login_sessions: &mut LoginSessions, - ) -> Result { - let authz_hdr = request - .headers() - .iter() - .find(|&hdr| hdr.field.equiv("Authorization")) - .ok_or_else(|| Error::custom("Missing Authorization HTTP request header on call to userinfo endpoint"))? - .value - .as_str() - .to_string(); - - if !authz_hdr.to_lowercase().starts_with("bearer ") { - return Err(Error::custom(format!( - "Authorization HTTP request header '{}' does not start with 'Bearer ' (case insensitive)", - authz_hdr - ))); - } - - let access_token = authz_hdr.split_once(' ').map(|x| x.1).ok_or_else(|| { - Error::custom(format!( - "Failed to extract access token after the first space in '{}'", - authz_hdr - )) - })?; - - let login_session = login_sessions.get(access_token).ok_or_else(|| { - Error::custom(format!( - "Unknown Authorization HTTP request header access token value '{}'", - access_token - )) - })?; - - let user = known_users.get(&login_session.id).ok_or_else(|| { - Error::custom(format!( - "No known users found for login session ID '{}'", - login_session.id - )) - })?; - - Ok(user.clone()) - } - - fn handle_user_info_request( - request: Request, - known_users: &KnownUsers, - login_sessions: &mut LoginSessions, - url: Url, - ) -> Result<(), Error> { - let standard_claims: StandardClaims = - StandardClaims::new(SubjectIdentifier::new("sub-123".to_string())); - let additional_claims = EmptyAdditionalClaims {}; - let claims = UserInfoClaims::new(standard_claims, additional_claims); - let claims_doc = serde_json::to_string(&claims) - .map_err(|err| Error::custom(format!("Error while building UserInfo JSON response: {}", err)))?; - - let user = get_requesting_user(&request, known_users, login_sessions)?; - let request = simulate_server_failure(request, Some(user), &url)?; - - request - .respond( - Response::empty(StatusCode(200)) - .with_header(Header::from_str("Content-Type: application/json").unwrap()) - .with_data(claims_doc.as_bytes(), None), - ) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err))) - } - - #[allow(clippy::too_many_arguments)] - fn handle_request( - mode: OpenIDConnectMockMode, - request: Request, - discovery_doc: &str, - jwks_doc: &str, - login_doc: &str, - signing_key: &CoreRsaPrivateSigningKey, - authz_codes: &mut TempAuthzCodes, - login_sessions: &mut LoginSessions, - known_users: &mut KnownUsers, - enabled: &mut bool, - ) -> Result<(), Error> { - let url = urlparse(request.url()); - - if !*enabled { - warn!("All OpenID Connect endpoints are disabled! POST /test/enable to re-enable them.") - } - - match (&enabled, request.method(), url.path.as_str()) { - // OpenID Connect 1.0. Discovery support - (true, Method::Get, "/.well-known/openid-configuration") => { - return handle_discovery_request(request, discovery_doc); - } - // OpenID Connect 1.0. Discovery support - (true, Method::Get, "/jwk") => { - return handle_jwks_request(request, jwks_doc); - } - // OAuth 2.0 Authorization Request support - (true, Method::Get, "/authorize") => { - return handle_authorize_request(request, url, login_doc); - } - (true, Method::Get, "/login_form_submit") => { - return handle_login_request(request, url, authz_codes, known_users); - } - // OpenID Connect 1.0. Discovery support - (true, Method::Get, "/userinfo") => { - return handle_user_info_request(request, known_users, login_sessions, url); - } - // OpenID Connect RP-Initiated Logout 1.0 support - (true, Method::Get, "/logout") => { - if matches!(mode, WithRPInitiatedLogout) { - return handle_logout_request(request, known_users, login_sessions, url); - } - } - (true, Method::Post, "/token") => { - return handle_token_request(request, signing_key, authz_codes, login_sessions, known_users, url); - } - // OAuth 2.0 Token Revocation support - (true, Method::Post, "/revoke") => { - if matches!(mode, WithOAuth2Revocation) { - return handle_oauth2_revocation_request(request, login_sessions, known_users, url); - } - } - // Test control APIs - (_, Method::Get, "/test/is_user_logged_in") => { - return handle_control_is_user_logged_in_request(request, url, login_sessions); - } - (_, Method::Post, "/test/enable") => { - info!("Enabling all OpenID Connect endpoints!"); - *enabled = true; - return request - .respond(Response::empty(StatusCode(200))) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err))); - } - (_, Method::Post, "/test/disable") => { - warn!("Disabling all OpenID Connect endpoints!"); - *enabled = false; - return request - .respond(Response::empty(StatusCode(200))) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err))); - } - _ => {} - }; - - Err(Error::custom(format!("Unknown request: {:?}", request))) - } - - let address = "127.0.0.1:1818"; - info!("Mock OpenID Connect server: starting on {}", address); - - let server = Server::https( - address, - tiny_http::SslConfig { - certificate: SELF_SIGNED_CERT_PEM.to_vec(), - private_key: SELF_SIGNED_KEY_PEM.to_vec(), - }, - ) - .unwrap(); - - info!("Mock OpenID Connect server: started"); - - if !enabled { - warn!("All OpenID Connect endpoints are disabled! POST /test/enable to re-enable them.") - } - - MOCK_OPENID_CONNECT_SERVER_RUNNING_FLAG.store(true, Ordering::Relaxed); - while MOCK_OPENID_CONNECT_SERVER_RUNNING_FLAG.load(Ordering::Relaxed) { - match server.recv_timeout(Duration::new(1, 0)) { - Ok(None) => { /* no request received within the timeout */ } - Ok(Some(request)) => { - info!("Received {:?}", &request); - if let Err(err) = handle_request( - config.mode(), - request, - &discovery_doc, - &jwks_doc, - login_doc, - &signing_key, - &mut authz_codes, - &mut login_sessions, - &mut known_users, - &mut enabled, - ) { - error!("{}", err); - } - } - Err(err) => { - error!("{}", err); - } - }; - } - - info!("Mock OpenID Connect: stopped"); -} - -fn simulate_server_failure(request: Request, user: Option, url: &Url) -> Result { - if let Some(user) = user { - if let Some(ref failure_mode) = user.failure_mode { - trace!( - "Checking if failure {:?} should be simulated for URL {}", - user.failure_mode, - url.path - ); - match failure_mode { - FailureMode::SlowResponse { - rel_path_prefix: prefix, - duration: dur, - } if url.path.starts_with(prefix) => { - warn!( - "Simulating server failure: Responding slowly after {} seconds", - &dur.as_secs() - ); - thread::sleep(*dur); - } - FailureMode::Error500Response { - rel_path_prefix: prefix, - } if url.path.starts_with(prefix) => { - warn!("Simulating server failure: Responding with HTTP 500"); - request - .respond(Response::empty(StatusCode(500))) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err)))?; - return Err(Error::custom( - "Aborting after deliberately returning a HTTP 500 response", - )); - } - FailureMode::Error503Response { - rel_path_prefix: prefix, - } if url.path.starts_with(prefix) => { - warn!("Simulating server failure: Responding with HTTP 503"); - request - .respond(Response::empty(StatusCode(503))) - .map_err(|err: std::io::Error| Error::custom(format!("IO error: {}", err)))?; - return Err(Error::custom( - "Aborting after deliberately returning a HTTP 503 response", - )); - } - _ => { - trace!("No simulation rules matched"); - } - } - } - } - - Ok(request) -} - -static SELF_SIGNED_CERT_PEM: &[u8; 1160] = br#" ------BEGIN CERTIFICATE----- -MIIDNjCCAh6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAzMTEwLwYDVQQDEygyMDBBRTIzM0Y4RUE2NkEwMTIyNTJDQThFRTA3OEE5NDM4NEEyQ0JBMCAXDTIxMDIwNTEzMTMxOFoYDzMwMTcwOTEyMTMxMzE4WjAzMTEwLwYDVQQDEygyMDBBRTIzM0Y4RUE2NkEwMTIyNTJDQThFRTA3OEE5NDM4NEEyQ0JBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsb/U46pChhSpznNzX5+XETV+cmSs8AhqVP4Dka7W7RxJnc1H/S5aZRFZsRuQJ7HNW6S9C49WhaY2Pq7s0MQBNjb58WP7XoKjtMrjO6yxOfTv/KwRDbJBahA0H28PpjbKGVHFCN00J8ftV5Cq5K6nLdUslJrNNLx7Rdr3JymHEksJTeK1MQuRtt9EO/1uy1/6a9vIljLUxy2QkbkgVh46GNSu23FAzp21c6c6A99V0FWYhDFSywROpQlhpjuijJKGUR2mulDkp3uaOhcmyUFCOoZ5iZfemI92J8QBLoR2mpQ1d6Kj53P4BgnaiWDSe5JifzDKEFyXhNXkegwI1f+XhwIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQgCuIz+OpmoBIlLKjuB4qUOEosujAfBgNVHSMEGDAWgBQgCuIz+OpmoBIlLKjuB4qUOEosujANBgkqhkiG9w0BAQsFAAOCAQEABAPbMHpra5BFLRtqX/UG/x8yOpjEepIKdSH7sP8QbYcJXa1f7rAe8ZksgmkrLRegwAqo1hcCxJrEaVHTuW+jd4gy9K7HMp+wLaz6W0ToiKZdCVdTH8xIRxH/nVwWFI//Q4F7Qkm+ceHAeHs5qDDMLBuuZz15VcXcw4HaOkDcxeaqdo+8LXx6jvg0Pz5qzjFvdFIxdd8U/q2v2bUSN4g7CZ4Ae6ate0VPCozflIRauNCQ3BBvUMAwxMg9mkNDtpcbJ8rmqMwSjMTP1g9YIDZ2w9BGUagV0xDSHiE56vONQBX209/AWyzQxrvV6jw/222FX2rJL9UNDR+M3jH1QJzS7g== ------END CERTIFICATE----- -"#; - -static SELF_SIGNED_KEY_PEM: &[u8; 1705] = br#" ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCxv9TjqkKGFKnO -c3Nfn5cRNX5yZKzwCGpU/gORrtbtHEmdzUf9LlplEVmxG5Ansc1bpL0Lj1aFpjY+ -ruzQxAE2NvnxY/tegqO0yuM7rLE59O/8rBENskFqEDQfbw+mNsoZUcUI3TQnx+1X -kKrkrqct1SyUms00vHtF2vcnKYcSSwlN4rUxC5G230Q7/W7LX/pr28iWMtTHLZCR -uSBWHjoY1K7bcUDOnbVzpzoD31XQVZiEMVLLBE6lCWGmO6KMkoZRHaa6UOSne5o6 -FybJQUI6hnmJl96Yj3YnxAEuhHaalDV3oqPnc/gGCdqJYNJ7kmJ/MMoQXJeE1eR6 -DAjV/5eHAgMBAAECggEABADSBp6bCPIGMQQgoRKzEEwoIONrkaxe2LMv2WQaqxRs -BAXPjUAyAPy3DGoWgQ5cFahMKap8xF3N8vN1me4QKOxsDKe3zZUbosK/A2UMSMXf -cc1eRPSyzHS498xEifXJ73AMA/sXZZ33FnXHo4bbdQjMDDzASmPEUvpvfo5M4HiO -hWMd1+vL/zbTvOJblPax7pPG4wL5+U88MezhcYZQ5bCE1Ggixuvnm3UIZaEyBz8+ -Jb93RK1f+dXMTnT1PmKaBMWuALzM1wgkES6KLn9ZR6J0x+5r+FVe3lAzUPnsNN0W -fDFVZ+A+padHmrUR+fYIcZRvjJU0wspsOppezM8rwQKBgQDnG80QQ9NwQESL14bS -rXeruqnUngWEOBO8axvF+WR/ImhZAbagDl+F3ERDw+r7b3HkXrmgnVnc9GbuFP27 -8jsZsx7aWiejcFkvSW21msDmKEm7ZzBvkcfuWsRUjQk+adLzZcv+0fhJAA/Z3qak -uBctntaiQJI/xAoxI2Mbo1s2SQKBgQDE5MrZ0eC69RLseZtMc4oligw8VNGRB5tN -W9kgXMRpGN2tGsaQQ5fv4B7/gDLZ9HD9g4pAYDMAvjPFYzvfFdvdHbNj5C85nPK0 -P/4xLNkzULja28cwzahzCufNuj32fjt5WVPwfqZCd2uP7pl0AIf4lfdx3jp//f0g -xplrmw8fTwKBgBaLTrisdR65FjayApPgmhDld5WnCJC6S6qQpDfuuQ/x0k4EbcU1 -Qbo0H3Cg1vZKC8kkOGVjlBWKvdOxtoK0AXHjWDoim0VFO13ygsI5Y2HQQkkGquHn -TaKBti8tRt6QwiQ+JOUppFeyqtks8AKXdqNboEJZnCqePARJGGzkxYwJAoGAEHIT -x3HSVYtW002s/QvBhDUtpHRpNLXv8Nw1HJDjDuw2x9iusSoULMMJk8m/dZkHPwWX -rJzcZbl9VYVeYNnQjX2HmFZc43EKjKezsaPPWIvrhMxKrPbglQtaJULjHg2ZJh+h -9Tp+5JpY76K8SoYo1UihbG9lb39lfzFXazd+Yd0CgYEAuP8OcGYA9Flg4VITsmsR -quZMVrwtPtNEhgfUiJ4v1fCr1OK/QYAufz12GwcK92Q0GMhSkTxjuwvx5EvMIQn2 -oGnjilZ7SOyWqZYYqnOSAa1QyS1jKwVeGr0VbZTUsxAa1j6e3IDfjulXVcAsY3Py -oku+A8ZldXbm+E5p9xuOE7w= ------END PRIVATE KEY----- -"#;