diff --git a/Cargo.lock b/Cargo.lock index 462dcee..a216954 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "ansi_term" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ "winapi", ] [[package]] name = "async-trait" -version = "0.1.51" +version = "0.1.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e" +checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3" dependencies = [ "proc-macro2", "quote", @@ -33,12 +33,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - [[package]] name = "bitflags" version = "1.3.2" @@ -59,9 +53,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "2.33.3" +version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "ansi_term", "atty", @@ -102,9 +96,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" +checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4" dependencies = [ "futures-channel", "futures-core", @@ -117,9 +111,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" +checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b" dependencies = [ "futures-core", "futures-sink", @@ -127,15 +121,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" +checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" [[package]] name = "futures-executor" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" +checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a" dependencies = [ "futures-core", "futures-task", @@ -144,18 +138,16 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" +checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2" [[package]] name = "futures-macro" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" +checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c" dependencies = [ - "autocfg", - "proc-macro-hack", "proc-macro2", "quote", "syn", @@ -163,23 +155,22 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" +checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508" [[package]] name = "futures-task" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" +checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72" [[package]] name = "futures-util" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" +checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" dependencies = [ - "autocfg", "futures-channel", "futures-core", "futures-io", @@ -189,16 +180,14 @@ dependencies = [ "memchr", "pin-project-lite", "pin-utils", - "proc-macro-hack", - "proc-macro-nested", "slab", ] [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" dependencies = [ "cfg-if", "libc", @@ -280,9 +269,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.104" +version = "0.2.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b2f96d100e1cf1929e7719b7edb3b90ab5298072638fccd77be9ce942ecdfce" +checksum = "0a8d982fa7a96a000f6ec4cfe966de9703eccde29750df2bb8949da91b0e818d" [[package]] name = "linked-hash-map" @@ -368,9 +357,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ "hermit-abi", "libc", @@ -378,9 +367,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" [[package]] name = "parking_lot" @@ -415,9 +404,9 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pin-project-lite" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" [[package]] name = "pin-utils" @@ -427,27 +416,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "ppv-lite86" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ca011bd0129ff4ae15cd04c4eef202cadf6c51c21e47aba319b4e0501db741" - -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "proc-macro2" -version = "1.0.30" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc3358ebc67bc8b7fa0c007f945b0b18226f78437d61bec735a9eb96b61ee70" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ "unicode-xid", ] @@ -460,9 +437,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.10" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" dependencies = [ "proc-macro2", ] @@ -560,9 +537,9 @@ checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" [[package]] name = "smallvec" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" [[package]] name = "socket2" @@ -583,9 +560,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" -version = "1.0.80" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194" +checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" dependencies = [ "proc-macro2", "quote", @@ -623,9 +600,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83b2a3d4d9091d0abd7eba4dc2710b1718583bd4d8992e2190720ea38f391f7" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" dependencies = [ "tinyvec_macros", ] @@ -638,11 +615,10 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.12.0" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2c2416fdedca8443ae44b4527de1ea633af61d8f7169ffa6e72c5b53d24efcc" +checksum = "0c27a64b625de6d309e8c57716ba93021dccf1b3b5c97edd6d3dd2d2135afc0a" dependencies = [ - "autocfg", "bytes", "libc", "memchr", @@ -658,9 +634,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "1.5.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2dd85aeaba7b68df939bd357c6afb36c87951be9e80bf9c859f2fc3e9fca0fd" +checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index cad2f99..0b47865 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,9 +12,9 @@ readme = "README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tokio = { version = "1.6.1", features = ["full"] } -futures = "0.3.15" -trust-dns-resolver = { version = "0.20.3" } +tokio = { version = "1.16.1", features = ["full"] } +futures = "0.3.19" +trust-dns-resolver = "0.20.3" # trust-dns-resolver = { git = "https://github.com/Edu4rdSHL/trust-dns", branch = "main" } clap = "2.33.3" -rand = "0.8.3" +rand = "0.8.4" diff --git a/rusolver.1 b/rusolver.1 index b034390..1fa2e01 100644 --- a/rusolver.1 +++ b/rusolver.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.48.5. -.TH RUSOLVER "1" "January 2022" "Rusolver 0.8.0" "User Commands" +.TH RUSOLVER "1" "February 2022" "Rusolver 0.8.0" "User Commands" .SH NAME Rusolver \- manual page for Rusolver 0.8.0 .SH DESCRIPTION diff --git a/src/args.rs b/src/args.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..cdacf92 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,4 @@ +pub mod resolver; +pub mod utils; + +mod structs; diff --git a/src/main.rs b/src/main.rs index 811effe..fb83357 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,26 +1,19 @@ use { clap::{value_t, App, Arg}, futures::stream::{self, StreamExt}, - rand::{distributions::Alphanumeric, thread_rng as rng, Rng}, - std::{ - collections::HashSet, - net::{Ipv4Addr, SocketAddr}, - }, + rusolver::{resolver, utils}, + std::collections::HashSet, tokio::{ self, - fs::File, io::{self, AsyncReadExt}, }, - trust_dns_resolver::{ - config::{ - LookupIpStrategy, NameServerConfig, NameServerConfigGroup, Protocol, ResolverConfig, - ResolverOpts, - }, - name_server::{GenericConnection, GenericConnectionProvider, TokioRuntime}, - AsyncResolver, TokioAsyncResolver, - }, + trust_dns_resolver::config::{LookupIpStrategy, ResolverOpts}, }; +// Please add support for AAAA, TXT, SRV, NAPTR, PTR, CNAME, DNAME, MX, NS, SOA, LOC, SVCB, HTTPS, SPF, CAA and AVC resource records. +// This could use a new command line option such as -t, e.g. echo www.example.com | rusolver -i -t AAAA. It might also make sense +// to change -i/--ip to -d/--data with the text Display the record data. + #[tokio::main] async fn main() -> Result<(), Box> { // Eval args @@ -133,13 +126,14 @@ async fn main() -> Result<(), Box> { if custom_resolvers { nameserver_ips = - return_file_lines(value_t!(matches.value_of("resolvers"), String).unwrap()).await; + utils::return_file_lines(value_t!(matches.value_of("resolvers"), String).unwrap()) + .await; nameserver_ips.retain(|ip| !ip.is_empty()); } else { nameserver_ips = built_in_nameservers.clone(); } - let resolvers = return_tokio_asyncresolver(nameserver_ips, options); - let trustable_resolver = return_tokio_asyncresolver(built_in_nameservers, options); + let resolvers = resolver::return_tokio_asyncresolver(nameserver_ips, options); + let trustable_resolver = resolver::return_tokio_asyncresolver(built_in_nameservers, options); let mut wildcard_ips = HashSet::new(); // Read stdin @@ -149,7 +143,7 @@ async fn main() -> Result<(), Box> { let hosts: Vec = if matches.is_present("domain") { let domain = value_t!(matches, "domain", String).unwrap(); - wildcard_ips = detect_wildcards(&domain, &trustable_resolver, quiet_flag).await; + wildcard_ips = utils::detect_wildcards(&domain, &trustable_resolver, quiet_flag).await; buffer .lines() .map(|word| format!("{}.{}", word, domain)) @@ -193,110 +187,3 @@ async fn main() -> Result<(), Box> { Ok(()) } - -// In the future I may need to implement error propagation, but for now it's fine -// to deal with matches -async fn return_file_lines(file: String) -> HashSet { - let mut f = match File::open(&file).await { - Ok(file) => file, - Err(e) => { - eprintln!("Error opening resolvers file. Error: {}", e); - std::process::exit(1) - } - }; - let mut buffer = String::new(); - - match f.read_to_string(&mut buffer).await { - Ok(a) => a, - _ => unreachable!("Error reading to string."), - }; - buffer.lines().map(|f| format!("{}:53", f)).collect() -} - -fn return_tokio_asyncresolver( - nameserver_ips: HashSet, - options: ResolverOpts, -) -> AsyncResolver> { - let mut name_servers = NameServerConfigGroup::with_capacity(nameserver_ips.len() * 2); - - name_servers.extend(nameserver_ips.into_iter().flat_map(|server| { - let socket_addr = SocketAddr::V4(match server.parse() { - Ok(a) => a, - Err(e) => unreachable!( - "Error parsing the server {}, only IPv4 are allowed. Error: {}", - server, e - ), - }); - - std::iter::once(NameServerConfig { - socket_addr, - protocol: Protocol::Udp, - tls_dns_name: None, - trust_nx_responses: false, - }) - .chain(std::iter::once(NameServerConfig { - socket_addr, - protocol: Protocol::Tcp, - tls_dns_name: None, - trust_nx_responses: false, - })) - })); - - TokioAsyncResolver::tokio( - ResolverConfig::from_parts(None, vec![], name_servers), - options, - ) - .unwrap() -} - -async fn detect_wildcards( - target: &str, - resolvers: &AsyncResolver>, - quiet_flag: bool, -) -> HashSet { - if !quiet_flag { - println!("Running wildcards detection for {}...\n", target) - } - let mut generated_wilcards: HashSet = HashSet::new(); - for _ in 1..20 { - generated_wilcards.insert(format!( - "{}.{}.", - rng() - .sample_iter(Alphanumeric) - .take(15) - .map(char::from) - .collect::(), - target - )); - } - - generated_wilcards = stream::iter(generated_wilcards.clone().into_iter().map( - |host| async move { - if let Ok(ips) = resolvers.ipv4_lookup(host.clone()).await { - ips.into_iter() - .map(|x| x.to_string()) - .collect::>() - } else { - Vec::new() - } - }, - )) - .buffer_unordered(10) - .map(stream::iter) - .flatten() - .collect() - .await; - - generated_wilcards.retain(|ip| ip.parse::().is_ok()); - - if !generated_wilcards.is_empty() && !quiet_flag { - println!( - "Wilcards detected for {} and wildcard's IP saved for furter work.", - target - ); - println!("Wilcard IPs: {:?}\n", generated_wilcards) - } else if !quiet_flag { - println!("No wilcards detected for {}, nice!\n", target) - } - generated_wilcards -} diff --git a/src/resolver.rs b/src/resolver.rs new file mode 100644 index 0000000..582ed07 --- /dev/null +++ b/src/resolver.rs @@ -0,0 +1,44 @@ +use { + std::{collections::HashSet, net::SocketAddr}, + trust_dns_resolver::{ + config::{NameServerConfig, NameServerConfigGroup, Protocol, ResolverConfig, ResolverOpts}, + name_server::{GenericConnection, GenericConnectionProvider, TokioRuntime}, + AsyncResolver, TokioAsyncResolver, + }, +}; + +pub fn return_tokio_asyncresolver( + nameserver_ips: HashSet, + options: ResolverOpts, +) -> AsyncResolver> { + let mut name_servers = NameServerConfigGroup::with_capacity(nameserver_ips.len() * 2); + + name_servers.extend(nameserver_ips.into_iter().flat_map(|server| { + let socket_addr = SocketAddr::V4(match server.parse() { + Ok(a) => a, + Err(e) => unreachable!( + "Error parsing the server {}, only IPv4 are allowed. Error: {}", + server, e + ), + }); + + std::iter::once(NameServerConfig { + socket_addr, + protocol: Protocol::Udp, + tls_dns_name: None, + trust_nx_responses: false, + }) + .chain(std::iter::once(NameServerConfig { + socket_addr, + protocol: Protocol::Tcp, + tls_dns_name: None, + trust_nx_responses: false, + })) + })); + + TokioAsyncResolver::tokio( + ResolverConfig::from_parts(None, vec![], name_servers), + options, + ) + .unwrap() +} diff --git a/src/structs.rs b/src/structs.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..1e9df99 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,81 @@ +use { + futures::stream::{self, StreamExt}, + rand::{distributions::Alphanumeric, thread_rng as rng, Rng}, + std::{collections::HashSet, net::Ipv4Addr}, + tokio::{self, fs::File, io::AsyncReadExt}, + trust_dns_resolver::{ + name_server::{GenericConnection, GenericConnectionProvider, TokioRuntime}, + AsyncResolver, + }, +}; + +// In the future I may need to implement error propagation, but for now it's fine +// to deal with matches +pub async fn return_file_lines(file: String) -> HashSet { + let mut f = match File::open(&file).await { + Ok(file) => file, + Err(e) => { + eprintln!("Error opening resolvers file. Error: {}", e); + std::process::exit(1) + } + }; + let mut buffer = String::new(); + + match f.read_to_string(&mut buffer).await { + Ok(a) => a, + _ => unreachable!("Error reading to string."), + }; + buffer.lines().map(|f| format!("{}:53", f)).collect() +} + +pub async fn detect_wildcards( + target: &str, + resolvers: &AsyncResolver>, + quiet_flag: bool, +) -> HashSet { + if !quiet_flag { + println!("Running wildcards detection for {}...\n", target) + } + let mut generated_wilcards: HashSet = HashSet::new(); + for _ in 1..20 { + generated_wilcards.insert(format!( + "{}.{}.", + rng() + .sample_iter(Alphanumeric) + .take(15) + .map(char::from) + .collect::(), + target + )); + } + + generated_wilcards = stream::iter(generated_wilcards.clone().into_iter().map( + |host| async move { + if let Ok(ips) = resolvers.ipv4_lookup(host.clone()).await { + ips.into_iter() + .map(|x| x.to_string()) + .collect::>() + } else { + Vec::new() + } + }, + )) + .buffer_unordered(10) + .map(stream::iter) + .flatten() + .collect() + .await; + + generated_wilcards.retain(|ip| ip.parse::().is_ok()); + + if !generated_wilcards.is_empty() && !quiet_flag { + println!( + "Wilcards detected for {} and wildcard's IP saved for furter work.", + target + ); + println!("Wilcard IPs: {:?}\n", generated_wilcards) + } else if !quiet_flag { + println!("No wilcards detected for {}, nice!\n", target) + } + generated_wilcards +}