From 86c35254933ca5f367fdffed886b119bf3427d25 Mon Sep 17 00:00:00 2001 From: pyro Date: Wed, 2 Sep 2026 14:29:50 -0500 Subject: [PATCH] fixed a bug in project promotion where the folder for the project name would be duplicated, and added rustbuster to the rust tools available! --- Cargo.lock | 711 +++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 3 + src/funcs.rs | 72 ++++- src/lib.rs | 308 +++++++++++++++++++- src/rust_tools.rs | 92 ++++++ 5 files changed, 1168 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 300ddfa..3dc322c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -653,6 +653,16 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" +[[package]] +name = "combine" +version = "4.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfc320937d09e6de266b31b9afb480f197d7a861be86be7cb2ea7e5d1bfffc5e" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "compact_str" version = "0.9.1" @@ -714,6 +724,16 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation" version = "0.10.1" @@ -1059,6 +1079,18 @@ dependencies = [ "syn 3.0.3", ] +[[package]] +name = "dns-lookup" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6120e7e5dcd1c90098e349def389e2797377cdbe6b465ad8fdd115c0c99d5cf2" +dependencies = [ + "cfg-if", + "libc", + "socket2", + "windows-sys 0.61.2", +] + [[package]] name = "document-features" version = "0.2.12" @@ -1080,12 +1112,33 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[package]] name = "endi" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099" +[[package]] +name = "enum-as-inner" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "enumflags2" version = "0.7.12" @@ -1235,6 +1288,16 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", + "futures-sink", +] + [[package]] name = "futures-core" version = "0.3.32" @@ -1271,6 +1334,12 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "futures-sink" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" + [[package]] name = "futures-task" version = "0.3.32" @@ -1284,8 +1353,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-core", + "futures-io", "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "slab", ] @@ -1307,8 +1379,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -1330,9 +1404,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 6.0.0", "rand_core 0.10.1", + "wasm-bindgen", ] [[package]] @@ -1344,6 +1420,25 @@ dependencies = [ "polyval", ] +[[package]] +name = "h2" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8e5e5a340588f4452631496976cf8636d4a7ecf600239fdc27615d2530bc16" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.16.1" @@ -1430,6 +1525,29 @@ dependencies = [ "itoa", ] +[[package]] +name = "http-body" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + [[package]] name = "httparse" version = "1.10.1" @@ -1445,6 +1563,67 @@ dependencies = [ "typenum", ] +[[package]] +name = "hyper" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b501faa50e7a26c3d3560ca625132f4078a17771f4810baf70475ae48cbe43" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", +] + [[package]] name = "icu_collections" version = "2.3.0" @@ -1534,6 +1713,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "idna" version = "1.1.0" @@ -1606,6 +1795,19 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "ipconfig" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d40460c0ce33d6ce4b0630ad68ff63d6661961c48b6dba35e5a4d81cfb48222" +dependencies = [ + "socket2", + "widestring", + "windows-registry", + "windows-result", + "windows-sys 0.61.2", +] + [[package]] name = "ipnet" version = "2.12.0" @@ -1633,6 +1835,55 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys", + "log", + "simd_cesu8", + "thiserror 2.0.18", + "walkdir", + "windows-link", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.117", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.117", +] + [[package]] name = "jobserver" version = "0.1.34" @@ -1714,6 +1965,12 @@ dependencies = [ "bitflags 2.12.1", ] +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-raw-sys" version = "0.12.1" @@ -1756,6 +2013,21 @@ dependencies = [ "hashbrown 0.16.1", ] +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "mac_address" version = "1.1.8" @@ -1796,6 +2068,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -2073,6 +2351,12 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + [[package]] name = "ordered-float" version = "4.6.0" @@ -2328,6 +2612,63 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quinn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror 2.0.18", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04759210543be93709136e28212294a659ef5001836ff4eab4d663e4529bba83" +dependencies = [ + "aws-lc-rs", + "bytes", + "getrandom 0.4.3", + "lru-slab", + "rand 0.10.2", + "rand_pcg", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.18", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.61.2", +] + [[package]] name = "quote" version = "1.0.45" @@ -2355,6 +2696,8 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ + "libc", + "rand_chacha 0.3.1", "rand_core 0.6.4", ] @@ -2364,7 +2707,7 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" dependencies = [ - "rand_chacha", + "rand_chacha 0.9.0", "rand_core 0.9.5", ] @@ -2379,6 +2722,16 @@ dependencies = [ "rand_core 0.10.1", ] +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + [[package]] name = "rand_chacha" version = "0.9.0" @@ -2394,6 +2747,9 @@ name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] [[package]] name = "rand_core" @@ -2410,6 +2766,15 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" +[[package]] +name = "rand_pcg" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" +dependencies = [ + "rand_core 0.10.1", +] + [[package]] name = "ratatui" version = "0.30.0" @@ -2567,6 +2932,52 @@ version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" +[[package]] +name = "reqwest" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "mime", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "rustls-platform-verifier", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "resolv-conf" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7" + [[package]] name = "rhai" version = "1.25.1" @@ -2665,6 +3076,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pemfile" version = "2.2.0" @@ -2680,9 +3103,37 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" dependencies = [ + "web-time", "zeroize", ] +[[package]] +name = "rustls-platform-verifier" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" version = "0.103.13" @@ -2716,6 +3167,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -2748,7 +3208,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ "bitflags 2.12.1", - "core-foundation", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -2889,6 +3349,22 @@ version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" +[[package]] +name = "simd_cesu8" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "siphasher" version = "1.0.3" @@ -3033,6 +3509,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + [[package]] name = "synstructure" version = "0.13.2" @@ -3059,6 +3544,27 @@ dependencies = [ "windows", ] +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags 2.12.1", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tempfile" version = "3.27.0" @@ -3144,6 +3650,7 @@ dependencies = [ "clap", "clipboard", "crossterm", + "dns-lookup", "fs_extra", "headless_chrome", "ipnet", @@ -3152,6 +3659,7 @@ dependencies = [ "ratatui", "rayon", "rcgen", + "reqwest", "rhai", "rustc-hash", "rustls", @@ -3160,6 +3668,7 @@ dependencies = [ "textwrap", "tokio", "tokio-rustls", + "trust-dns-resolver", "walkdir", ] @@ -3275,6 +3784,21 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinyvec" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.52.3" @@ -3313,6 +3837,20 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-util" +version = "0.7.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "libc", + "pin-project-lite", + "tokio", +] + [[package]] name = "toml_datetime" version = "1.1.1+spec-1.1.0" @@ -3343,6 +3881,51 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" +dependencies = [ + "bitflags 2.12.1", + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", + "url", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + [[package]] name = "tracing" version = "0.1.44" @@ -3374,6 +3957,58 @@ dependencies = [ "once_cell", ] +[[package]] +name = "trust-dns-proto" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3119112651c157f4488931a01e586aa459736e9d6046d3bd9105ffb69352d374" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna 0.4.0", + "ipnet", + "once_cell", + "rand 0.8.6", + "smallvec", + "thiserror 1.0.69", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a3e6c3aff1718b3c73e395d1f35202ba2ffa847c6a62eea0db8fb4cfe30be6" +dependencies = [ + "cfg-if", + "futures-util", + "ipconfig", + "lru-cache", + "once_cell", + "parking_lot", + "rand 0.8.6", + "resolv-conf", + "smallvec", + "thiserror 1.0.69", + "tokio", + "tracing", + "trust-dns-proto", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "tungstenite" version = "0.29.0" @@ -3413,6 +4048,12 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + [[package]] name = "unicode-ident" version = "1.0.24" @@ -3425,6 +4066,15 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" +[[package]] +name = "unicode-normalization" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-segmentation" version = "1.13.3" @@ -3501,7 +4151,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", - "idna", + "idna 1.1.0", "percent-encoding", "serde", ] @@ -3562,6 +4212,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -3590,6 +4249,16 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.122" @@ -3622,6 +4291,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "web-sys" +version = "0.3.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "web-time" version = "1.1.0" @@ -3632,6 +4311,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webpki-roots" version = "1.0.9" @@ -3722,6 +4410,12 @@ dependencies = [ "libc", ] +[[package]] +name = "widestring" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" + [[package]] name = "winapi" version = "0.3.9" @@ -3849,6 +4543,17 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link", + "windows-result", + "windows-strings", +] + [[package]] name = "windows-result" version = "0.4.1" diff --git a/Cargo.toml b/Cargo.toml index df967ef..faadecf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ anyhow = "1.0.103" clap = { version = "4.6.1", features = ["derive"] } clipboard = "0.5.0" crossterm = "0.29.0" +dns-lookup = "4.0.1" fs_extra = "1.3.0" headless_chrome = "1.0.22" ipnet = "2.12.0" @@ -17,6 +18,7 @@ rand = "0.10.2" ratatui = "0.30.0" rayon = "1.12.0" rcgen = "0.14.8" +reqwest = { version = "0.13.4", features = ["blocking"] } rhai = { version = "1.24.0", features = ["metadata", "sync"] } rustc-hash = "2.1.2" rustls = "0.23.43" @@ -25,4 +27,5 @@ sysinfo = "0.39.6" textwrap = "0.16.2" tokio = { version = "1.52.3", features = ["full"] } tokio-rustls = "0.26.4" +trust-dns-resolver = "0.23.2" walkdir = "2.5.0" diff --git a/src/funcs.rs b/src/funcs.rs index f687373..416ee3e 100644 --- a/src/funcs.rs +++ b/src/funcs.rs @@ -6,6 +6,7 @@ use crossterm::{ terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode}, }; use ratatui::{ + layout::{Constraint, Layout}, prelude::*, widgets::{Block, Borders, List, ListItem, ListState, Paragraph}, }; @@ -248,19 +249,68 @@ pub fn run_tui( state.config.get(setting).unwrap() ))); } - let info_area_height = top_chunks[1].height.saturating_sub(2) as usize; - if state.info_scroll as usize > info_lines.len().saturating_sub(info_area_height) { - state.info_scroll = info_lines.len().saturating_sub(info_area_height) as u16; - } - let info_paragraph = Paragraph::new(info_lines) - .block( + if state.progress_bars.is_empty() { + let info_area_height = top_chunks[2].height.saturating_sub(2) as usize; + if state.info_scroll as usize > info_lines.len().saturating_sub(info_area_height) { + state.info_scroll = info_lines.len().saturating_sub(info_area_height) as u16; + } + let info_paragraph = Paragraph::new(info_lines) + .block( + Block::default() + .borders(Borders::ALL) + .title("Selected Project Information"), + ) + .scroll((state.info_scroll, 0)) + .wrap(ratatui::widgets::Wrap { trim: false }); + f.render_widget(info_paragraph, top_chunks[2]); + } else { + let progress_section = Layout::default() + .direction(Direction::Vertical) + .constraints([Constraint::Percentage(60), Constraint::Percentage(40)]) + .split(top_chunks[2]); + let info_area_height = top_chunks[2].height.saturating_sub(2) as usize; + if state.info_scroll as usize > info_lines.len().saturating_sub(info_area_height) { + state.info_scroll = info_lines.len().saturating_sub(info_area_height) as u16; + } + let info_paragraph = Paragraph::new(info_lines) + .block( + Block::default() + .borders(Borders::ALL) + .title("Selected Project Information"), + ) + .scroll((state.info_scroll, 0)) + .wrap(ratatui::widgets::Wrap { trim: false }); + f.render_widget(info_paragraph, progress_section[0]); + let mut progress_lines = Vec::new(); + state.progress_bars.iter().for_each(|progress| { + if let Ok(status) = progress.read() { + let percentage = status.complete / status.total * 100; + if percentage == 100 { + progress_lines.push(Line::from(Span::styled( + format!( + "{} - {}/{} ({}%)", + status.name, status.complete, status.total, percentage + ), + Style::default().fg(Color::Green), + ))); + } else { + progress_lines.push(Line::from(Span::styled( + format!( + "{} - {}/{} ({}%)", + status.name, status.complete, status.total, percentage + ), + Style::default().fg(Color::Magenta), + ))); + } + } + }); + let progress_paragraph = Paragraph::new(progress_lines).block( Block::default() .borders(Borders::ALL) - .title("Selected Project Information"), - ) - .scroll((state.info_scroll, 0)) - .wrap(ratatui::widgets::Wrap { trim: false }); - f.render_widget(info_paragraph, top_chunks[2]); + .title("Operations in progress"), + ); + f.render_widget(progress_paragraph, progress_section[1]); + } let mut output_lines = Vec::new(); state.output.iter().for_each(|text| { let line = Line::from(Span::raw(text)); diff --git a/src/lib.rs b/src/lib.rs index 552dd7c..7e857a2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +use crate::rust_tools::rustwitness; use clipboard::ClipboardContext; use clipboard::ClipboardProvider; use fs_extra::dir::{CopyOptions, copy}; @@ -6,24 +7,26 @@ use keyring::Entry; use ratatui::crossterm::event; use rayon::prelude::*; use rhai::{AST, Dynamic, Engine, Scope}; +use rust_tools::{BusterTarget, rustbuster}; use rustls::{ClientConfig, ClientConnection, RootCertStore, StreamOwned, pki_types::ServerName}; use std::collections::HashMap; use std::env; use std::error::Error; +use std::fs::OpenOptions; use std::fs::{self, File, create_dir_all, read_dir, read_to_string, remove_dir, remove_dir_all}; use std::io::{self, BufRead, BufReader, Read, Write}; use std::net::IpAddr; +use std::net::SocketAddr; use std::net::TcpStream; use std::path::PathBuf; use std::process::{Command, Stdio}; +use std::sync::RwLock; use std::sync::mpsc::Receiver; use std::sync::{Arc, Mutex, mpsc::Sender, mpsc::channel}; use std::time::Duration; use std::time::{self, Instant}; use walkdir::WalkDir; -use crate::rust_tools::rustwitness; - pub mod funcs; pub mod rust_tools; pub mod server; @@ -99,6 +102,7 @@ pub struct AppState { pub remoting: bool, pub help: Vec, pub name: String, + pub progress_bars: Vec>>, } impl AppState { @@ -138,6 +142,7 @@ impl AppState { remoting: false, help: Vec::new(), name: String::new(), + progress_bars: Vec::new(), } } @@ -251,6 +256,10 @@ impl AppState { self.help .push("stop_db\nrestart this project's distrobox".to_string()); self.help.push("rustwitness\nRun a scan on the hosts in the urls.txt file in yoru project files directory that captures screenshots of those urls, optionally through a proxy.".to_string()); + self.help.push("portscan\nRun a simple TCP portscan on either the scope for the project, or a given list of ips.\nportscan ip,ip,ip,ip port,port,port,port or portscan port,port,port".to_string()); + self.help.push("rustbuster\nRun the Subdomain/Subdirectory bruteforcetool RustBuster (included in tetanus now!) against a given domain name or url.\nrustbuster target,target,target subs=/path/to/subwordlist dirs=/path/to/dirwordlist".to_string()); + self.help + .push("clear_operations\nClear the progress section of the tool.".to_string()); self.help.push("exit\nquit the tool\n".to_string()); self.initialize_modules(); return Ok(()); @@ -1077,6 +1086,271 @@ impl AppState { } } } + "portscan" => { + if let Some(project) = self.projects.get(self.selected_project) { + let mut ports = Vec::new(); + let mut hosts = project.hosts.clone(); + if let Some(args) = command_args { + let args_vec: Vec<&str> = args.split_whitespace().collect(); + match args_vec.len() { + 1 => { + args_vec[0].split(",").into_iter().for_each(|p| { + if let Ok(port) = p.trim().parse::() { + ports.push(port); + } + }); + } + 2 => { + args_vec[0].split(",").into_iter().for_each(|ip| { + if let Ok(ip) = ip.parse::() { + let mut new_host = Host::new(); + new_host.ip = ip.to_string(); + hosts.push(new_host); + } else if let Ok(net) = ip.parse::() { + for host_addr in net.hosts() { + let mut new_host = Host::new(); + new_host.ip = host_addr.to_string(); + hosts.push(new_host); + } + } + }); + args_vec[1].split(",").into_iter().for_each(|p| { + if p.contains("-") { + if let Some((start, end)) = p.split_once("-") { + if let Ok(start) = start.parse::() { + if let Ok(end) = end.parse::() { + for range in [start..end] { + range.into_iter().for_each(|port| { + ports.push(port.clone()); + }); + } + } + } + } + } else if let Ok(port) = p.trim().parse::() { + ports.push(port); + } + }); + } + _ => {} + } + if !ports.is_empty() && !hosts.is_empty() { + let _ = self.main_tx.send(ToolMessage::Output(( + rid, + format!("scanning {} ports on {} hosts", ports.len(), hosts.len()), + ))); + let project_clone = Arc::new(Mutex::new(project.clone())); + let id = self.selected_project.clone(); + let tx_clone = self.main_tx.clone(); + self.workers.spawn(move || { + hosts.par_iter_mut().for_each(|h| { + ports.par_iter().for_each(|p| { + let mut host = h.clone(); + match host.check_port(p.clone(), tx_clone.clone()) { + Ok(_) => { + if let Ok(mut lock) = project_clone.lock() { + lock.add_host(host.clone()); + } + } + Err(_) => {} + } + }); + }); + if let Ok(lock) = project_clone.lock() { + let _ = + tx_clone.send(ToolMessage::UpdateProject(id, lock.clone())); + let _ = tx_clone.send(ToolMessage::Output(( + 0, + "[success] portscan finished!".to_string(), + ))); + } + }); + } + } + } + } + "rustbuster" => { + if let Some(args) = command_args { + let args: Vec<&str> = args.split(" ").collect(); + let mut dirs = Vec::new(); + let mut subs = Vec::new(); + let mut targets = Vec::new(); + if args + .iter() + .any(|a| a.contains("subs=") || a.contains("dirs=")) + { + args.iter().for_each(|arg| { + if arg.contains("subs=") { + if let Some((_, sub_path)) = arg.split_once("=") { + if let Ok(subtext) = read_to_string(sub_path) { + subtext.lines().into_iter().for_each(|sub| { + subs.push(sub.to_string()); + }); + } + } + } + if arg.contains("dirs=") { + if let Some((_, dir_path)) = arg.split_once("=") { + if let Ok(dir_text) = read_to_string(dir_path) { + dir_text.lines().into_iter().for_each(|dir| { + dirs.push(dir.to_string()); + }); + } + } + } else { + if arg.contains(",") { + arg.split(",").into_iter().for_each(|t| { + targets.push(t.to_string()); + }); + } else if !arg.contains("=") { + targets.push(arg.to_string()); + } + } + }); + let mut num_dir = 0; + let mut num_sub = 0; + let _ = self.main_tx.send(ToolMessage::Output(( + rid, + format!("{} targets found scanning...", num_dir + num_sub), + ))); + let tx_clone = self.main_tx.clone(); + let out_path = self.projects[self.selected_project].files.clone(); + let project_clone = + Arc::new(Mutex::new(self.projects[self.selected_project].clone())); + let mut buster_targets = Vec::new(); + for target in targets { + if target.contains("://") { + for dir in &dirs { + num_dir += 1; + buster_targets + .push(BusterTarget::Dir(format!("{}/{}", target, dir))); + } + } else if target.contains(".") { + for sub in &subs { + num_sub += 1; + buster_targets + .push(BusterTarget::Sub(format!("{}.{}", sub, target))); + } + } + } + let new_progress = Arc::new(RwLock::new(ToolProgress { + name: "rustbuster".to_string(), + total: num_dir + num_sub, + complete: 0, + })); + self.progress_bars.push(new_progress.clone()); + self.workers.spawn(move || { + buster_targets.par_iter().for_each(|t| match t { + BusterTarget::Dir(_) => { + if let Some(res) = rustbuster(t.clone()) { + let mut url_path = out_path.clone(); + url_path.push("urls.txt"); + if let Ok(mut url_file) = OpenOptions::new() + .write(true) + .append(true) + .create(true) + .open(&url_path) + { + if let Err(e) = writeln!( + url_file, + "{}", + format!("[success] {}", res) + ) { + let _ = tx_clone.send(ToolMessage::Output(( + rid, + format!( + "[error] saving url to {}: {e}", + url_path.display() + ), + ))); + } + } + let _ = tx_clone.send(ToolMessage::Output(( + rid, + format!("[success] {}", res), + ))); + } + if let Ok(mut lock) = new_progress.write() { + lock.complete += 1; + } + } + BusterTarget::Sub(_) => { + if let Some(res) = rustbuster(t.clone()) { + let mut url_path = out_path.clone(); + url_path.push("domains.txt"); + if let Ok(mut url_file) = OpenOptions::new() + .write(true) + .append(true) + .create(true) + .open(&url_path) + { + if let Err(e) = + writeln!(url_file, "{}", format!("{}", res)) + { + let _ = tx_clone.send(ToolMessage::Output(( + rid, + format!( + "[error] saving domain to {}: {e}", + url_path.display() + ), + ))); + } + } + let _ = tx_clone.send(ToolMessage::Output(( + rid, + format!("[success] {}", res), + ))); + if let Some((domain, ip)) = res.split_once(":") { + let mut new_host = Host::new(); + new_host.ip = ip.to_string(); + new_host.hostname = domain.to_string(); + if let Ok(mut project_lock) = project_clone.lock() { + project_lock.add_host(new_host); + } + } + } + if let Ok(mut lock) = new_progress.write() { + lock.complete += 1; + } + } + }); + drop(project_clone); + }); + } else { + let _ = self.main_tx.send(ToolMessage::Output(( + rid, + "[error] no sub or dir wordlist provided!".to_string(), + ))); + let _ = self + .main_tx + .send(ToolMessage::Output((rid, "USAGE:".to_string()))); + let _ = self.main_tx.send(ToolMessage::Output(( + rid, + "rustbuster target,target,target subs=/path/to/subwordlist dirs=/path/to/dirwordlist".to_string(), + ))); + let _ = self.main_tx.send(ToolMessage::Output(( + rid, + "be sure to include the subs= or dirs= part of the command above!" + .to_string(), + ))); + } + } else { + let _ = self.main_tx.send(ToolMessage::Output(( + rid, + "[error] no arguments provided!".to_string(), + ))); + let _ = self + .main_tx + .send(ToolMessage::Output((rid, "USAGE:".to_string()))); + let _ = self.main_tx.send(ToolMessage::Output(( + rid, + "rustbuster target,target,target subs=/path/to/subwordlist dirs=/path/to/dirwordlist".to_string(), + ))); + } + } + "clear_operations" => { + self.progress_bars.clear(); + } "exit" => { self.save_all()?; let _ = self.main_tx.send(ToolMessage::AppStateExit); @@ -1382,9 +1656,9 @@ impl AppState { let return_string = String::from("[success] Project promoted!"); let mut new_project = self.projects[self.selected_project].clone(); let new_files_path = PathBuf::from(self.config.get("current_files").unwrap()) - .join(format!("{}/{}", new_project.org_name, new_project.name)); + .join(format!("{}", new_project.org_name)); let new_notes_path = PathBuf::from(self.config.get("current_notes").unwrap()) - .join(format!("{}/{}", new_project.org_name, new_project.name)); + .join(format!("{}", new_project.org_name)); let mut options = CopyOptions::new(); create_dir_all(&new_files_path)?; create_dir_all(&new_notes_path)?; @@ -2505,6 +2779,26 @@ id: {}", host_file.sync_all()?; Ok(()) } + + pub fn check_port(&mut self, port: u16, tx: Sender) -> Result<(), Box> { + if let Ok(ip) = self.ip.parse::() { + let address = SocketAddr::new(ip, port); + if let Ok(_) = TcpStream::connect_timeout(&address, Duration::from_secs(3)) { + self.add_port(&format!("{}", port)); + let _ = tx.send(ToolMessage::Output(( + 0, + format!("[success] {} is open on {}", port, self.ip), + ))); + } + } else { + let _ = tx.send(ToolMessage::Output(( + 0, + format!("[error] {} is not a valid ip address!", self.ip), + ))); + return Err("not valid IP".into()); + } + return Ok(()); + } } #[derive(Clone, Debug)] @@ -3013,3 +3307,9 @@ struct PromptQuery { id: usize, query: String, } + +struct ToolProgress { + name: String, + total: usize, + complete: usize, +} diff --git a/src/rust_tools.rs b/src/rust_tools.rs index 60d6a8b..e4ead79 100644 --- a/src/rust_tools.rs +++ b/src/rust_tools.rs @@ -1,6 +1,16 @@ use crate::*; use anyhow::Context; +use dns_lookup::lookup_host; use headless_chrome::{Browser, LaunchOptions}; +use reqwest::StatusCode; +use std::net::SocketAddr; +use trust_dns_resolver::lookup::Ipv4Lookup; + +#[derive(Clone)] +pub enum BusterTarget { + Sub(String), + Dir(String), +} pub fn rustwitness( input: String, @@ -61,3 +71,85 @@ pub fn rustwitness( capture_screenshot(&input, proxy.clone(), output.clone())?; Ok(()) } + +pub fn rustbuster(target: BusterTarget) -> Option { + match target { + BusterTarget::Dir(url) => { + if let Ok(resp) = reqwest::blocking::get(&url) { + let status = resp.status(); + match status { + StatusCode::OK => { + return Some(format!("{}", url)); + } + StatusCode::ACCEPTED => { + return Some(format!("{}", url)); + } + StatusCode::CONTINUE => { + return Some(format!("{}", url)); + } + StatusCode::CREATED => { + return Some(format!("{}", url)); + } + StatusCode::FOUND => { + return Some(format!("{}", url)); + } + StatusCode::IM_A_TEAPOT => { + return Some(format!("{}", url)); + } + StatusCode::MOVED_PERMANENTLY => { + return Some(format!("{}", url)); + } + StatusCode::PERMANENT_REDIRECT => { + return Some(format!("{}", url)); + } + StatusCode::TEMPORARY_REDIRECT => { + return Some(format!("{}", url)); + } + _ => { + return None; + } + } + } else { + return None; + } + } + BusterTarget::Sub(name) => { + let mut base = String::new(); + if let Some((given_name, tld)) = name.rsplit_once(".") { + if let Some((_, base_name)) = name.rsplit_once(".") { + base = format!("{}.{}", base_name, tld); + } else { + base = format!("{}.{}", given_name, tld); + } + } + let mut wildcards = Vec::new(); + if base.len() > 0 { + if let Ok(ips) = lookup_host(&format!("burstpyrofoo.{}", base)) { + ips.into_iter().for_each(|ip| { + wildcards.push(ip); + }); + } + } + if let Ok(mut ips) = lookup_host(&name) { + let mut found_ips = Vec::new(); + let not_wild = !ips.all(|ip| wildcards.contains(&ip)); + if not_wild { + ips.for_each(|ip| { + found_ips.push(ip.to_string()); + }); + } + if found_ips.len() > 0 { + let mut out = String::new(); + found_ips.iter().for_each(|ip| { + out.push_str(&format!("{}:{}\n", name, ip)); + }); + return Some(out); + } else { + return None; + } + } else { + return None; + } + } + } +}