diff options
author | Galen Guyer <galen@galenguyer.com> | 2022-07-25 21:17:33 -0400 |
---|---|---|
committer | Galen Guyer <galen@galenguyer.com> | 2022-07-25 21:17:56 -0400 |
commit | b4eb857f107866143b0b06d7c6f3744aea50da02 (patch) | |
tree | 48b1bf3e69c2b22e4a7756bff89c95160325f98c | |
parent | c4a4f360dbf1f2742c33e551a42de8a70e07d506 (diff) |
Use whois query to ensure domain validity
-rw-r--r-- | Cargo.lock | 271 | ||||
-rw-r--r-- | Cargo.toml | 4 | ||||
-rw-r--r-- | data/whois-servers.json | 793 | ||||
-rw-r--r-- | src/main.rs | 10 | ||||
-rw-r--r-- | src/routes/v1/zones.rs | 40 |
5 files changed, 1114 insertions, 4 deletions
@@ -24,6 +24,15 @@ dependencies = [ ] [[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] name = "ansi_term" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -198,7 +207,7 @@ dependencies = [ "num-integer", "num-traits", "serde", - "time", + "time 0.1.43", "winapi", ] @@ -289,6 +298,12 @@ dependencies = [ ] [[package]] +name = "data-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" + +[[package]] name = "digest" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -335,12 +350,56 @@ dependencies = [ ] [[package]] +name = "educe" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07b7cc9cd8c08d10db74fca3b20949b9b6199725c04a0cce6d543496098fcac" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn", +] + +[[package]] name = "either" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "enum-as-inner" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21cdad81446a7f7dc43f6a77409efeb9733d2fa65553efef6018ef257c959b73" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "enum-ordinalize" +version = "3.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2170fc0efee383079a8bdd05d6ea2a184d2a0f07a1c1dcabdb2fd5e9f24bc36c" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "rustc_version", + "syn", +] + +[[package]] name = "event-listener" version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -414,6 +473,12 @@ dependencies = [ ] [[package]] +name = "futures-io" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" + +[[package]] name = "futures-sink" version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -436,6 +501,7 @@ dependencies = [ "futures-task", "pin-project-lite", "pin-utils", + "slab", ] [[package]] @@ -479,7 +545,7 @@ dependencies = [ [[package]] name = "hdt-api" -version = "0.1.3" +version = "0.1.4" dependencies = [ "addr", "anyhow", @@ -504,6 +570,8 @@ dependencies = [ "tower-http", "tracing-subscriber", "uuid", + "whois-rust", + "whoisthere", ] [[package]] @@ -651,6 +719,12 @@ dependencies = [ ] [[package]] +name = "ipnet" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" + +[[package]] name = "itertools" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -801,6 +875,15 @@ dependencies = [ ] [[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] name = "nom" version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -820,6 +903,17 @@ dependencies = [ ] [[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] name = "num-integer" version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -849,6 +943,15 @@ dependencies = [ ] [[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + +[[package]] name = "once_cell" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1037,6 +1140,16 @@ dependencies = [ ] [[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] name = "rand" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1087,6 +1200,23 @@ dependencies = [ ] [[package]] +name = "regex" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" + +[[package]] name = "remove_dir_all" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1096,6 +1226,15 @@ dependencies = [ ] [[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] name = "ryu" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1141,6 +1280,12 @@ dependencies = [ ] [[package]] +name = "semver" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1" + +[[package]] name = "serde" version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1224,6 +1369,15 @@ dependencies = [ ] [[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] name = "smallvec" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1429,6 +1583,16 @@ dependencies = [ ] [[package]] +name = "time" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217" +dependencies = [ + "libc", + "num_threads", +] + +[[package]] name = "tinyvec" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1618,6 +1782,51 @@ dependencies = [ ] [[package]] +name = "trust-dns-client" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6d9ba1c6079f6f9b4664e482db1700bd53d2ee77b1c9752c1d7a66c0c8bda99" +dependencies = [ + "cfg-if", + "data-encoding", + "futures-channel", + "futures-util", + "lazy_static", + "log", + "radix_trie", + "rand", + "thiserror", + "time 0.3.11", + "tokio", + "trust-dns-proto", +] + +[[package]] +name = "trust-dns-proto" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c31f240f59877c3d4bb3b3ea0ec5a6a0cff07323580ff8c7a605cd7d08b255d" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna", + "ipnet", + "lazy_static", + "log", + "rand", + "smallvec", + "thiserror", + "tinyvec", + "tokio", + "url", +] + +[[package]] name = "try-lock" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1685,6 +1894,41 @@ dependencies = [ ] [[package]] +name = "validators" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a608a36865089e56a81675b11129cfac8f410d1afcf52f07e1662af75634c691" +dependencies = [ + "idna", + "validators-derive", + "validators-options", +] + +[[package]] +name = "validators-derive" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a677309c30754937e1164d730b8b3fcf6a7fbc26fcfe141c52b06aeae4743b9" +dependencies = [ + "educe", + "enum-ordinalize", + "proc-macro2", + "quote", + "syn", + "validators-options", +] + +[[package]] +name = "validators-options" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad273b68c2810b6bc92a6df4008505849bf02d5723381156871e9729616d2523" +dependencies = [ + "educe", + "enum-ordinalize", +] + +[[package]] name = "valuable" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1799,6 +2043,29 @@ dependencies = [ ] [[package]] +name = "whois-rust" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf31968a3b3d30e115707b8857f0a4e19cc67235ad29f659c91dd4713213c5d6" +dependencies = [ + "once_cell", + "regex", + "serde_json", + "trust-dns-client", + "validators", +] + +[[package]] +name = "whoisthere" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea492e2aa1beb56ebcd94341685bb8641181c45ebd33548f3249b558ca59113" +dependencies = [ + "chrono", + "regex", +] + +[[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1,6 +1,6 @@ [package] name = "hdt-api" -version = "0.1.3" +version = "0.1.4" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -30,5 +30,7 @@ tower-http = { version = "0.3.3", features = ["cors", "trace"] } tracing-subscriber = "0.3.11" # uuid v1.0.0 is out, but it breaks sqlx... we just have to wait for sqlx to release v0.6 uuid = { version = "0.8.2", features = ["serde", "v4"] } +whois-rust = "1.5.0" +whoisthere = "0.1.3" [features] diff --git a/data/whois-servers.json b/data/whois-servers.json new file mode 100644 index 0000000..651e88d --- /dev/null +++ b/data/whois-servers.json @@ -0,0 +1,793 @@ +{ + "br.com": "whois.centralnic.net", + "cn.com": "whois.centralnic.net", + "de.com": "whois.centralnic.net", + "eu.com": "whois.centralnic.net", + "gb.com": "whois.centralnic.net", + "gb.net": "whois.centralnic.net", + "gr.com": "whois.centralnic.net", + "hu.com": "whois.centralnic.net", + "in.net": "whois.centralnic.net", + "jpn.com": "whois.centralnic.net", + "no.com": "whois.centralnic.net", + "qc.com": "whois.centralnic.net", + "ru.com": "whois.centralnic.net", + "sa.com": "whois.centralnic.net", + "se.com": "whois.centralnic.net", + "se.net": "whois.centralnic.net", + "uk.com": "whois.centralnic.net", + "uk.net": "whois.centralnic.net", + "us.com": "whois.centralnic.net", + "uy.com": "whois.centralnic.net", + "web.com": "whois.centralnic.net", + "za.com": "whois.centralnic.net", + "com": { + "host": "whois.verisign-grs.com", + "query": "DOMAIN $addr\r\n" + }, + + "za.net": "whois.za.net", + "net": { + "host": "whois.verisign-grs.com", + "query": "DOMAIN $addr\r\n" + }, + + "eu.org": "whois.eu.org", + "za.org": "whois.za.org", + "org": "whois.pir.org", + + "edu": "whois.educause.edu", + "gov": "whois.dotgov.gov", + "int": "whois.iana.org", + "mil": null, + + "e164.arpa": "whois.ripe.net", + "in-addr.arpa": null, + "arpa": "whois.iana.org", + + "aero": "whois.aero", + "asia": "whois.nic.asia", + "biz": "whois.biz", + "cat": "whois.cat", + "coop": "whois.nic.coop", + "info": "whois.afilias.net", + "jobs": "jobswhois.verisign-grs.com", + "mobi": "whois.dotmobiregistry.net", + "museum": "whois.museum", + "name": "whois.nic.name", + "post": "whois.dotpostregistry.net", + "pro": "whois.afilias.net", + "tel": "whois.nic.tel", + "travel": "whois.nic.travel", + "xxx": "whois.nic.xxx", + + "academy": "whois.nic.academy", + "accountants": "whois.nic.accountants", + "actor": "whois.nic.actor", + "agency": "whois.nic.agency", + "airforce": "whois.nic.airforce", + "apartments": "whois.nic.apartments", + "app": "whois.nic.google", + "archi": "whois.nic.archi", + "army": "whois.nic.army", + "associates": "whois.nic.associates", + "attorney": "whois.nic.attorney", + "auction": "whois.nic.auction", + "audio": "whois.nic.audio", + "autos": "whois.nic.autos", + "axa": "whois.nic.axa", + "band": "whois.nic.band", + "bar": "whois.nic.bar", + "bargains": "whois.nic.bargains", + "bayern": "whois.nic.bayern", + "beer": "whois.nic.beer", + "berlin": "whois.nic.berlin", + "best": "whois.nic.best", + "bid": "whois.nic.bid", + "bike": "whois.nic.bike", + "bingo": "whois.nic.bingo", + "black": "whois.nic.black", + "blackfriday": "whois.nic.blackfriday", + "blog": "whois.nic.blog", + "blue": "whois.nic.blue", + "boutique": "whois.nic.boutique", + "build": "whois.nic.build", + "builders": "whois.nic.builders", + "business": "whois.nic.business", + "buzz": "whois.nic.buzz", + "cab": "whois.nic.cab", + "cafe": "whois.nic.cafe", + "camera": "whois.nic.camera", + "camp": "whois.nic.camp", + "capital": "whois.nic.capital", + "cards": "whois.nic.cards", + "care": "whois.nic.care", + "career": "whois.nic.career", + "careers": "whois.nic.careers", + "cash": "whois.nic.cash", + "casino": "whois.nic.casino", + "catering": "whois.nic.catering", + "center": "whois.nic.center", + "ceo": "whois.nic.ceo", + "charity": "whois.nic.charity", + "chat": "whois.nic.chat", + "cheap": "whois.nic.cheap", + "christmas": "whois.nic.christmas", + "church": "whois.nic.church", + "citic": "whois.nic.citic", + "city": "whois.nic.city", + "claims": "whois.nic.claims", + "cleaning": "whois.nic.cleaning", + "clinic": "whois.nic.clinic", + "clothing": "whois.nic.clothing", + "cloud": "whois.nic.cloud", + "club": "whois.nic.club", + "coach": "whois.nic.coach", + "codes": "whois.nic.codes", + "coffee": "whois.nic.coffee", + "college": "whois.nic.college", + "cologne": "whois.nic.cologne", + "community": "whois.nic.community", + "company": "whois.nic.company", + "computer": "whois.nic.computer", + "condos": "whois.nic.condos", + "construction": "whois.nic.construction", + "consulting": "whois.nic.consulting", + "contractors": "whois.nic.contractors", + "cooking": "whois.nic.cooking", + "cool": "whois.nic.cool", + "country": "whois.nic.country", + "coupons": "whois.nic.coupons", + "credit": "whois.nic.credit", + "creditcard": "whois.nic.creditcard", + "cruises": "whois.nic.cruises", + "dance": "whois.nic.dance", + "dating": "whois.nic.dating", + "deals": "whois.nic.deals", + "degree": "whois.nic.degree", + "delivery": "whois.nic.delivery", + "democrat": "whois.nic.democrat", + "dental": "whois.nic.dental", + "dentist": "whois.nic.dentist", + "desi": "whois.nic.desi", + "dev": "whois.nic.google", + "diamonds": "whois.nic.diamonds", + "digital": "whois.donuts.co", + "direct": "whois.nic.direct", + "directory": "whois.nic.directory", + "discount": "whois.nic.discount", + "dnp": "whois.nic.dnp", + "doctor": "whois.nic.doctor", + "dog": "whois.nic.dog", + "domains": "whois.nic.domains", + "education": "whois.nic.education", + "email": "whois.nic.email", + "energy": "whois.nic.energy", + "engineer": "whois.nic.engineer", + "engineering": "whois.nic.engineering", + "enterprises": "whois.nic.enterprises", + "equipment": "whois.nic.equipment", + "estate": "whois.nic.estate", + "eus": "whois.nic.eus", + "events": "whois.nic.events", + "exchange": "whois.nic.exchange", + "expert": "whois.nic.expert", + "exposed": "whois.nic.exposed", + "express": "whois.nic.express", + "fail": "whois.nic.fail", + "family": "whois.nic.family", + "fan": "whois.nic.fan", + "farm": "whois.nic.farm", + "feedback": "whois.nic.feedback", + "finance": "whois.nic.finance", + "financial": "whois.nic.financial", + "fish": "whois.nic.fish", + "fishing": "whois.nic.fishing", + "fitness": "whois.nic.fitness", + "flights": "whois.nic.flights", + "florist": "whois.nic.florist", + "foo": "whois.nic.foo", + "football": "whois.nic.football", + "forsale": "whois.nic.forsale", + "foundation": "whois.nic.foundation", + "frogans": "whois.nic.frogans", + "fun": "whois.nic.fun", + "fund": "whois.nic.fund", + "furniture": "whois.nic.furniture", + "futbol": "whois.nic.futbol", + "fyi": "whois.nic.fyi", + "gal": "whois.nic.gal", + "gallery": "whois.nic.gallery", + "games": "whois.nic.games", + "gift": "whois.nic.gift", + "gifts": "whois.nic.gifts", + "gives": "whois.nic.gives", + "glass": "whois.nic.glass", + "global": "whois.nic.global", + "globo": "whois.nic.globo", + "gmbh": "whois.nic.gmbh", + "gmo": "whois.nic.gmo", + "gold": "whois.nic.gold", + "golf": "whois.nic.golf", + "gop": "whois.nic.gop", + "graphics": "whois.nic.graphics", + "gratis": "whois.nic.gratis", + "gripe": "whois.nic.gripe", + "group": "whois.nic.group", + "guide": "whois.nic.guide", + "guitars": "whois.nic.guitars", + "guru": "whois.nic.guru", + "haus": "whois.nic.haus", + "healthcare": "whois.nic.healthcare", + "hiphop": "whois.nic.hiphop", + "hockey": "whois.nic.hockey", + "holdings": "whois.nic.holdings", + "holiday": "whois.nic.holiday", + "homes": "whois.nic.homes", + "horse": "whois.nic.horse", + "hospital": "whois.nic.hospital", + "host": "whois.nic.host", + "house": "whois.nic.house", + "immo": "whois.nic.immo", + "immobilien": "whois.nic.immobilien", + "industries": "whois.nic.industries", + "ink": "whois.nic.ink", + "institute": "whois.nic.institute", + "insure": "whois.nic.insure", + "international": "whois.nic.international", + "investments": "whois.nic.investments", + "irish": "whois.nic.irish", + "jetzt": "whois.nic.jetzt", + "jewelry": "whois.nic.jewelry", + "juegos": "whois.nic.juegos", + "kaufen": "whois.nic.kaufen", + "kim": "whois.nic.kim", + "kitchen": "whois.nic.kitchen", + "kiwi": "whois.nic.kiwi", + "koeln": "whois.nic.koeln", + "kred": "whois.nic.kred", + "land": "whois.nic.land", + "lawyer": "whois.nic.lawyer", + "lease": "whois.nic.lease", + "legal": "whois.nic.legal", + "life": "whois.nic.life", + "lighting": "whois.nic.lighting", + "limited": "whois.nic.limited", + "limo": "whois.nic.limo", + "link": "whois.nic.link", + "live": "whois.nic.live", + "loans": "whois.nic.loans", + "london": "whois.nic.london", + "love": "whois.nic.love", + "ltd": "whois.nic.ltd", + "luxe": "whois.nic.luxe", + "luxury": "whois.nic.luxury", + "maison": "whois.nic.maison", + "management": "whois.nic.management", + "mango": "whois.nic.mango", + "market": "whois.nic.market", + "marketing": "whois.nic.marketing", + "mba": "whois.nic.mba", + "media": "whois.nic.media", + "meet": "whois.nic.meet", + "memorial": "whois.nic.memorial", + "menu": "whois.nic.menu", + "miami": "whois.nic.miami", + "moda": "whois.nic.moda", + "moe": "whois.nic.moe", + "monash": "whois.nic.monash", + "money": "whois.nic.money", + "mortgage": "whois.nic.mortgage", + "moscow": "whois.nic.moscow", + "motorcycles": "whois.nic.motorcycles", + "movie": "whois.nic.movie", + "nagoya": "whois.nic.nagoya", + "navy": "whois.nic.navy", + "network": "whois.nic.network", + "neustar": "whois.nic.neustar", + "news": "whois.nic.news", + "ninja": "whois.nic.ninja", + "nyc": "whois.nic.nyc", + "okinawa": "whois.nic.okinawa", + "one": "whois.nic.one", + "onl": "whois.nic.onl", + "online": "whois.centralnic.net", + "paris": "whois.nic.paris", + "partners": "whois.nic.partners", + "parts": "whois.nic.parts", + "photo": "whois.nic.photo", + "photography": "whois.nic.photography", + "photos": "whois.nic.photos", + "pics": "whois.nic.pics", + "pictures": "whois.nic.pictures", + "pink": "whois.nic.pink", + "pizza": "whois.nic.pizza", + "place": "whois.nic.place", + "plumbing": "whois.nic.plumbing", + "plus": "whois.nic.plus", + "press": "whois.nic.press", + "productions": "whois.nic.productions", + "properties": "whois.nic.properties", + "pub": "whois.nic.pub", + "qpon": "whois.nic.qpon", + "quebec": "whois.nic.quebec", + "recipes": "whois.nic.recipes", + "red": "whois.nic.red", + "rehab": "whois.nic.rehab", + "reise": "whois.nic.reise", + "reisen": "whois.nic.reisen", + "ren": "whois.nic.ren", + "rentals": "whois.nic.rentals", + "repair": "whois.nic.repair", + "report": "whois.nic.report", + "republican": "whois.nic.republican", + "rest": "whois.nic.rest", + "restaurant": "whois.nic.restaurant", + "reviews": "whois.nic.reviews", + "rich": "whois.nic.rich", + "rio": "whois.nic.rio", + "rip": "whois.nic.rip", + "rocks": "whois.nic.rocks", + "rodeo": "whois.nic.rodeo", + "ruhr": "whois.nic.ruhr", + "run": "whois.nic.run", + "ryukyu": "whois.nic.ryukyu", + "saarland": "whois.nic.saarland", + "sale": "whois.nic.sale", + "salon": "whois.nic.salon", + "sarl": "whois.nic.sarl", + "school": "whois.nic.school", + "schule": "whois.nic.schule", + "services": "whois.nic.services", + "sexy": "whois.nic.sexy", + "shiksha": "whois.nic.shiksha", + "shoes": "whois.nic.shoes", + "shopping": "whois.nic.shopping", + "show": "whois.nic.show", + "singles": "whois.nic.singles", + "site": "whois.nic.site", + "soccer": "whois.nic.soccer", + "social": "whois.nic.social", + "software": "whois.nic.software", + "sohu": "whois.nic.sohu", + "solar": "whois.nic.solar", + "solutions": "whois.nic.solutions", + "soy": "whois.nic.soy", + "space": "whois.nic.space", + "sport": "whois.nic.sport", + "store": "whois.nic.store", + "studio": "whois.nic.studio", + "style": "whois.nic.style", + "supplies": "whois.nic.supplies", + "supply": "whois.nic.supply", + "support": "whois.nic.support", + "surgery": "whois.nic.surgery", + "systems": "whois.nic.systems", + "tattoo": "whois.nic.tattoo", + "tax": "whois.nic.tax", + "taxi": "whois.nic.taxi", + "team": "whois.nic.team", + "tech": "whois.nic.tech", + "technology": "whois.nic.technology", + "tennis": "whois.nic.tennis", + "theater": "whois.nic.theater", + "tienda": "whois.nic.tienda", + "tips": "whois.nic.tips", + "tires": "whois.nic.tires", + "today": "whois.nic.today", + "tokyo": "whois.nic.tokyo", + "tools": "whois.nic.tools", + "top": "whois.nic.top", + "tours": "whois.nic.tours", + "town": "whois.nic.town", + "toys": "whois.nic.toys", + "trade": "whois.nic.trade", + "training": "whois.nic.training", + "university": "whois.nic.university", + "uno": "whois.nic.uno", + "vacations": "whois.nic.vacations", + "vegas": "whois.nic.vegas", + "ventures": "whois.nic.ventures", + "versicherung": "whois.nic.versicherung", + "vet": "whois.nic.vet", + "viajes": "whois.nic.viajes", + "video": "whois.nic.video", + "villas": "whois.nic.villas", + "vin": "whois.nic.vin", + "vip": "whois.nic.vip", + "vision": "whois.nic.vision", + "vodka": "whois.nic.vodka", + "vote": "whois.nic.vote", + "voting": "whois.nic.voting", + "voto": "whois.nic.voto", + "voyage": "whois.nic.voyage", + "wang": "whois.nic.wang", + "watch": "whois.nic.watch", + "webcam": "whois.nic.webcam", + "website": "whois.nic.website", + "wed": "whois.nic.wed", + "wien": "whois.nic.wien", + "wiki": "whois.nic.wiki", + "wine": "whois.nic.wine", + "works": "whois.nic.works", + "world": "whois.nic.world", + "wtc": "whois.nic.wtc", + "wtf": "whois.nic.wtf", + "xn--3bst00m": "whois.nic.xn--3bst00m", + "xn--3ds443g": "whois.nic.xn--3ds443g", + "xn--55qw42g": "whois.nic.xn--55qw42g", + "xn--55qx5d": "whois.nic.xn--55qx5d", + "xn--6frz82g": "whois.nic.xn--6frz82g", + "xn--6qq986b3xl": "whois.nic.xn--6qq986b3xl", + "xn--80adxhks": "whois.nic.xn--80adxhks", + "xn--80asehdb": "whois.nic.xn--80asehdb", + "xn--80aswg": "whois.nic.xn--80aswg", + "xn--c1avg": "whois.nic.xn--c1avg", + "xn--cg4bki": "whois.nic.xn--cg4bki", + "xn--czrs0t": "whois.nic.xn--czrs0t", + "xn--czr694b": "whois.nic.xn--czr694b", + "xn--czru2d": "whois.nic.xn--czru2d", + "xn--d1acj3b": "whois.nic.xn--d1acj3b", + "xn--fiq228c5hs": "whois.nic.xn--fiq228c5hs", + "xn--fiq64b": "whois.nic.xn--fiq64b", + "xn--i1b6b1a6a2e": "whois.nic.xn--i1b6b1a6a2e", + "xn--io0a7i": "whois.nic.xn--io0a7i", + "xn--mgbab2bd": "whois.nic.xn--mgbab2bd", + "xn--ngbc5azd": "whois.nic.xn--ngbc5azd", + "xn--nqv7f": "whois.nic.xn--nqv7f", + "xn--nqv7fs00ema": "whois.nic.xn--nqv7fs00ema", + "xn--q9jyb4c": "whois.nic.xn--q9jyb4c", + "xn--rhqv96g": "whois.nic.xn--rhqv96g", + "xn--ses554g": "whois.nic.xn--ses554g", + "xn--unup4y": "whois.nic.xn--unup4y", + "xn--vhquv": "whois.nic.xn--vhquv", + "xn--zfr164b": "whois.nic.xn--zfr164b", + "xyz": "whois.nic.xyz", + "yachts": "whois.nic.yachts", + "yokohama": "whois.nic.yokohama", + "zone": "whois.nic.zone", + + "ac": "whois.nic.ac", + "ad": null, + "ae": "whois.aeda.net.ae", + "af": "whois.nic.af", + "ag": "whois.nic.ag", + "ai": "whois.nic.ai", + "al": null, + "am": "whois.amnic.net", + "an": null, + "ao": null, + "aq": null, + "ar": null, + "as": "whois.nic.as", + "priv.at": "whois.nic.priv.at", + "at": "whois.nic.at", + "au": "whois.auda.org.au", + "aw": "whois.nic.aw", + "ax": "whois.ax", + "az": null, + "ba": null, + "bb": null, + "bd": null, + "be": "whois.dns.be", + "bf": null, + "bg": "whois.register.bg", + "bh": null, + "bi": "whois1.nic.bi", + "bj": "whois.nic.bj", + "bl": null, + "bm": "whois.afilias-srs.net", + "bn": "whois.bn", + "bo": "whois.nic.bo", + "bq": null, + "br": "whois.registro.br", + "bs": null, + "bt": null, + "bv": null, + "by": "whois.cctld.by", + "bw": "whois.nic.net.bw", + "bz": "whois.afilias-grs.info", + "co.ca": "whois.co.ca", + "ca": "whois.cira.ca", + "cc": "ccwhois.verisign-grs.com", + "cd": "whois.nic.cd", + "cf": "whois.dot.cf", + "cg": null, + "ch": "whois.nic.ch", + "ci": "whois.nic.ci", + "ck": null, + "cl": "whois.nic.cl", + "cm": "whois.netcom.cm", + "edu.cn": "whois.edu.cn", + "cn": "whois.cnnic.cn", + "uk.co": "whois.uk.co", + "co": "whois.nic.co", + "cr": "whois.nic.cr", + "cu": null, + "cv": null, + "cw": null, + "cx": "whois.nic.cx", + "cy": null, + "cz": "whois.nic.cz", + "de": { + "host": "whois.denic.de", + "query": "-T dn $addr\r\n", + "punycode": false + }, + "dj": null, + "dk": { + "host": "whois.dk-hostmaster.dk", + "query": "--charset=utf-8 --show-handles $addr\r\n" + }, + "dm": "whois.nic.dm", + "do": "whois.nic.do", + "dz": "whois.nic.dz", + "ec": "whois.nic.ec", + "ee": "whois.tld.ee", + "eg": null, + "eh": null, + "er": null, + "es": null, + "et": null, + "eu": "whois.eu", + "fi": "whois.fi", + "fj": "whois.usp.ac.fj", + "fk": null, + "fm": "whois.nic.fm", + "fo": "whois.nic.fo", + "fr": "whois.nic.fr", + "ga": "whois.dot.ga", + "gb": null, + "gd": "whois.nic.gd", + "ge": "whois.nic.ge", + "gf": "whois.mediaserv.net", + "gg": "whois.gg", + "gh": "whois.nic.gh", + "gi": "whois.afilias-grs.info", + "gl": "whois.nic.gl", + "gm": null, + "gn": null, + "gp": "whois.nic.gp", + "gq": "whois.dominio.gq", + "gr": null, + "gs": "whois.nic.gs", + "gt": null, + "gu": null, + "gw": null, + "gy": "whois.registry.gy", + "hk": "whois.hkirc.hk", + "hm": "whois.registry.hm", + "hn": "whois.nic.hn", + "hr": "whois.dns.hr", + "ht": "whois.nic.ht", + "hu": "whois.nic.hu", + "id": "whois.pandi.or.id", + "ie": "whois.domainregistry.ie", + "il": "whois.isoc.org.il", + "im": "whois.nic.im", + "in": "whois.registry.in", + "io": "whois.nic.io", + "iq": "whois.cmc.iq", + "ir": "whois.nic.ir", + "is": "whois.isnic.is", + "it": "whois.nic.it", + "je": "whois.je", + "jm": null, + "jo": null, + "jp": { + "host": "whois.jprs.jp", + "query": "$addr/e\r\n" + }, + "ke": "whois.kenic.or.ke", + "kg": "whois.domain.kg", + "kh": null, + "ki": "whois.nic.ki", + "km": null, + "kn": "whois.nic.kn", + "kp": null, + "kr": "whois.kr", + "kw": null, + "ky": "whois.kyregistry.ky", + "kz": "whois.nic.kz", + "la": "whois.nic.la", + "lb": null, + "lc": "whois.afilias-grs.info", + "li": "whois.nic.li", + "lk": "whois.nic.lk", + "lr": null, + "ls": "whois.nic.ls", + "lt": "whois.domreg.lt", + "lu": "whois.dns.lu", + "lv": "whois.nic.lv", + "ly": "whois.nic.ly", + "ma": "whois.iam.net.ma", + "mc": null, + "md": "whois.nic.md", + "me": "whois.nic.me", + "mf": null, + "mg": "whois.nic.mg", + "mh": null, + "mk": "whois.marnet.mk", + "ml": "whois.dot.ml", + "mm": null, + "mn": "whois.nic.mn", + "mo": null, + "mp": null, + "mq": "whois.mediaserv.net", + "mr": "whois.nic.mr", + "ms": "whois.nic.ms", + "mt": null, + "mu": "whois.nic.mu", + "mv": null, + "mw": "whois.nic.mw", + "mx": "whois.mx", + "my": "whois.domainregistry.my", + "mz": "whois.nic.mz", + "na": "whois.na-nic.com.na", + "nc": "whois.nc", + "ne": null, + "nf": "whois.nic.nf", + "ng": "whois.nic.net.ng", + "ni": null, + "nl": "whois.domain-registry.nl", + "no": { + "host": "whois.norid.no", + "query": "-c utf-8 $addr\r\n" + }, + "np": null, + "nr": null, + "nu": "whois.iis.nu", + "nz": "whois.srs.net.nz", + "om": "whois.registry.om", + "pa": null, + "pe": "kero.yachay.pe", + "pf": "whois.registry.pf", + "pg": null, + "ph": null, + "pk": null, + "co.pl": "whois.co.pl", + "pl": "whois.dns.pl", + "pm": "whois.nic.pm", + "pn": null, + "pr": "whois.nic.pr", + "ps": "whois.pnina.ps", + "pt": "whois.dns.pt", + "pw": "whois.nic.pw", + "py": null, + "qa": "whois.registry.qa", + "re": "whois.nic.re", + "ro": "whois.rotld.ro", + "rs": "whois.rnids.rs", + "edu.ru": "whois.informika.ru", + "ru": "whois.tcinet.ru", + "rw": "whois.ricta.org.rw", + "sa": "whois.nic.net.sa", + "sb": "whois.nic.sb", + "sc": "whois.afilias-grs.info", + "sd": null, + "se": "whois.iis.se", + "sg": "whois.sgnic.sg", + "sh": "whois.nic.sh", + "si": "whois.arnes.si", + "sj": null, + "sk": "whois.sk-nic.sk", + "sl": "whois.nic.sl", + "sm": "whois.nic.sm", + "sn": "whois.nic.sn", + "so": "whois.nic.so", + "sr": null, + "ss": "whois.nic.ss", + "st": "whois.nic.st", + "su": "whois.tcinet.ru", + "sv": null, + "sx": "whois.sx", + "sy": "whois.tld.sy", + "sz": null, + "tc": "whois.nic.tc", + "td": "whois.nic.td", + "tf": "whois.nic.tf", + "tg": "whois.nic.tg", + "th": "whois.thnic.co.th", + "tj": null, + "tk": "whois.dot.tk", + "tl": "whois.nic.tl", + "tm": "whois.nic.tm", + "tn": "whois.ati.tn", + "to": "whois.tonic.to", + "tp": null, + "tr": "whois.nic.tr", + "tt": null, + "tv": "tvwhois.verisign-grs.com", + "tw": "whois.twnic.net.tw", + "tz": "whois.tznic.or.tz", + "biz.ua": "whois.biz.ua", + "co.ua": "whois.co.ua", + "pp.ua": "whois.pp.ua", + "ua": "whois.ua", + "ug": "whois.co.ug", + "ac.uk": "whois.ja.net", + "bl.uk": null, + "british-library.uk": null, + "gov.uk": "whois.ja.net", + "icnet.uk": null, + "jet.uk": null, + "mod.uk": null, + "nhs.uk": null, + "nls.uk": null, + "parliament.uk": null, + "police.uk": null, + "uk": "whois.nic.uk", + "um": null, + "fed.us": "whois.nic.gov", + "us": "whois.nic.us", + "com.uy": null, + "uy": "whois.nic.org.uy", + "uz": "whois.cctld.uz", + "va": null, + "vc": "whois.afilias-grs.info", + "ve": "whois.nic.ve", + "vg": "whois.nic.vg", + "vi": null, + "vn": null, + "vu": "vunic.vu", + "wf": "whois.nic.wf", + "ws": "whois.website.ws", + "ye": null, + "yt": "whois.nic.yt", + "ac.za": "whois.ac.za", + "alt.za": "whois.alt.za", + "co.za": "whois.registry.net.za", + "gov.za": "whois.gov.za", + "net.za": "whois.net.za", + "org.za": null, + "web.za": "whois.web.za", + "za": null, + "zm": "whois.nic.zm", + "zw": null, + + "xn--3e0b707e": "whois.kr", + "xn--45brj9c": "whois.inregistry.net", + "xn--80ao21a": "whois.nic.kz", + "xn--90a3ac": "whois.rnids.rs", + "xn--clchc0ea0b2g2a9gcd": "whois.sgnic.sg", + "xn--fiqs8s": "cwhois.cnnic.cn", + "xn--fiqz9s": "cwhois.cnnic.cn", + "xn--fpcrj9c3d": "whois.inregistry.net", + "xn--fzc2c9e2c": "whois.nic.lk", + "xn--gecrj9c": "whois.inregistry.net", + "xn--h2brj9c": "whois.inregistry.net", + "xn--j1amh": "whois.dotukr.com", + "xn--j6w193g": "whois.hkirc.hk", + "xn--kprw13d": "whois.twnic.net.tw", + "xn--kpry57d": "whois.twnic.net.tw", + "xn--l1acc": "whois.nic.mn", + "xn--lgbbat1ad8j": "whois.nic.dz", + "xn--mgb9awbf": "whois.registry.om", + "xn--mgba3a4f16a": "whois.nic.ir", + "xn--mgbaam7a8h": "whois.aeda.net.ae", + "xn--mgbayh7gpa": null, + "xn--mgbbh1a71e": "whois.inregistry.net", + "xn--mgbc0a9azcg": null, + "xn--mgberp4a5d4ar": "whois.nic.net.sa", + "xn--mgbx4cd0ab": "whois.domainregistry.my", + "xn--o3cw4h": "whois.thnic.co.th", + "xn--ogbpf8fl": "whois.tld.sy", + "xn--p1ai": "whois.tcinet.ru", + "xn--pgbs0dh": null, + "xn--s9brj9c": "whois.inregistry.net", + "xn--wgbh1c": "whois.dotmasr.eg", + "xn--wgbl6a": "whois.registry.qa", + "xn--xkc2al3hye2a": "whois.nic.lk", + "xn--xkc2dl3a5ee0h": "whois.inregistry.net", + "xn--yfro4i67o": "whois.sgnic.sg", + "xn--ygbi2ammx": "whois.pnina.ps", + + "": "whois.ripe.net", + + "_": { + "ip": { + "host": "whois.arin.net", + "query": "n + $addr\r\n" + } + } +} diff --git a/src/main.rs b/src/main.rs index 3190db3..e7e2489 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,6 +51,13 @@ async fn main() { ); info!("Postgres pool initialized"); + // Create our WhoIs client + let whois_client = whois_rust::WhoIs::from_string(include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/data/whois-servers.json" + ))) + .unwrap(); + let app = Router::new() .nest( "/api", @@ -87,7 +94,8 @@ async fn main() { ), ) .layer(ServiceBuilder::new().layer(TraceLayer::new_for_http())) - .layer(Extension(pg_pool)); + .layer(Extension(pg_pool)) + .layer(Extension(whois_client)); let addr = SocketAddr::from(([0, 0, 0, 0], 8000)); info!("Binding to {addr}"); diff --git a/src/routes/v1/zones.rs b/src/routes/v1/zones.rs index 5336d28..ddbeb19 100644 --- a/src/routes/v1/zones.rs +++ b/src/routes/v1/zones.rs @@ -11,6 +11,7 @@ use serde::Deserialize; use serde_json::json; use sqlx::{Error, Pool, Postgres}; use std::sync::Arc; +use whois_rust::{WhoIs, WhoIsLookupOptions}; lazy_static! { static ref NAMESERVERS: Vec<String> = Vec::from([ @@ -66,6 +67,7 @@ pub async fn create_zone( Path(zone_id): Path<String>, Jwt(user): Jwt, Extension(pool): Extension<Arc<Pool<Postgres>>>, + Extension(whois_client): Extension<WhoIs>, ) -> impl IntoResponse { let domain = ensure_trailing_dot(&zone_id); let domain = addr::parse_domain_name(&domain).unwrap(); @@ -87,6 +89,44 @@ pub async fn create_zone( ); } + let lookup = match WhoIsLookupOptions::from_string(&*zone_id.trim_end_matches('.')) { + Ok(lookup) => lookup, + Err(e) => { + return ( + StatusCode::BAD_REQUEST, + Json(json!({ + "error": "Invalid domain", + "message": format!("Could not parse WhoIs Lookup ({})", e) + })), + ) + } + }; + let whois_res = match whois_client.lookup(lookup) { + Ok(res) => { + res + } + Err(e) => { + return ( + StatusCode::BAD_REQUEST, + Json(json!({ + "error": "Invalid domain", + "message": format!("{}", e) + })), + ) + } + }; + + let whois_info = whoisthere::parse_info(&*zone_id.trim_end_matches('.'), &whois_res); + if !whois_info.is_registered || whois_info.is_under_grace_period { + return ( + StatusCode::BAD_REQUEST, + Json(json!({ + "error": "Invalid domain", + "message": "Domain is not registered or expired" + })), + ) + } + let zone = db::zones::create_zone(&pool, &zone_id, user.sub).await; match zone { Ok(zone) => (StatusCode::OK, Json(json!(zone))), |