fixed a bug on new project creation where the config file path wasn't
being passed correctly. Also started the groundwork for adding more of my rust based tooling to tetanus.
This commit is contained in:
Generated
+583
-15
@@ -2,6 +2,12 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 4
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "adler2"
|
||||||
|
version = "2.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aead"
|
name = "aead"
|
||||||
version = "0.6.1"
|
version = "0.6.1"
|
||||||
@@ -329,6 +335,20 @@ version = "1.1.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "auto_generate_cdp"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "359220d0b9360b79d17d648d0a3ba1e792ec36bdbc227c8fd0351df3a0415704"
|
||||||
|
dependencies = [
|
||||||
|
"convert_case 0.8.0",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"ureq",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.5.1"
|
version = "1.5.1"
|
||||||
@@ -364,6 +384,12 @@ version = "0.22.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.23.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bit-set"
|
name = "bit-set"
|
||||||
version = "0.5.3"
|
version = "0.5.3"
|
||||||
@@ -670,6 +696,15 @@ dependencies = [
|
|||||||
"tiny-keccak",
|
"tiny-keccak",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "convert_case"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "convert_case"
|
name = "convert_case"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
@@ -719,6 +754,15 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc32fast"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8498c871161e1742aaa9d52551b2d6ebdd4c3d45a3be423e3728f33b955be550"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-deque"
|
name = "crossbeam-deque"
|
||||||
version = "0.8.6"
|
version = "0.8.6"
|
||||||
@@ -826,14 +870,38 @@ dependencies = [
|
|||||||
"cmov",
|
"cmov",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling"
|
||||||
|
version = "0.20.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core 0.20.11",
|
||||||
|
"darling_macro 0.20.11",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling"
|
name = "darling"
|
||||||
version = "0.23.0"
|
version = "0.23.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d"
|
checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling_core",
|
"darling_core 0.23.0",
|
||||||
"darling_macro",
|
"darling_macro 0.23.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_core"
|
||||||
|
version = "0.20.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e"
|
||||||
|
dependencies = [
|
||||||
|
"fnv",
|
||||||
|
"ident_case",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"strsim",
|
||||||
|
"syn 2.0.117",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -849,13 +917,24 @@ dependencies = [
|
|||||||
"syn 2.0.117",
|
"syn 2.0.117",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_macro"
|
||||||
|
version = "0.20.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core 0.20.11",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.117",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling_macro"
|
name = "darling_macro"
|
||||||
version = "0.23.0"
|
version = "0.23.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d"
|
checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling_core",
|
"darling_core 0.23.0",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.117",
|
"syn 2.0.117",
|
||||||
]
|
]
|
||||||
@@ -895,6 +974,37 @@ dependencies = [
|
|||||||
"powerfmt",
|
"powerfmt",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_builder"
|
||||||
|
version = "0.20.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947"
|
||||||
|
dependencies = [
|
||||||
|
"derive_builder_macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_builder_core"
|
||||||
|
version = "0.20.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8"
|
||||||
|
dependencies = [
|
||||||
|
"darling 0.20.11",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.117",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_builder_macro"
|
||||||
|
version = "0.20.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c"
|
||||||
|
dependencies = [
|
||||||
|
"derive_builder_core",
|
||||||
|
"syn 2.0.117",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derive_more"
|
name = "derive_more"
|
||||||
version = "2.1.1"
|
version = "2.1.1"
|
||||||
@@ -910,7 +1020,7 @@ version = "2.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb"
|
checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"convert_case",
|
"convert_case 0.10.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rustc_version",
|
"rustc_version",
|
||||||
@@ -1088,6 +1198,16 @@ version = "0.4.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
|
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flate2"
|
||||||
|
version = "1.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
|
||||||
|
dependencies = [
|
||||||
|
"crc32fast",
|
||||||
|
"miniz_oxide",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
@@ -1100,6 +1220,15 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "form_urlencoded"
|
||||||
|
version = "1.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
|
||||||
|
dependencies = [
|
||||||
|
"percent-encoding",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fs_extra"
|
name = "fs_extra"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
@@ -1232,6 +1361,29 @@ version = "0.17.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "headless_chrome"
|
||||||
|
version = "1.0.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5754ca220578ad74a5d5174c8ca2ff956fd3b94025f870844de1e910b47dfee5"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"auto_generate_cdp",
|
||||||
|
"base64 0.22.1",
|
||||||
|
"derive_builder",
|
||||||
|
"log",
|
||||||
|
"rand 0.10.2",
|
||||||
|
"regex",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"tempfile",
|
||||||
|
"thiserror 2.0.18",
|
||||||
|
"tungstenite",
|
||||||
|
"url",
|
||||||
|
"which",
|
||||||
|
"winreg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@@ -1268,6 +1420,22 @@ dependencies = [
|
|||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"itoa",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "httparse"
|
||||||
|
version = "1.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hybrid-array"
|
name = "hybrid-array"
|
||||||
version = "0.4.14"
|
version = "0.4.14"
|
||||||
@@ -1277,12 +1445,116 @@ dependencies = [
|
|||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_collections"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"potential_utf",
|
||||||
|
"utf8_iter",
|
||||||
|
"yoke",
|
||||||
|
"zerofrom",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_locale_core"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"litemap",
|
||||||
|
"tinystr",
|
||||||
|
"writeable",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_normalizer"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f"
|
||||||
|
dependencies = [
|
||||||
|
"icu_collections",
|
||||||
|
"icu_normalizer_data",
|
||||||
|
"icu_properties",
|
||||||
|
"icu_provider",
|
||||||
|
"smallvec",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_normalizer_data"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_properties"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"icu_collections",
|
||||||
|
"icu_locale_core",
|
||||||
|
"icu_properties_data",
|
||||||
|
"icu_provider",
|
||||||
|
"zerotrie",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_properties_data"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_provider"
|
||||||
|
version = "2.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"icu_locale_core",
|
||||||
|
"writeable",
|
||||||
|
"yoke",
|
||||||
|
"zerofrom",
|
||||||
|
"zerotrie",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ident_case"
|
name = "ident_case"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de"
|
||||||
|
dependencies = [
|
||||||
|
"idna_adapter",
|
||||||
|
"smallvec",
|
||||||
|
"utf8_iter",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna_adapter"
|
||||||
|
version = "1.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714"
|
||||||
|
dependencies = [
|
||||||
|
"icu_normalizer",
|
||||||
|
"icu_properties",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.14.0"
|
version = "2.14.0"
|
||||||
@@ -1327,7 +1599,7 @@ version = "0.3.12"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5eb2d60ef19920a3a9193c3e371f726ec1dafc045dac788d0fb3704272458971"
|
checksum = "5eb2d60ef19920a3a9193c3e371f726ec1dafc045dac788d0fb3704272458971"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling",
|
"darling 0.23.0",
|
||||||
"indoc",
|
"indoc",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -1448,6 +1720,12 @@ version = "0.12.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
|
checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "litemap"
|
||||||
|
version = "0.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "litrs"
|
name = "litrs"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@@ -1465,9 +1743,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.31"
|
version = "0.4.34"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "113b30b4cd05f7c06868fdb2854f66a7b9fece9a48425351cd532e810d74024f"
|
checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lru"
|
name = "lru"
|
||||||
@@ -1524,6 +1802,16 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miniz_oxide"
|
||||||
|
version = "0.8.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
|
||||||
|
dependencies = [
|
||||||
|
"adler2",
|
||||||
|
"simd-adler32",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
@@ -1839,10 +2127,16 @@ version = "3.0.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be"
|
checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64 0.22.1",
|
||||||
"serde_core",
|
"serde_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "percent-encoding"
|
||||||
|
version = "2.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pest"
|
name = "pest"
|
||||||
version = "2.8.6"
|
version = "2.8.6"
|
||||||
@@ -1992,12 +2286,30 @@ version = "1.13.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
|
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "potential_utf"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661"
|
||||||
|
dependencies = [
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "powerfmt"
|
name = "powerfmt"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||||
|
dependencies = [
|
||||||
|
"zerocopy",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-crate"
|
name = "proc-macro-crate"
|
||||||
version = "3.5.0"
|
version = "3.5.0"
|
||||||
@@ -2046,6 +2358,16 @@ dependencies = [
|
|||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.9.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41"
|
||||||
|
dependencies = [
|
||||||
|
"rand_chacha",
|
||||||
|
"rand_core 0.9.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.10.2"
|
version = "0.10.2"
|
||||||
@@ -2057,12 +2379,31 @@ dependencies = [
|
|||||||
"rand_core 0.10.1",
|
"rand_core 0.10.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core 0.9.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_core"
|
name = "rand_core"
|
||||||
version = "0.6.4"
|
version = "0.6.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.9.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.3.4",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_core"
|
name = "rand_core"
|
||||||
version = "0.10.1"
|
version = "0.10.1"
|
||||||
@@ -2199,9 +2540,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.12.3"
|
version = "1.13.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
|
checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
@@ -2211,9 +2552,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-automata"
|
name = "regex-automata"
|
||||||
version = "0.4.14"
|
version = "0.4.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
|
checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
@@ -2222,9 +2563,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.8.10"
|
version = "0.8.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
|
checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rhai"
|
name = "rhai"
|
||||||
@@ -2317,6 +2658,7 @@ dependencies = [
|
|||||||
"aws-lc-rs",
|
"aws-lc-rs",
|
||||||
"log",
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"ring",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"rustls-webpki",
|
"rustls-webpki",
|
||||||
"subtle",
|
"subtle",
|
||||||
@@ -2482,6 +2824,17 @@ dependencies = [
|
|||||||
"syn 2.0.117",
|
"syn 2.0.117",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha1"
|
||||||
|
version = "0.10.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures 0.2.17",
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha2"
|
name = "sha2"
|
||||||
version = "0.10.9"
|
version = "0.10.9"
|
||||||
@@ -2530,6 +2883,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "simd-adler32"
|
||||||
|
version = "0.3.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "siphasher"
|
name = "siphasher"
|
||||||
version = "1.0.3"
|
version = "1.0.3"
|
||||||
@@ -2579,12 +2938,29 @@ dependencies = [
|
|||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "socks"
|
||||||
|
version = "0.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0c3dbbd9ae980613c6dd8e28a9407b50509d3803b57624d5dfe8315218cd58b"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spin"
|
name = "spin"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stable_deref_trait"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "static_assertions"
|
name = "static_assertions"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@@ -2724,7 +3100,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "4676b37242ccbd1aabf56edb093a4827dc49086c0ffd764a5705899e0f35f8f7"
|
checksum = "4676b37242ccbd1aabf56edb093a4827dc49086c0ffd764a5705899e0f35f8f7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64 0.22.1",
|
||||||
"bitflags 2.12.1",
|
"bitflags 2.12.1",
|
||||||
"fancy-regex",
|
"fancy-regex",
|
||||||
"filedescriptor",
|
"filedescriptor",
|
||||||
@@ -2769,6 +3145,7 @@ dependencies = [
|
|||||||
"clipboard",
|
"clipboard",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"fs_extra",
|
"fs_extra",
|
||||||
|
"headless_chrome",
|
||||||
"ipnet",
|
"ipnet",
|
||||||
"keyring",
|
"keyring",
|
||||||
"rand 0.10.2",
|
"rand 0.10.2",
|
||||||
@@ -2888,6 +3265,16 @@ dependencies = [
|
|||||||
"crunchy",
|
"crunchy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinystr"
|
||||||
|
version = "0.8.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.52.3"
|
version = "1.52.3"
|
||||||
@@ -2987,6 +3374,22 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tungstenite"
|
||||||
|
version = "0.29.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c01152af293afb9c7c2a57e4b559c5620b421f6d133261c60dd2d0cdb38e6b8"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"data-encoding",
|
||||||
|
"http",
|
||||||
|
"httparse",
|
||||||
|
"log",
|
||||||
|
"rand 0.9.5",
|
||||||
|
"sha1",
|
||||||
|
"thiserror 2.0.18",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.20.1"
|
version = "1.20.1"
|
||||||
@@ -3061,6 +3464,60 @@ version = "0.9.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ureq"
|
||||||
|
version = "3.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "972d7902c8735f2695410b8aed7df6ed12a47394aa1c8d7af49f0497b731a94d"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.23.1",
|
||||||
|
"flate2",
|
||||||
|
"log",
|
||||||
|
"percent-encoding",
|
||||||
|
"rustls",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"socks",
|
||||||
|
"ureq-proto",
|
||||||
|
"utf8-zero",
|
||||||
|
"webpki-roots",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ureq-proto"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da5f78b09e6941e1a0f2e30e695e4b120377b54d5e0aec11b594bb57b3971613"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.23.1",
|
||||||
|
"http",
|
||||||
|
"httparse",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "url"
|
||||||
|
version = "2.5.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed"
|
||||||
|
dependencies = [
|
||||||
|
"form_urlencoded",
|
||||||
|
"idna",
|
||||||
|
"percent-encoding",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8-zero"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8_iter"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf8parse"
|
name = "utf8parse"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
@@ -3175,6 +3632,15 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki-roots"
|
||||||
|
version = "1.0.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a"
|
||||||
|
dependencies = [
|
||||||
|
"rustls-pki-types",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wezterm-bidi"
|
name = "wezterm-bidi"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
@@ -3247,6 +3713,15 @@ dependencies = [
|
|||||||
"wezterm-dynamic",
|
"wezterm-dynamic",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "which"
|
||||||
|
version = "8.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bae2f2b2b816647a1cab1acc91f5bd20812d53cb344382635ec2181940c8034f"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
@@ -3492,12 +3967,28 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winreg"
|
||||||
|
version = "0.56.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7d6f32a0ff4a9f6f01231eb2059cc85479330739333e0e58cadf03b6af2cca10"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wit-bindgen"
|
name = "wit-bindgen"
|
||||||
version = "0.57.1"
|
version = "0.57.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
|
checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "writeable"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "x11-clipboard"
|
name = "x11-clipboard"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
@@ -3545,6 +4036,29 @@ dependencies = [
|
|||||||
"time",
|
"time",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yoke"
|
||||||
|
version = "0.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5"
|
||||||
|
dependencies = [
|
||||||
|
"stable_deref_trait",
|
||||||
|
"yoke-derive",
|
||||||
|
"zerofrom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yoke-derive"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.117",
|
||||||
|
"synstructure",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zbus"
|
name = "zbus"
|
||||||
version = "5.16.0"
|
version = "5.16.0"
|
||||||
@@ -3637,12 +4151,66 @@ dependencies = [
|
|||||||
"syn 2.0.117",
|
"syn 2.0.117",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerofrom"
|
||||||
|
version = "0.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272"
|
||||||
|
dependencies = [
|
||||||
|
"zerofrom-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerofrom-derive"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.117",
|
||||||
|
"synstructure",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zeroize"
|
name = "zeroize"
|
||||||
version = "1.9.0"
|
version = "1.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
|
checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerotrie"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"yoke",
|
||||||
|
"zerofrom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerovec"
|
||||||
|
version = "0.11.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8"
|
||||||
|
dependencies = [
|
||||||
|
"yoke",
|
||||||
|
"zerofrom",
|
||||||
|
"zerovec-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerovec-derive"
|
||||||
|
version = "0.11.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zmij"
|
name = "zmij"
|
||||||
version = "1.0.21"
|
version = "1.0.21"
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ clap = { version = "4.6.1", features = ["derive"] }
|
|||||||
clipboard = "0.5.0"
|
clipboard = "0.5.0"
|
||||||
crossterm = "0.29.0"
|
crossterm = "0.29.0"
|
||||||
fs_extra = "1.3.0"
|
fs_extra = "1.3.0"
|
||||||
|
headless_chrome = "1.0.22"
|
||||||
ipnet = "2.12.0"
|
ipnet = "2.12.0"
|
||||||
keyring = "4.1.6"
|
keyring = "4.1.6"
|
||||||
rand = "0.10.2"
|
rand = "0.10.2"
|
||||||
|
|||||||
+55
-3
@@ -49,6 +49,7 @@ pub fn startup(
|
|||||||
let response = get_user_input("which config would you like to load?")?;
|
let response = get_user_input("which config would you like to load?")?;
|
||||||
if let Some(path) = selections.get(&response) {
|
if let Some(path) = selections.get(&response) {
|
||||||
app.load_config(PathBuf::from(path), true)?;
|
app.load_config(PathBuf::from(path), true)?;
|
||||||
|
println!("entering tui...");
|
||||||
run_tui(app, rx, handles.clone())?;
|
run_tui(app, rx, handles.clone())?;
|
||||||
} else {
|
} else {
|
||||||
eprintln!("error invalid selection! exiting...");
|
eprintln!("error invalid selection! exiting...");
|
||||||
@@ -56,11 +57,13 @@ pub fn startup(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
app.load_config(state.config_file.clone(), true)?;
|
app.load_config(state.config_file.clone(), true)?;
|
||||||
|
println!("entering tui...");
|
||||||
run_tui(app, rx, handles.clone())?;
|
run_tui(app, rx, handles.clone())?;
|
||||||
}
|
}
|
||||||
if nested {
|
if nested {
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
state.main_tx = tx;
|
state.main_tx = tx;
|
||||||
|
println!("returning to prevous tui...");
|
||||||
run_tui(state, rx, handles.clone())?;
|
run_tui(state, rx, handles.clone())?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -475,6 +478,35 @@ pub fn run_tui(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
"CMD" => {
|
"CMD" => {
|
||||||
|
if let Some((cmd, data)) =
|
||||||
|
data.split_once("|")
|
||||||
|
{
|
||||||
|
match cmd.trim() {
|
||||||
|
"SET_NAME" => {
|
||||||
|
locked_server
|
||||||
|
.name = data
|
||||||
|
.trim()
|
||||||
|
.to_string();
|
||||||
|
}
|
||||||
|
"LIST_PROJECTS" => {
|
||||||
|
let _ = ToolMessage::Input((locked_server.client_id.clone(), "list_projects".to_string()));
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let msg = format!(
|
||||||
|
"MSG FROM: {}",
|
||||||
|
data.trim()
|
||||||
|
);
|
||||||
|
let _ = tx_clone.send(
|
||||||
|
ToolMessage::Output((
|
||||||
|
locked_server
|
||||||
|
.client_id
|
||||||
|
.clone(),
|
||||||
|
msg,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if data.contains("SET_NAME") {
|
if data.contains("SET_NAME") {
|
||||||
if let Some((_, name)) =
|
if let Some((_, name)) =
|
||||||
data.split_once("|")
|
data.split_once("|")
|
||||||
@@ -485,7 +517,7 @@ pub fn run_tui(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let _ = tx_clone.send(
|
let _ = tx_clone.send(
|
||||||
ToolMessage::Input((
|
ToolMessage::Output((
|
||||||
locked_server
|
locked_server
|
||||||
.client_id
|
.client_id
|
||||||
.clone(),
|
.clone(),
|
||||||
@@ -680,18 +712,38 @@ pub fn run_tui(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if args == "" {
|
if args == "" {
|
||||||
let _ = state.execute_command(command, None, 0);
|
match state.execute_command(command, None, 0) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => {
|
||||||
|
let _ = state.main_tx.send(
|
||||||
|
ToolMessage::Output((
|
||||||
|
0,
|
||||||
|
e.to_string(),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let _ = state.execute_command(
|
match state.execute_command(
|
||||||
command,
|
command,
|
||||||
Some(args.to_string()),
|
Some(args.to_string()),
|
||||||
0,
|
0,
|
||||||
|
) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => {
|
||||||
|
let _ = state.main_tx.send(
|
||||||
|
ToolMessage::Output((
|
||||||
|
0,
|
||||||
|
e.to_string(),
|
||||||
|
)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
state.curent_intput.clear();
|
state.curent_intput.clear();
|
||||||
}
|
}
|
||||||
history_index = state.history.len();
|
history_index = state.history.len();
|
||||||
|
|||||||
+642
-94
@@ -14,13 +14,17 @@ use std::io::{self, BufRead, BufReader, Read, Write};
|
|||||||
use std::net::IpAddr;
|
use std::net::IpAddr;
|
||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::{Command, CommandArgs, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
use std::sync::mpsc::Receiver;
|
use std::sync::mpsc::Receiver;
|
||||||
use std::sync::{Arc, Mutex, mpsc::Sender, mpsc::channel};
|
use std::sync::{Arc, Mutex, mpsc::Sender, mpsc::channel};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::time::{self, Instant};
|
use std::time::{self, Instant};
|
||||||
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
|
use crate::rust_tools::rustwitness;
|
||||||
|
|
||||||
pub mod funcs;
|
pub mod funcs;
|
||||||
|
pub mod rust_tools;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
pub mod victim;
|
pub mod victim;
|
||||||
|
|
||||||
@@ -242,6 +246,10 @@ impl AppState {
|
|||||||
.to_string(),
|
.to_string(),
|
||||||
);
|
);
|
||||||
self.help.push("parse_scope\nparse the projects general.md notes file for the scope copied from the workbook\n".to_string());
|
self.help.push("parse_scope\nparse the projects general.md notes file for the scope copied from the workbook\n".to_string());
|
||||||
|
self.help.push("parse_portscan | pps\nParse a services.tsv file exported from cobalt stirke in your current project's files directory".to_string());
|
||||||
|
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("exit\nquit the tool\n".to_string());
|
self.help.push("exit\nquit the tool\n".to_string());
|
||||||
self.initialize_modules();
|
self.initialize_modules();
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@@ -392,6 +400,10 @@ impl AppState {
|
|||||||
} else {
|
} else {
|
||||||
out_vec.push(format!("status: upcoming"));
|
out_vec.push(format!("status: upcoming"));
|
||||||
}
|
}
|
||||||
|
out_vec.push(format!(
|
||||||
|
"Num hosts: {}",
|
||||||
|
&self.projects[self.selected_project].hosts.iter().count()
|
||||||
|
));
|
||||||
for line in out_vec {
|
for line in out_vec {
|
||||||
let _ = self.main_tx.send(ToolMessage::Output((rid, line)));
|
let _ = self.main_tx.send(ToolMessage::Output((rid, line)));
|
||||||
}
|
}
|
||||||
@@ -438,7 +450,7 @@ impl AppState {
|
|||||||
let project = self.projects[self.selected_project].clone();
|
let project = self.projects[self.selected_project].clone();
|
||||||
let mut config_file = project.config_folder.clone();
|
let mut config_file = project.config_folder.clone();
|
||||||
config_file.pop();
|
config_file.pop();
|
||||||
if let Err(e) = remove_dir_all(&project.config_folder) {
|
if let Err(e) = remove_dir_all(config_file) {
|
||||||
let _ = self.main_tx.send(ToolMessage::Output((
|
let _ = self.main_tx.send(ToolMessage::Output((
|
||||||
rid,
|
rid,
|
||||||
format!(
|
format!(
|
||||||
@@ -947,6 +959,75 @@ impl AppState {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"collab_with" => {
|
||||||
|
if let Some(args) = command_args {
|
||||||
|
if let Ok(id) = args.trim().parse::<usize>() {
|
||||||
|
if let Some(server) = self.servers.get(self.selected_server) {
|
||||||
|
if let Ok(mut lock) = server.lock() {
|
||||||
|
lock.action_que.push(format!("COLLAB|{}", id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"collab" => {
|
||||||
|
if let Some(args) = command_args {
|
||||||
|
if let Some(server) = self.servers.get(self.selected_server) {
|
||||||
|
if let Ok(mut lock) = server.lock() {
|
||||||
|
lock.action_que.push(format!("CMD|{}", args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"parse_port_scan" | "pps" => {
|
||||||
|
self.parse_cs_portscan()?;
|
||||||
|
}
|
||||||
|
"stop_db" => {
|
||||||
|
if let Some(project) = self.projects.get_mut(self.selected_project) {
|
||||||
|
if let Some(db) = project.db.as_mut() {
|
||||||
|
db.stop(self.main_tx.clone(), rid)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"rustwitness" => {
|
||||||
|
if let Some(project) = self.projects.get(self.selected_project) {
|
||||||
|
if let Some(args) = command_args {
|
||||||
|
if let Some((outfile, proxy)) = args.split_once(" ") {
|
||||||
|
let mut proxy_string = None;
|
||||||
|
if let Some((ip, port)) = proxy.split_once(" ") {
|
||||||
|
proxy_string = Some(format!("socks5://{}:{}", ip, port));
|
||||||
|
}
|
||||||
|
WalkDir::new(&project.files)
|
||||||
|
.into_iter()
|
||||||
|
.filter(|res| res.is_ok())
|
||||||
|
.for_each(|res| {
|
||||||
|
if let Ok(entry) = res {
|
||||||
|
if entry.file_name().to_string_lossy().contains("urls.txt")
|
||||||
|
{
|
||||||
|
let input = PathBuf::from(entry.path());
|
||||||
|
let mut output = project.files.clone();
|
||||||
|
output.push(outfile.trim());
|
||||||
|
let proxy_intput = proxy_string.clone();
|
||||||
|
let tx = self.main_tx.clone();
|
||||||
|
self.workers.spawn(move || {
|
||||||
|
rustwitness(input, output, proxy_intput, tx)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let _ = self.main_tx.send(ToolMessage::Output((
|
||||||
|
0,
|
||||||
|
"[error] incorrect command usage!".to_string(),
|
||||||
|
)));
|
||||||
|
let _ = self.main_tx.send(ToolMessage::Output((
|
||||||
|
0,
|
||||||
|
"usage: rustwitness output_file_name optional_proxy_ip optional_proxy_port".to_string(),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
"exit" => {
|
"exit" => {
|
||||||
self.save_all()?;
|
self.save_all()?;
|
||||||
let _ = self.main_tx.send(ToolMessage::AppStateExit);
|
let _ = self.main_tx.send(ToolMessage::AppStateExit);
|
||||||
@@ -966,7 +1047,7 @@ impl AppState {
|
|||||||
.module_loader
|
.module_loader
|
||||||
.asts
|
.asts
|
||||||
.get(command_name)
|
.get(command_name)
|
||||||
.ok_or_else(|| format!("Command not found: {}", command_name))?
|
.ok_or_else(|| format!("[error] Command not found: {}", command_name))?
|
||||||
.clone();
|
.clone();
|
||||||
let engine = Arc::clone(&self.module_loader.engine);
|
let engine = Arc::clone(&self.module_loader.engine);
|
||||||
let cmd_meta = self
|
let cmd_meta = self
|
||||||
@@ -1001,12 +1082,28 @@ impl AppState {
|
|||||||
}
|
}
|
||||||
scope.push("config", map);
|
scope.push("config", map);
|
||||||
}
|
}
|
||||||
|
"distrobox" => {
|
||||||
|
if let Some(db) = self.projects[self.selected_project].db.clone() {
|
||||||
|
scope.push("distrobox", db);
|
||||||
|
}
|
||||||
|
}
|
||||||
_ if arg_requirement.starts_with("string") => {
|
_ if arg_requirement.starts_with("string") => {
|
||||||
let input_val = command_args
|
let input_val = command_args
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_else(|| self.curent_intput.clone());
|
.unwrap_or_else(|| self.curent_intput.clone());
|
||||||
scope.push("input_string", input_val);
|
scope.push("input_string", input_val);
|
||||||
}
|
}
|
||||||
|
_ if arg_requirement.starts_with("bool") => {
|
||||||
|
let mut input_val = false;
|
||||||
|
if command_args
|
||||||
|
.clone()
|
||||||
|
.unwrap_or_else(|| self.curent_intput.clone())
|
||||||
|
.contains("true")
|
||||||
|
{
|
||||||
|
input_val = true;
|
||||||
|
}
|
||||||
|
scope.push("input_bool", input_val);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1053,7 +1150,7 @@ impl AppState {
|
|||||||
Err(err) => {
|
Err(err) => {
|
||||||
let _ = tx.send(ToolMessage::Output((
|
let _ = tx.send(ToolMessage::Output((
|
||||||
rid,
|
rid,
|
||||||
format!("Script [error] in execution: {}", err),
|
format!("[error] in script execution: {}", err),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1079,20 +1176,44 @@ impl AppState {
|
|||||||
name: String,
|
name: String,
|
||||||
rid: usize,
|
rid: usize,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
let mut main_config_file = self.config_file.clone();
|
||||||
|
main_config_file.pop();
|
||||||
|
let _ = self.main_tx.send(ToolMessage::Output((
|
||||||
|
rid,
|
||||||
|
format!("{} is the main config folder.", main_config_file.display()),
|
||||||
|
)));
|
||||||
let template_box = self.config.get("template_box").unwrap();
|
let template_box = self.config.get("template_box").unwrap();
|
||||||
let project_files = PathBuf::from(self.config.get("upcoming_files").unwrap())
|
let project_files = PathBuf::from(self.config.get("upcoming_files").unwrap())
|
||||||
.join(format!("{}/{}", org, name));
|
.join(format!("{}/{}", org, name));
|
||||||
|
let _ = self.main_tx.send(ToolMessage::Output((
|
||||||
|
rid,
|
||||||
|
format!("{} is the project_files folder", project_files.display()),
|
||||||
|
)));
|
||||||
let project_notes = PathBuf::from(self.config.get("upcoming_notes").unwrap())
|
let project_notes = PathBuf::from(self.config.get("upcoming_notes").unwrap())
|
||||||
.join(format!("{}/{}", org, name));
|
.join(format!("{}/{}", org, name));
|
||||||
let mut template_path = self.config_file.clone();
|
let _ = self.main_tx.send(ToolMessage::Output((
|
||||||
let mut project_conf_folder = self.config_file.clone();
|
rid,
|
||||||
|
format!("{} is the project_notes folder", project_notes.display()),
|
||||||
|
)));
|
||||||
|
let mut template_path = main_config_file.clone();
|
||||||
|
let mut project_conf_folder = main_config_file.clone();
|
||||||
let tools = self.config.get("tools").unwrap();
|
let tools = self.config.get("tools").unwrap();
|
||||||
template_path.pop();
|
|
||||||
template_path.push("note_templates");
|
template_path.push("note_templates");
|
||||||
project_conf_folder.pop();
|
let _ = self.main_tx.send(ToolMessage::Output((
|
||||||
|
rid,
|
||||||
|
format!("{} is the note template folder", template_path.display()),
|
||||||
|
)));
|
||||||
project_conf_folder.push(format!("projects/{}-{}", org, name));
|
project_conf_folder.push(format!("projects/{}-{}", org, name));
|
||||||
|
let _ = self.main_tx.send(ToolMessage::Output((
|
||||||
|
rid,
|
||||||
|
format!(
|
||||||
|
"{} is the project config folder",
|
||||||
|
project_conf_folder.display()
|
||||||
|
),
|
||||||
|
)));
|
||||||
let mut options = CopyOptions::new();
|
let mut options = CopyOptions::new();
|
||||||
options.overwrite = true;
|
options.overwrite = true;
|
||||||
|
if !project_files.exists() {
|
||||||
match create_dir_all(&project_files) {
|
match create_dir_all(&project_files) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -1105,6 +1226,8 @@ impl AppState {
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if !project_notes.exists() {}
|
||||||
match create_dir_all(&project_notes) {
|
match create_dir_all(&project_notes) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -1117,6 +1240,7 @@ impl AppState {
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !project_conf_folder.exists() {
|
||||||
match create_dir_all(&project_conf_folder) {
|
match create_dir_all(&project_conf_folder) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -1129,6 +1253,9 @@ impl AppState {
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
let mut project_config_file = project_conf_folder.clone();
|
||||||
|
project_config_file.push("project.conf");
|
||||||
for entry in read_dir(template_path)? {
|
for entry in read_dir(template_path)? {
|
||||||
let entry = entry?;
|
let entry = entry?;
|
||||||
let template_name_os = entry.file_name();
|
let template_name_os = entry.file_name();
|
||||||
@@ -1179,11 +1306,20 @@ impl AppState {
|
|||||||
notes: project_notes,
|
notes: project_notes,
|
||||||
files: project_files,
|
files: project_files,
|
||||||
hosts: Vec::new(),
|
hosts: Vec::new(),
|
||||||
config_folder: project_conf_folder,
|
config_folder: project_config_file,
|
||||||
current: false,
|
current: false,
|
||||||
db: Some(db),
|
db: Some(db),
|
||||||
scope: Vec::new(),
|
scope: Vec::new(),
|
||||||
};
|
};
|
||||||
|
match new_project.save_config() {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => {
|
||||||
|
let _ = self.main_tx.send(ToolMessage::Output((
|
||||||
|
0,
|
||||||
|
format!("[error] saving project! {e}"),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
new_project.save_config()?;
|
new_project.save_config()?;
|
||||||
self.projects.push(new_project);
|
self.projects.push(new_project);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@@ -1458,6 +1594,381 @@ impl AppState {
|
|||||||
self.prompt.execute_command.clear();
|
self.prompt.execute_command.clear();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_cs_portscan(&mut self) -> Result<(), Box<dyn Error>> {
|
||||||
|
if let Some(project) = self.projects.get_mut(self.selected_project) {
|
||||||
|
let walk = WalkDir::new(project.files.clone());
|
||||||
|
walk.into_iter().for_each(|res| {
|
||||||
|
if let Ok(entry) = res {
|
||||||
|
if entry.file_name().to_string_lossy().contains("services.tsv") {
|
||||||
|
if let Ok(scan) = read_to_string(entry.path()) {
|
||||||
|
let mut url_lines = Vec::new();
|
||||||
|
let mut web_host_lines = Vec::new();
|
||||||
|
let mut rdp_host_lines = Vec::new();
|
||||||
|
let mut ftp_host_lines = Vec::new();
|
||||||
|
let mut telnet_host_lines = Vec::new();
|
||||||
|
let mut winrm_host_lines = Vec::new();
|
||||||
|
let mut mysql_host_lines = Vec::new();
|
||||||
|
let mut mssql_host_lines = Vec::new();
|
||||||
|
let mut snmp_host_lines = Vec::new();
|
||||||
|
let mut kerberos_host_lines = Vec::new();
|
||||||
|
let mut ldap_host_lines = Vec::new();
|
||||||
|
let mut smb_host_lines = Vec::new();
|
||||||
|
let mut unknonw_host_lines = Vec::new();
|
||||||
|
let mut ssh_host_lines = Vec::new();
|
||||||
|
scan.lines().into_iter().for_each(|line| {
|
||||||
|
if line.len() > 0 {
|
||||||
|
let data: Vec<&str> = line.split_whitespace().collect();
|
||||||
|
match data[1].trim() {
|
||||||
|
"80" | "443" | "8080" | "8443" | "8000" | "4433" => {
|
||||||
|
let http_line =
|
||||||
|
format!("http://{}:{}", data[0], data[1]);
|
||||||
|
let https_line =
|
||||||
|
format!("https://{}:{}", data[0], data[1]);
|
||||||
|
url_lines.push(http_line);
|
||||||
|
url_lines.push(https_line);
|
||||||
|
web_host_lines.push(data[0].to_string());
|
||||||
|
let mut existing = false;
|
||||||
|
project
|
||||||
|
.hosts
|
||||||
|
.iter_mut()
|
||||||
|
.filter(|h| h.ip == data[0].to_string())
|
||||||
|
.for_each(|h| {
|
||||||
|
h.add_port(data[1]);
|
||||||
|
existing = true;
|
||||||
|
});
|
||||||
|
if !existing {
|
||||||
|
let mut new_host = Host::new();
|
||||||
|
new_host.ip = data[0].trim().to_string();
|
||||||
|
new_host.add_port(data[1]);
|
||||||
|
project.add_host(new_host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"3389" => {
|
||||||
|
rdp_host_lines.push(data[0].to_string());
|
||||||
|
let mut existing = false;
|
||||||
|
project
|
||||||
|
.hosts
|
||||||
|
.iter_mut()
|
||||||
|
.filter(|h| h.ip == data[0].to_string())
|
||||||
|
.for_each(|h| {
|
||||||
|
h.add_port(data[1]);
|
||||||
|
existing = true;
|
||||||
|
});
|
||||||
|
if !existing {
|
||||||
|
let mut new_host = Host::new();
|
||||||
|
new_host.ip = data[0].trim().to_string();
|
||||||
|
new_host.add_port(data[1]);
|
||||||
|
project.add_host(new_host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"21" => {
|
||||||
|
ftp_host_lines.push(data[0].to_string());
|
||||||
|
let mut existing = false;
|
||||||
|
project
|
||||||
|
.hosts
|
||||||
|
.iter_mut()
|
||||||
|
.filter(|h| h.ip == data[0].to_string())
|
||||||
|
.for_each(|h| {
|
||||||
|
h.add_port(data[1]);
|
||||||
|
existing = true;
|
||||||
|
});
|
||||||
|
if !existing {
|
||||||
|
let mut new_host = Host::new();
|
||||||
|
new_host.ip = data[0].trim().to_string();
|
||||||
|
new_host.add_port(data[1]);
|
||||||
|
project.add_host(new_host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"23" => {
|
||||||
|
telnet_host_lines.push(data[0].to_string());
|
||||||
|
let mut existing = false;
|
||||||
|
project
|
||||||
|
.hosts
|
||||||
|
.iter_mut()
|
||||||
|
.filter(|h| h.ip == data[0].to_string())
|
||||||
|
.for_each(|h| {
|
||||||
|
h.add_port(data[1]);
|
||||||
|
existing = true;
|
||||||
|
});
|
||||||
|
if !existing {
|
||||||
|
let mut new_host = Host::new();
|
||||||
|
new_host.ip = data[0].trim().to_string();
|
||||||
|
new_host.add_port(data[1]);
|
||||||
|
project.add_host(new_host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"22" => {
|
||||||
|
ssh_host_lines.push(data[0].to_string());
|
||||||
|
let mut existing = false;
|
||||||
|
project
|
||||||
|
.hosts
|
||||||
|
.iter_mut()
|
||||||
|
.filter(|h| h.ip == data[0].to_string())
|
||||||
|
.for_each(|h| {
|
||||||
|
h.add_port(data[1]);
|
||||||
|
existing = true;
|
||||||
|
});
|
||||||
|
if !existing {
|
||||||
|
let mut new_host = Host::new();
|
||||||
|
new_host.ip = data[0].trim().to_string();
|
||||||
|
new_host.add_port(data[1]);
|
||||||
|
project.add_host(new_host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"5985" | "5986" => {
|
||||||
|
winrm_host_lines.push(data[0].to_string());
|
||||||
|
let mut existing = false;
|
||||||
|
project
|
||||||
|
.hosts
|
||||||
|
.iter_mut()
|
||||||
|
.filter(|h| h.ip == data[0].to_string())
|
||||||
|
.for_each(|h| {
|
||||||
|
h.add_port(data[1]);
|
||||||
|
existing = true;
|
||||||
|
});
|
||||||
|
if !existing {
|
||||||
|
let mut new_host = Host::new();
|
||||||
|
new_host.ip = data[0].trim().to_string();
|
||||||
|
new_host.add_port(data[1]);
|
||||||
|
project.add_host(new_host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"3306" => {
|
||||||
|
mysql_host_lines.push(data[0].to_string());
|
||||||
|
let mut existing = false;
|
||||||
|
project
|
||||||
|
.hosts
|
||||||
|
.iter_mut()
|
||||||
|
.filter(|h| h.ip == data[0].to_string())
|
||||||
|
.for_each(|h| {
|
||||||
|
h.add_port(data[1]);
|
||||||
|
existing = true;
|
||||||
|
});
|
||||||
|
if !existing {
|
||||||
|
let mut new_host = Host::new();
|
||||||
|
new_host.ip = data[0].trim().to_string();
|
||||||
|
new_host.add_port(data[1]);
|
||||||
|
project.add_host(new_host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"1433" => {
|
||||||
|
mssql_host_lines.push(data[0].to_string());
|
||||||
|
let mut existing = false;
|
||||||
|
project
|
||||||
|
.hosts
|
||||||
|
.iter_mut()
|
||||||
|
.filter(|h| h.ip == data[0].to_string())
|
||||||
|
.for_each(|h| {
|
||||||
|
h.add_port(data[1]);
|
||||||
|
existing = true;
|
||||||
|
});
|
||||||
|
if !existing {
|
||||||
|
let mut new_host = Host::new();
|
||||||
|
new_host.ip = data[0].trim().to_string();
|
||||||
|
new_host.add_port(data[1]);
|
||||||
|
project.add_host(new_host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"161" => {
|
||||||
|
snmp_host_lines.push(data[0].to_string());
|
||||||
|
let mut existing = false;
|
||||||
|
project
|
||||||
|
.hosts
|
||||||
|
.iter_mut()
|
||||||
|
.filter(|h| h.ip == data[0].to_string())
|
||||||
|
.for_each(|h| {
|
||||||
|
h.add_port(data[1]);
|
||||||
|
existing = true;
|
||||||
|
});
|
||||||
|
if !existing {
|
||||||
|
let mut new_host = Host::new();
|
||||||
|
new_host.ip = data[0].trim().to_string();
|
||||||
|
new_host.add_port(data[1]);
|
||||||
|
project.add_host(new_host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"88" => {
|
||||||
|
kerberos_host_lines.push(data[0].to_string());
|
||||||
|
let mut existing = false;
|
||||||
|
project
|
||||||
|
.hosts
|
||||||
|
.iter_mut()
|
||||||
|
.filter(|h| h.ip == data[0].to_string())
|
||||||
|
.for_each(|h| {
|
||||||
|
h.add_port(data[1]);
|
||||||
|
existing = true;
|
||||||
|
});
|
||||||
|
if !existing {
|
||||||
|
let mut new_host = Host::new();
|
||||||
|
new_host.ip = data[0].trim().to_string();
|
||||||
|
new_host.add_port(data[1]);
|
||||||
|
project.add_host(new_host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"389" | "636" => {
|
||||||
|
ldap_host_lines.push(data[0].to_string());
|
||||||
|
let mut existing = false;
|
||||||
|
project
|
||||||
|
.hosts
|
||||||
|
.iter_mut()
|
||||||
|
.filter(|h| h.ip == data[0].to_string())
|
||||||
|
.for_each(|h| {
|
||||||
|
h.add_port(data[1]);
|
||||||
|
existing = true;
|
||||||
|
});
|
||||||
|
if !existing {
|
||||||
|
let mut new_host = Host::new();
|
||||||
|
new_host.ip = data[0].trim().to_string();
|
||||||
|
new_host.add_port(data[1]);
|
||||||
|
project.add_host(new_host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"445" | "139" => {
|
||||||
|
smb_host_lines.push(data[0].to_string());
|
||||||
|
let mut existing = false;
|
||||||
|
project
|
||||||
|
.hosts
|
||||||
|
.iter_mut()
|
||||||
|
.filter(|h| h.ip == data[0].to_string())
|
||||||
|
.for_each(|h| {
|
||||||
|
h.add_port(data[1]);
|
||||||
|
existing = true;
|
||||||
|
});
|
||||||
|
if !existing {
|
||||||
|
let mut new_host = Host::new();
|
||||||
|
new_host.ip = data[0].trim().to_string();
|
||||||
|
new_host.add_port(data[1]);
|
||||||
|
project.add_host(new_host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
unknonw_host_lines.push(data[0].to_string());
|
||||||
|
let mut existing = false;
|
||||||
|
project
|
||||||
|
.hosts
|
||||||
|
.iter_mut()
|
||||||
|
.filter(|h| h.ip == data[0].to_string())
|
||||||
|
.for_each(|h| {
|
||||||
|
h.add_port(data[1]);
|
||||||
|
existing = true;
|
||||||
|
});
|
||||||
|
if !existing {
|
||||||
|
let mut new_host = Host::new();
|
||||||
|
new_host.ip = data[0].trim().to_string();
|
||||||
|
new_host.add_port(data[1]);
|
||||||
|
project.add_host(new_host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if !url_lines.is_empty() {
|
||||||
|
let mut file_path = project.files.clone();
|
||||||
|
file_path.push("urls.txt");
|
||||||
|
if let Ok(mut file) = File::create(file_path) {
|
||||||
|
let _ = write!(file, "{}", url_lines.join("\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !web_host_lines.is_empty() {
|
||||||
|
let mut file_path = project.files.clone();
|
||||||
|
file_path.push("web_hosts.txt");
|
||||||
|
if let Ok(mut file) = File::create(file_path) {
|
||||||
|
let _ = write!(file, "{}", web_host_lines.join("\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !rdp_host_lines.is_empty() {
|
||||||
|
let mut file_path = project.files.clone();
|
||||||
|
file_path.push("rdp_hosts.txt");
|
||||||
|
if let Ok(mut file) = File::create(file_path) {
|
||||||
|
let _ = write!(file, "{}", rdp_host_lines.join("\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !ftp_host_lines.is_empty() {
|
||||||
|
let mut file_path = project.files.clone();
|
||||||
|
file_path.push("ftp_hosts.txt");
|
||||||
|
if let Ok(mut file) = File::create(file_path) {
|
||||||
|
let _ = write!(file, "{}", ftp_host_lines.join("\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !telnet_host_lines.is_empty() {
|
||||||
|
let mut file_path = project.files.clone();
|
||||||
|
file_path.push("telnet_hosts.txt");
|
||||||
|
if let Ok(mut file) = File::create(file_path) {
|
||||||
|
let _ = write!(file, "{}", telnet_host_lines.join("\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !winrm_host_lines.is_empty() {
|
||||||
|
let mut file_path = project.files.clone();
|
||||||
|
file_path.push("winrm_hosts.txt");
|
||||||
|
if let Ok(mut file) = File::create(file_path) {
|
||||||
|
let _ = write!(file, "{}", winrm_host_lines.join("\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !mysql_host_lines.is_empty() {
|
||||||
|
let mut file_path = project.files.clone();
|
||||||
|
file_path.push("mysql_hosts.txt");
|
||||||
|
if let Ok(mut file) = File::create(file_path) {
|
||||||
|
let _ = write!(file, "{}", mysql_host_lines.join("\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !mssql_host_lines.is_empty() {
|
||||||
|
let mut file_path = project.files.clone();
|
||||||
|
file_path.push("mssql_hosts.txt");
|
||||||
|
if let Ok(mut file) = File::create(file_path) {
|
||||||
|
let _ = write!(file, "{}", mssql_host_lines.join("\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !snmp_host_lines.is_empty() {
|
||||||
|
let mut file_path = project.files.clone();
|
||||||
|
file_path.push("snmp_hosts.txt");
|
||||||
|
if let Ok(mut file) = File::create(file_path) {
|
||||||
|
let _ = write!(file, "{}", snmp_host_lines.join("\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !kerberos_host_lines.is_empty() {
|
||||||
|
let mut file_path = project.files.clone();
|
||||||
|
file_path.push("kerberos_hosts.txt");
|
||||||
|
if let Ok(mut file) = File::create(file_path) {
|
||||||
|
let _ = write!(file, "{}", kerberos_host_lines.join("\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !ldap_host_lines.is_empty() {
|
||||||
|
let mut file_path = project.files.clone();
|
||||||
|
file_path.push("ldap_hosts.txt");
|
||||||
|
if let Ok(mut file) = File::create(file_path) {
|
||||||
|
let _ = write!(file, "{}", ldap_host_lines.join("\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !smb_host_lines.is_empty() {
|
||||||
|
let mut file_path = project.files.clone();
|
||||||
|
file_path.push("smb_hosts.txt");
|
||||||
|
if let Ok(mut file) = File::create(file_path) {
|
||||||
|
let _ = write!(file, "{}", smb_host_lines.join("\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !unknonw_host_lines.is_empty() {
|
||||||
|
let mut file_path = project.files.clone();
|
||||||
|
file_path.push("unknown_hosts.txt");
|
||||||
|
if let Ok(mut file) = File::create(file_path) {
|
||||||
|
let _ = write!(file, "{}", unknonw_host_lines.join("\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !ssh_host_lines.is_empty() {
|
||||||
|
let mut file_path = project.files.clone();
|
||||||
|
file_path.push("ssh_hosts.txt");
|
||||||
|
if let Ok(mut file) = File::create(file_path) {
|
||||||
|
let _ = write!(file, "{}", ssh_host_lines.join("\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
project.save_config()?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@@ -1632,9 +2143,19 @@ impl Project {
|
|||||||
self.hosts = hosts;
|
self.hosts = hosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_host(&mut self, host: Host) {
|
pub fn add_host(&mut self, mut host: Host) {
|
||||||
|
let mut new_id = 0;
|
||||||
|
self.hosts.iter().for_each(|h| {
|
||||||
|
if h.id > new_id {
|
||||||
|
new_id = h.id.clone();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
new_id += 1;
|
||||||
|
if !self.hosts.iter().any(|h| h.ip == host.ip) {
|
||||||
|
host.id = new_id;
|
||||||
self.hosts.push(host);
|
self.hosts.push(host);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn config_folder(&mut self, path: PathBuf) {
|
pub fn config_folder(&mut self, path: PathBuf) {
|
||||||
self.config_folder = path;
|
self.config_folder = path;
|
||||||
@@ -1681,11 +2202,11 @@ impl Project {
|
|||||||
println!("{} | {} config loaded!", self.org_name, self.name);
|
println!("{} | {} config loaded!", self.org_name, self.name);
|
||||||
println!("loading hosts...");
|
println!("loading hosts...");
|
||||||
}
|
}
|
||||||
let mut hosts_folder = self.config_folder.clone();
|
let mut conf_folder = self.config_folder.clone();
|
||||||
let mut users_folder = self.config_folder.clone();
|
conf_folder.pop();
|
||||||
hosts_folder.pop();
|
let mut hosts_folder = conf_folder.clone();
|
||||||
|
let mut users_folder = conf_folder.clone();
|
||||||
hosts_folder.push("hosts");
|
hosts_folder.push("hosts");
|
||||||
users_folder.pop();
|
|
||||||
users_folder.push("users");
|
users_folder.push("users");
|
||||||
let mut users = HashMap::new();
|
let mut users = HashMap::new();
|
||||||
if users_folder.exists() {
|
if users_folder.exists() {
|
||||||
@@ -1710,20 +2231,25 @@ impl Project {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if hosts_folder.exists() {
|
if hosts_folder.exists() {
|
||||||
for entry in read_dir(hosts_folder)? {
|
read_dir(hosts_folder)?.into_iter().for_each(|res| {
|
||||||
let entry = entry?;
|
if let Ok(entry) = res {
|
||||||
let host_path = entry.path();
|
let host_path = entry.path();
|
||||||
let mut new_host = Host::new();
|
let mut new_host = Host::new();
|
||||||
let host_conf_text = read_to_string(host_path)?;
|
println!("loading {}...", host_path.display());
|
||||||
for line in host_conf_text.lines() {
|
if let Ok(host_conf_text) = read_to_string(host_path) {
|
||||||
|
host_conf_text.lines().into_iter().for_each(|line| {
|
||||||
if line.contains(": ") {
|
if line.contains(": ") {
|
||||||
let (setting, data) = line.split_once(": ").unwrap();
|
let (setting, data) = line.split_once(": ").unwrap();
|
||||||
match setting.trim() {
|
match setting.trim() {
|
||||||
"ip" => new_host.ip = data.trim().to_string(),
|
"ip" => new_host.ip = data.trim().to_string(),
|
||||||
"hostname" => new_host.hostname = data.trim().to_string(),
|
"hostname" => new_host.hostname = data.trim().to_string(),
|
||||||
"control_port" => new_host.control_port = data.trim().parse()?,
|
"control_port" => {
|
||||||
"pwned" => new_host.pwned = data.trim().parse()?,
|
new_host.control_port = data.trim().parse().unwrap();
|
||||||
"id" => new_host.id = data.trim().parse()?,
|
}
|
||||||
|
"pwned" => {
|
||||||
|
new_host.pwned = data.trim().parse().unwrap();
|
||||||
|
}
|
||||||
|
"id" => new_host.id = data.trim().parse().unwrap(),
|
||||||
"findings" => {
|
"findings" => {
|
||||||
new_host.findings = data
|
new_host.findings = data
|
||||||
.trim()
|
.trim()
|
||||||
@@ -1736,7 +2262,7 @@ impl Project {
|
|||||||
.trim()
|
.trim()
|
||||||
.split(",")
|
.split(",")
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|port| port.parse().unwrap())
|
.map(|port| port.parse().unwrap_or_default())
|
||||||
.collect::<Vec<usize>>()
|
.collect::<Vec<usize>>()
|
||||||
}
|
}
|
||||||
"users" => {
|
"users" => {
|
||||||
@@ -1750,8 +2276,11 @@ impl Project {
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
self.add_host(new_host);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if display {
|
if display {
|
||||||
println!("{} | {} loaded!", self.org_name, self.name);
|
println!("{} | {} loaded!", self.org_name, self.name);
|
||||||
@@ -1760,16 +2289,29 @@ impl Project {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn save_config(&mut self) -> Result<(), Box<dyn Error>> {
|
pub fn save_config(&mut self) -> Result<(), Box<dyn Error>> {
|
||||||
create_dir_all(&self.config_folder)?;
|
let mut conf_folder = self.config_folder.clone();
|
||||||
let mut hosts_folder = self.config_folder.clone();
|
conf_folder.pop();
|
||||||
|
if !conf_folder.exists() {
|
||||||
|
match create_dir_all(&conf_folder) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => {
|
||||||
|
return Err(
|
||||||
|
format!("save_config: couldn't create project conf folder! {e}").into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut hosts_folder = conf_folder.clone();
|
||||||
hosts_folder.push("hosts");
|
hosts_folder.push("hosts");
|
||||||
let mut users_folder = self.config_folder.clone();
|
let mut users_folder = conf_folder.clone();
|
||||||
users_folder.push("users");
|
users_folder.push("users");
|
||||||
|
if !hosts_folder.exists() {
|
||||||
create_dir_all(&hosts_folder)?;
|
create_dir_all(&hosts_folder)?;
|
||||||
|
}
|
||||||
|
if !users_folder.exists() {
|
||||||
create_dir_all(&users_folder)?;
|
create_dir_all(&users_folder)?;
|
||||||
let mut conf_file = self.config_folder.clone();
|
}
|
||||||
conf_file.push("project.conf");
|
let mut file = File::create(&self.config_folder)?;
|
||||||
let mut file = File::create(conf_file)?;
|
|
||||||
let mut out_string = format!(
|
let mut out_string = format!(
|
||||||
"org_name: {}\nname: {}\nnotes: {}\nfiles: {}\nscope: {}\n",
|
"org_name: {}\nname: {}\nnotes: {}\nfiles: {}\nscope: {}\n",
|
||||||
self.org_name,
|
self.org_name,
|
||||||
@@ -1784,67 +2326,13 @@ impl Project {
|
|||||||
out_string.push_str("stage: upcoming");
|
out_string.push_str("stage: upcoming");
|
||||||
}
|
}
|
||||||
file.write_all(out_string.as_bytes())?;
|
file.write_all(out_string.as_bytes())?;
|
||||||
if !self.hosts.is_empty() {
|
self.hosts
|
||||||
for host in &self.hosts {
|
.iter_mut()
|
||||||
let mut host_conf_file =
|
.try_for_each(|h| -> Result<(), Box<dyn Error>> {
|
||||||
File::create(hosts_folder.join(format!("{}.conf", host.id)))?;
|
let mut host_path = hosts_folder.clone();
|
||||||
let mut out_string = format!(
|
host_path.push(format!("{}.conf", h.id));
|
||||||
"
|
h.save_config_file(host_path)
|
||||||
ip: {}
|
})?;
|
||||||
hostname: {}
|
|
||||||
control_port: {}
|
|
||||||
pwned: {}
|
|
||||||
id: {}",
|
|
||||||
host.ip, host.hostname, host.control_port, host.pwned, host.id,
|
|
||||||
);
|
|
||||||
if !host.findings.is_empty() {
|
|
||||||
out_string.push_str(&format!("\nfindings: "));
|
|
||||||
out_string.push_str(&host.findings.join(","));
|
|
||||||
}
|
|
||||||
if !host.open_ports.is_empty() {
|
|
||||||
out_string.push_str(&format!("\nopen_ports: "));
|
|
||||||
out_string.push_str(
|
|
||||||
&host
|
|
||||||
.open_ports
|
|
||||||
.iter()
|
|
||||||
.map(|port| port.to_string())
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join(","),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if !host.users.is_empty() {
|
|
||||||
out_string.push_str(&format!("\nusers: "));
|
|
||||||
out_string.push_str(
|
|
||||||
&host
|
|
||||||
.users
|
|
||||||
.iter()
|
|
||||||
.map(|user| user.name.clone())
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join(","),
|
|
||||||
);
|
|
||||||
for user in &host.users {
|
|
||||||
let mut user_conf_file =
|
|
||||||
File::create(users_folder.join(format!("{}.conf", user.name)))?;
|
|
||||||
let mut user_string = format!("username: {}", &user.name);
|
|
||||||
user_string.push_str(&format!("\ncompromised: {}", user.compromised));
|
|
||||||
if user.hash.is_some() {
|
|
||||||
let hash = user.hash.clone().unwrap();
|
|
||||||
user_string.push_str(&format!("hash: {hash}"));
|
|
||||||
}
|
|
||||||
if user.password.is_some() {
|
|
||||||
let password = user.password.clone().unwrap();
|
|
||||||
user_string.push_str(&format!("password: {password}"));
|
|
||||||
}
|
|
||||||
if user.ticket.is_some() {
|
|
||||||
let ticket = user.ticket.clone().unwrap().display().to_string();
|
|
||||||
user_string.push_str(&format!("ticket: {ticket}"));
|
|
||||||
}
|
|
||||||
user_conf_file.write_all(user_string.as_bytes())?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
host_conf_file.write_all(out_string.as_bytes())?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1922,9 +2410,13 @@ impl Host {
|
|||||||
self.findings = findings;
|
self.findings = findings;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_port(&mut self, port: usize) {
|
pub fn add_port(&mut self, port: &str) {
|
||||||
|
if let Ok(port) = port.trim().parse() {
|
||||||
|
if !self.open_ports.contains(&port) {
|
||||||
self.open_ports.push(port);
|
self.open_ports.push(port);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_user(&mut self, user: User) {
|
pub fn add_user(&mut self, user: User) {
|
||||||
self.users.push(user);
|
self.users.push(user);
|
||||||
@@ -1933,6 +2425,37 @@ impl Host {
|
|||||||
pub fn add_finding(&mut self, finding: String) {
|
pub fn add_finding(&mut self, finding: String) {
|
||||||
self.findings.push(finding);
|
self.findings.push(finding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn save_config_file(&mut self, path: PathBuf) -> Result<(), Box<dyn Error>> {
|
||||||
|
let mut host_file = File::create(path)?;
|
||||||
|
let mut out_string = format!(
|
||||||
|
"
|
||||||
|
ip: {}
|
||||||
|
hostname: {}
|
||||||
|
control_port: {}
|
||||||
|
pwned: {}
|
||||||
|
id: {}",
|
||||||
|
self.ip, self.hostname, self.control_port, self.pwned, self.id
|
||||||
|
);
|
||||||
|
if !self.findings.is_empty() {
|
||||||
|
out_string.push_str(&format!("\nfindings: "));
|
||||||
|
out_string.push_str(&self.findings.join(","));
|
||||||
|
}
|
||||||
|
if !self.open_ports.is_empty() {
|
||||||
|
out_string.push_str("\nopen_ports: ");
|
||||||
|
out_string.push_str(
|
||||||
|
&self
|
||||||
|
.open_ports
|
||||||
|
.iter()
|
||||||
|
.map(|port| port.to_string())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(","),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
write!(host_file, "{}", out_string)?;
|
||||||
|
host_file.sync_all()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@@ -2034,12 +2557,12 @@ impl ModuleLoader {
|
|||||||
engine.register_fn("get_host", |hosts: &mut Vec<Host>, index: i64| {
|
engine.register_fn("get_host", |hosts: &mut Vec<Host>, index: i64| {
|
||||||
hosts.get(index as usize).cloned().unwrap_or_else(Host::new)
|
hosts.get(index as usize).cloned().unwrap_or_else(Host::new)
|
||||||
});
|
});
|
||||||
engine.register_fn("Host", Host::new);
|
engine.register_fn("new_host", Host::new);
|
||||||
engine.register_fn("open_file", |path: &str| {
|
engine.register_fn("open_file", |path: &str| {
|
||||||
std::fs::read_to_string(path).unwrap_or_else(|_| String::new())
|
std::fs::read_to_string(path).unwrap_or_else(|_| String::new())
|
||||||
});
|
});
|
||||||
engine.register_fn("add_port", |host: &mut Host, port: i64| {
|
engine.register_fn("add_port", |host: &mut Host, port: i64| {
|
||||||
host.add_port(port as usize);
|
host.add_port(format!("{}", port).as_str());
|
||||||
});
|
});
|
||||||
engine.register_fn("expand_target", |s: &str| -> rhai::Array {
|
engine.register_fn("expand_target", |s: &str| -> rhai::Array {
|
||||||
let mut results = rhai::Array::new();
|
let mut results = rhai::Array::new();
|
||||||
@@ -2096,6 +2619,13 @@ impl ModuleLoader {
|
|||||||
}
|
}
|
||||||
return out_string;
|
return out_string;
|
||||||
});
|
});
|
||||||
|
engine.register_fn("db_run", |p: &mut Project, command: String| -> String {
|
||||||
|
let mut out_string = format!("No distrobox configured for selected project.");
|
||||||
|
if let Some(db) = p.db.clone() {
|
||||||
|
out_string = db.run_command(&command);
|
||||||
|
}
|
||||||
|
return out_string;
|
||||||
|
});
|
||||||
Self {
|
Self {
|
||||||
engine: Arc::new(engine),
|
engine: Arc::new(engine),
|
||||||
commands: HashMap::new(),
|
commands: HashMap::new(),
|
||||||
@@ -2317,7 +2847,6 @@ impl DistroBox {
|
|||||||
let reader = BufReader::new(stdout);
|
let reader = BufReader::new(stdout);
|
||||||
for line in reader.lines().flatten() {
|
for line in reader.lines().flatten() {
|
||||||
let _ = tx_out.send(ToolMessage::Output((rid, line.clone())));
|
let _ = tx_out.send(ToolMessage::Output((rid, line.clone())));
|
||||||
println!("{}", line);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2327,7 +2856,6 @@ impl DistroBox {
|
|||||||
let reader = BufReader::new(stderr);
|
let reader = BufReader::new(stderr);
|
||||||
for line in reader.lines().flatten() {
|
for line in reader.lines().flatten() {
|
||||||
let _ = tx_out.send(ToolMessage::Output((rid, line.clone())));
|
let _ = tx_out.send(ToolMessage::Output((rid, line.clone())));
|
||||||
println!("{}", line);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2382,6 +2910,26 @@ impl DistroBox {
|
|||||||
let _ = term_cmd.spawn();
|
let _ = term_cmd.spawn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn run_command(&self, cmd: &str) -> String {
|
||||||
|
let output = Command::new("distrobox")
|
||||||
|
.arg("enter")
|
||||||
|
.arg("-e")
|
||||||
|
.arg(format!("\"{}\"", cmd))
|
||||||
|
.output();
|
||||||
|
match output {
|
||||||
|
Ok(output) => {
|
||||||
|
if output.status.success() {
|
||||||
|
return String::from_utf8_lossy(&output.stdout).to_string();
|
||||||
|
} else {
|
||||||
|
return format!("[error] {}", String::from_utf8_lossy(&output.stdout));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
return format!("[error] {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
use crate::*;
|
||||||
|
use anyhow::Context;
|
||||||
|
use headless_chrome::{Browser, LaunchOptions};
|
||||||
|
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
|
||||||
|
|
||||||
|
pub fn rustwitness(
|
||||||
|
input: PathBuf,
|
||||||
|
output: PathBuf,
|
||||||
|
proxy: Option<String>,
|
||||||
|
tx: Sender<ToolMessage>,
|
||||||
|
) {
|
||||||
|
fn capture_screenshot(
|
||||||
|
url: &str,
|
||||||
|
proxy: Option<String>,
|
||||||
|
output: PathBuf,
|
||||||
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
if !output.exists() {
|
||||||
|
create_dir_all(&output)?;
|
||||||
|
}
|
||||||
|
let mut launch_options = LaunchOptions::default();
|
||||||
|
let file_name = url.split("://").collect::<Vec<&str>>()[1].to_string();
|
||||||
|
if let Some(ref proxy_url) = proxy {
|
||||||
|
let proxy_arg = format!("--proxy-server={}", proxy_url);
|
||||||
|
launch_options
|
||||||
|
.args
|
||||||
|
.push(std::ffi::OsStr::new(Box::leak(proxy_arg.into_boxed_str())));
|
||||||
|
}
|
||||||
|
let browser = Browser::new(launch_options).context("Browser launch failed")?;
|
||||||
|
let tab = browser.new_tab().context("Failed to open tab")?;
|
||||||
|
tab.navigate_to(url).context("Navigation failed")?;
|
||||||
|
tab.wait_until_navigated()
|
||||||
|
.context("Waiting for load failed")?;
|
||||||
|
tab.wait_for_element("body")?;
|
||||||
|
tab.evaluate("document.readyState === 'complete'", false)?;
|
||||||
|
let mut file_path = output.clone();
|
||||||
|
let mut log_path = output.clone();
|
||||||
|
log_path.push("log.txt");
|
||||||
|
file_path.push(format!("{}.png", file_name));
|
||||||
|
let png_data = tab
|
||||||
|
.capture_screenshot(
|
||||||
|
headless_chrome::protocol::cdp::Page::CaptureScreenshotFormatOption::Png,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.context("Screenshot capture failed")?;
|
||||||
|
|
||||||
|
fs::write(&file_path, png_data)
|
||||||
|
.context("Failed to write file")
|
||||||
|
.context(format!(
|
||||||
|
"failed to write png file! {}",
|
||||||
|
&file_path.display()
|
||||||
|
))?;
|
||||||
|
println!("Successfully captured: {}", url);
|
||||||
|
fs::write(&log_path, format!("{}\n", url).as_bytes())
|
||||||
|
.context("failed to write log file!")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
match File::open(&input) {
|
||||||
|
Ok(file) => {
|
||||||
|
let urls: Vec<String> = BufReader::new(file)
|
||||||
|
.lines()
|
||||||
|
.filter_map(|line| line.ok())
|
||||||
|
.map(|s| s.trim().to_string())
|
||||||
|
.filter(|s| !s.is_empty())
|
||||||
|
.collect();
|
||||||
|
let _ = tx.send(ToolMessage::Output((
|
||||||
|
0,
|
||||||
|
format!("Starting capture of {} urls...", urls.len()),
|
||||||
|
)));
|
||||||
|
urls.par_iter().enumerate().for_each(|(_index, url)| {
|
||||||
|
if let Err(e) = capture_screenshot(url, proxy.clone(), output.clone()) {
|
||||||
|
let _ = tx.send(ToolMessage::Output((
|
||||||
|
0,
|
||||||
|
format!("[error] rustwitness: Failed to process {}: {:?}", url, e),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let _ = tx.send(ToolMessage::Output((
|
||||||
|
0,
|
||||||
|
"[success] all urls scanned for screenshots!".to_string(),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
let _ = tx.send(ToolMessage::Output((0, format!("[error] rustwitness {e}"))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,7 @@ use tokio_rustls::rustls::pki_types::{CertificateDer, PrivateKeyDer};
|
|||||||
enum ClientAction {
|
enum ClientAction {
|
||||||
Output(String),
|
Output(String),
|
||||||
Cmd(String),
|
Cmd(String),
|
||||||
|
Collab(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
@@ -31,6 +32,7 @@ pub struct Client {
|
|||||||
actions: Vec<ClientAction>,
|
actions: Vec<ClientAction>,
|
||||||
controlling: usize,
|
controlling: usize,
|
||||||
controlled: usize,
|
controlled: usize,
|
||||||
|
collabing: Vec<usize>,
|
||||||
output_que: Vec<String>,
|
output_que: Vec<String>,
|
||||||
logged_in: bool,
|
logged_in: bool,
|
||||||
timer: Duration,
|
timer: Duration,
|
||||||
@@ -201,6 +203,7 @@ where
|
|||||||
actions: Vec::new(),
|
actions: Vec::new(),
|
||||||
controlled: 0,
|
controlled: 0,
|
||||||
controlling: 0,
|
controlling: 0,
|
||||||
|
collabing: Vec::new(),
|
||||||
output_que: Vec::new(),
|
output_que: Vec::new(),
|
||||||
logged_in: false,
|
logged_in: false,
|
||||||
timer: Duration::from_secs(5),
|
timer: Duration::from_secs(5),
|
||||||
@@ -312,6 +315,26 @@ where
|
|||||||
dest_client.id, cmd
|
dest_client.id, cmd
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
let mut colabs = Vec::new();
|
||||||
|
lock.clients.iter_mut().filter(|c| c.id == source_id).for_each(|c|{
|
||||||
|
if c.collabing.is_empty(){
|
||||||
|
c.actions.push(ClientAction::Output("Error no controlled or collabed clients associated with you!".to_string()));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
c.collabing.iter().for_each(|id|{
|
||||||
|
colabs.push(id.clone());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if !colabs.is_empty(){
|
||||||
|
colabs.iter().for_each(|id|{
|
||||||
|
lock.clients.iter_mut().filter(|c| &c.id == id).for_each(|c|{
|
||||||
|
c.actions.push(ClientAction::Cmd(data.to_string()));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"CONTROL" => {
|
"CONTROL" => {
|
||||||
let new_control_id = data.trim().parse::<usize>().unwrap();
|
let new_control_id = data.trim().parse::<usize>().unwrap();
|
||||||
@@ -429,6 +452,22 @@ where
|
|||||||
c.remove = true;
|
c.remove = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
"COLLAB" => {
|
||||||
|
let dest_id: usize = data.trim().parse().unwrap();
|
||||||
|
lock.clients
|
||||||
|
.iter_mut()
|
||||||
|
.filter(|c| c.id == source_id)
|
||||||
|
.for_each(|c| {
|
||||||
|
c.collabing.push(dest_id.clone());
|
||||||
|
});
|
||||||
|
lock.clients
|
||||||
|
.iter_mut()
|
||||||
|
.filter(|d| d.id == dest_id)
|
||||||
|
.for_each(|d| {
|
||||||
|
d.collabing.push(dest_id.clone());
|
||||||
|
});
|
||||||
|
println!("{} is collabing with {}", source_id, dest_id);
|
||||||
|
}
|
||||||
"SLEEP" => {
|
"SLEEP" => {
|
||||||
if let Ok(secs) = data.parse::<u64>() {
|
if let Ok(secs) = data.parse::<u64>() {
|
||||||
lock.clients
|
lock.clients
|
||||||
@@ -455,6 +494,9 @@ where
|
|||||||
println!("adding {} to output", text);
|
println!("adding {} to output", text);
|
||||||
messages.push(format!("OUTPUT|{}", text));
|
messages.push(format!("OUTPUT|{}", text));
|
||||||
}
|
}
|
||||||
|
ClientAction::Collab(text) => {
|
||||||
|
println!("todo");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let full_message = messages.join("||");
|
let full_message = messages.join("||");
|
||||||
@@ -523,6 +565,9 @@ where
|
|||||||
println!("adding {} to output", text);
|
println!("adding {} to output", text);
|
||||||
messages.push(format!("OUTPUT|{}", text));
|
messages.push(format!("OUTPUT|{}", text));
|
||||||
}
|
}
|
||||||
|
ClientAction::Collab(text) => {
|
||||||
|
println!("todo");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let full_message = messages.join("||");
|
let full_message = messages.join("||");
|
||||||
|
|||||||
Reference in New Issue
Block a user