diff --git a/Makefile b/Makefile index f3f492766..f0da03a6f 100644 --- a/Makefile +++ b/Makefile @@ -162,7 +162,7 @@ $(IMAGE_TYPE): results/$(BASENAME).$(IMAGE_TYPE) squashfs: results/$(BASENAME).squashfs results/$(BASENAME).$(IMAGE_TYPE) results/$(BASENAME).squashfs: $(IMAGE_RECIPE_SRC) results/$(BASENAME).deb - REQUIRES=debian ./build/os-compat/run-compat.sh ./image-recipe/run-local-build.sh "results/$(BASENAME).deb" + ./image-recipe/run-local-build.sh "results/$(BASENAME).deb" # For creating os images. DO NOT USE install: $(STARTOS_TARGETS) @@ -300,8 +300,8 @@ container-runtime/dist/node_modules/.package-lock.json container-runtime/dist/pa container-runtime/rootfs.$(ARCH).squashfs: container-runtime/debian.$(ARCH).squashfs container-runtime/container-runtime.service container-runtime/update-image.sh container-runtime/deb-install.sh container-runtime/dist/index.js container-runtime/dist/node_modules/.package-lock.json core/target/$(ARCH)-unknown-linux-musl/release/containerbox ARCH=$(ARCH) REQUIRES=linux ./build/os-compat/run-compat.sh ./container-runtime/update-image.sh -build/lib/depends build/lib/conflicts: $(ENVIRONMENT_FILE) build/dpkg-deps/* - build/dpkg-deps/generate.sh +build/lib/depends build/lib/conflicts: $(ENVIRONMENT_FILE) $(PLATFORM_FILE) $(shell ls build/dpkg-deps/*) + PLATFORM=$(PLATFORM) ARCH=$(ARCH) build/dpkg-deps/generate.sh $(FIRMWARE_ROMS): build/lib/firmware.json download-firmware.sh $(PLATFORM_FILE) ./download-firmware.sh $(PLATFORM) diff --git a/build/dpkg-deps/depends b/build/dpkg-deps/depends index 8593bc733..9703cc99e 100644 --- a/build/dpkg-deps/depends +++ b/build/dpkg-deps/depends @@ -9,7 +9,6 @@ ca-certificates cifs-utils cryptsetup curl -dnsutils dmidecode dnsutils dosfstools @@ -19,6 +18,8 @@ exfatprogs flashrom fuse3 grub-common +grub-efi +grub2-common htop httpdirfs iotop @@ -41,7 +42,6 @@ nvme-cli nyx openssh-server podman -postgresql psmisc qemu-guest-agent rfkill diff --git a/build/dpkg-deps/generate.sh b/build/dpkg-deps/generate.sh index 6aafeefc3..f3a963e5f 100755 --- a/build/dpkg-deps/generate.sh +++ b/build/dpkg-deps/generate.sh @@ -5,6 +5,10 @@ set -e cd "$(dirname "${BASH_SOURCE[0]}")" IFS="-" read -ra FEATURES <<< "$ENVIRONMENT" +FEATURES+=("${ARCH}") +if [ "$ARCH" != "$PLATFORM" ]; then + FEATURES+=("${PLATFORM}") +fi feature_file_checker=' /^#/ { next } diff --git a/build/dpkg-deps/raspberrypi.depends b/build/dpkg-deps/raspberrypi.depends new file mode 100644 index 000000000..1b50bcdb9 --- /dev/null +++ b/build/dpkg-deps/raspberrypi.depends @@ -0,0 +1,13 @@ +- grub-common +- grub-efi +- grub2-common ++ parted ++ raspberrypi-net-mods ++ raspberrypi-sys-mods ++ raspi-config ++ raspi-firmware ++ raspi-gpio ++ raspi-utils ++ rpi-eeprom ++ rpi-update ++ rpi.gpio-common \ No newline at end of file diff --git a/build/dpkg-deps/x86_64.depends b/build/dpkg-deps/x86_64.depends new file mode 100644 index 000000000..f6773627f --- /dev/null +++ b/build/dpkg-deps/x86_64.depends @@ -0,0 +1 @@ ++ grub-pc-bin \ No newline at end of file diff --git a/build/lib/scripts/enable-kiosk b/build/lib/scripts/enable-kiosk index 769a139e0..56baebd50 100755 --- a/build/lib/scripts/enable-kiosk +++ b/build/lib/scripts/enable-kiosk @@ -64,9 +64,11 @@ user_pref("messaging-system.rsexperimentloader.enabled", false); user_pref("network.allow-experiments", false); user_pref("network.captive-portal-service.enabled", false); user_pref("network.connectivity-service.enabled", false); -user_pref("network.proxy.autoconfig_url", "file:///usr/lib/startos/proxy.pac"); +user_pref("network.proxy.socks", "10.0.3.1"); +user_pref("network.proxy.socks_port", 9050); +user_pref("network.proxy.socks_version", 5); user_pref("network.proxy.socks_remote_dns", true); -user_pref("network.proxy.type", 2); +user_pref("network.proxy.type", 1); user_pref("privacy.resistFingerprinting", true); //Enable letterboxing if we want the window size sent to the server to snap to common resolutions: //user_pref("privacy.resistFingerprinting.letterboxing", true); diff --git a/build/lib/scripts/startos-initramfs-module b/build/lib/scripts/startos-initramfs-module index e13c887e2..f093328cc 100755 --- a/build/lib/scripts/startos-initramfs-module +++ b/build/lib/scripts/startos-initramfs-module @@ -83,6 +83,7 @@ local_mount_root() if [ -d "$image" ]; then mount -r --bind $image /lower elif [ -f "$image" ]; then + modprobe loop modprobe squashfs mount -r $image /lower else diff --git a/core/Cargo.lock b/core/Cargo.lock index dbf8e79f7..3413e08f6 100644 --- a/core/Cargo.lock +++ b/core/Cargo.lock @@ -4,9 +4,9 @@ version = 4 [[package]] name = "addr2line" -version = "0.24.2" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" dependencies = [ "gimli", ] @@ -60,7 +60,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom 0.3.3", "once_cell", "version_check", "zerocopy", @@ -142,12 +141,6 @@ dependencies = [ "syn 1.0.109", ] -[[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" @@ -174,9 +167,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.20" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -189,9 +182,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" @@ -224,9 +217,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "arbitrary" @@ -239,9 +232,9 @@ dependencies = [ [[package]] name = "archery" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae2ed21cd55021f05707a807a5fc85695dafb98832921f6cfa06db67ca5b869" +checksum = "70e0a5f99dfebb87bb342d0f53bb92c81842e100bbb915223e38349580e5441d" [[package]] name = "arrayref" @@ -270,7 +263,7 @@ dependencies = [ "cfg-if", "derive-deftly 1.2.0", "derive_builder_fork_arti", - "derive_more", + "derive_more 2.0.1", "educe", "fs-mistrust", "futures", @@ -283,7 +276,7 @@ dependencies = [ "rand 0.9.2", "safelog", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", "time", "tor-async-utils", "tor-basic-utils", @@ -354,7 +347,7 @@ dependencies = [ "nom 7.1.3", "num-traits", "rusticata-macros", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -411,8 +404,8 @@ dependencies = [ "pem", "rcgen", "ring", - "rustls 0.23.31", - "rustls-pemfile 2.2.0", + "rustls 0.23.32", + "rustls-pemfile", "serde", "serde_json", "thiserror 1.0.69", @@ -475,9 +468,9 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.13.2" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb812ffb58524bdd10860d7d974e2f01cc0950c2438a74ee5ec2e2280c6c4ffa" +checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" dependencies = [ "async-task", "concurrent-queue 2.5.0", @@ -504,20 +497,20 @@ dependencies = [ [[package]] name = "async-io" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19634d6336019ef220f09fd31168ce5c184b295cbf80345437cc36094ef223ca" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" dependencies = [ - "async-lock", + "autocfg", "cfg-if", "concurrent-queue 2.5.0", "futures-io", "futures-lite", "parking", "polling", - "rustix 1.0.8", + "rustix 1.1.2", "slab", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -545,9 +538,9 @@ dependencies = [ [[package]] name = "async-process" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65daa13722ad51e6ab1a1b9c01299142bc75135b337923cfa10e79bbbd669f00" +checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" dependencies = [ "async-channel 2.5.0", "async-io", @@ -558,7 +551,7 @@ dependencies = [ "cfg-if", "event-listener 5.4.1", "futures-lite", - "rustix 1.0.8", + "rustix 1.1.2", ] [[package]] @@ -574,9 +567,9 @@ dependencies = [ [[package]] name = "async-signal" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f567af260ef69e1d52c2b560ce0ea230763e6fbb9214a85d768760a920e3e3c1" +checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" dependencies = [ "async-io", "async-lock", @@ -584,10 +577,10 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 1.0.8", + "rustix 1.1.2", "signal-hook-registry", "slab", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -723,9 +716,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" -version = "1.13.3" +version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c953fe1ba023e6b7730c0d4b031d06f267f23a46167dcbd40316644b10a17ba" +checksum = "879b6c89592deb404ba4dc0ae6b58ffd1795c78991cbb5b8bc441c48a070440d" dependencies = [ "aws-lc-sys", "zeroize", @@ -733,15 +726,16 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.30.0" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff" +checksum = "a2b715a6010afb9e457ca2b7c9d2b9c344baa8baed7b38dc476034c171b32575" dependencies = [ "bindgen", "cc", "cmake", "dunce", "fs_extra", + "libloading", ] [[package]] @@ -773,11 +767,11 @@ dependencies = [ [[package]] name = "axum" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5" +checksum = "8a18ed336352031311f4e0b4dd2ff392d4fbb370777c9d18d7fc9d7359f73871" dependencies = [ - "axum-core 0.5.2", + "axum-core 0.5.5", "base64 0.22.1", "bytes", "form_urlencoded", @@ -793,15 +787,14 @@ dependencies = [ "mime", "percent-encoding", "pin-project-lite", - "rustversion", - "serde", + "serde_core", "serde_json", "serde_path_to_error", "serde_urlencoded", "sha1", "sync_wrapper", "tokio", - "tokio-tungstenite", + "tokio-tungstenite 0.28.0", "tower 0.5.2", "tower-layer", "tower-service", @@ -830,9 +823,9 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.5.2" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6" +checksum = "59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22" dependencies = [ "bytes", "futures-core", @@ -841,7 +834,6 @@ dependencies = [ "http-body-util", "mime", "pin-project-lite", - "rustversion", "sync_wrapper", "tower-layer", "tower-service", @@ -858,7 +850,7 @@ dependencies = [ "flate2", "lz4_flex", "solana-nohash-hasher", - "thiserror 2.0.16", + "thiserror 2.0.17", "tracing", "xxhash-rust", "xz2", @@ -868,9 +860,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.75" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ "addr2line", "cfg-if", @@ -878,7 +870,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", + "windows-link 0.2.1", ] [[package]] @@ -909,12 +901,24 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base32" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23ce669cd6c8588f79e15cf450314f9638f967fc5770ff1c7c1deb0925ea7cfa" + [[package]] name = "base32" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "022dfe9eb35f19ebbcb51e0b40a5ab759f46ad60cadf7297e0bd085afb50e076" +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "base64" version = "0.21.7" @@ -975,16 +979,14 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.69.5" +version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "cexpr", "clang-sys", - "itertools 0.12.1", - "lazy_static", - "lazycell", + "itertools 0.13.0", "log", "prettyplease", "proc-macro2", @@ -993,7 +995,6 @@ dependencies = [ "rustc-hash", "shlex", "syn 2.0.106", - "which", ] [[package]] @@ -1034,9 +1035,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.3" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" [[package]] name = "bitmaps" @@ -1120,6 +1121,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ + "block-padding", "generic-array", ] @@ -1132,6 +1134,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + [[package]] name = "blocking" version = "1.6.2" @@ -1179,7 +1187,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" dependencies = [ "memchr", - "regex-automata 0.4.10", + "regex-automata", "serde", ] @@ -1197,9 +1205,9 @@ checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" [[package]] name = "bytemuck" -version = "1.23.2" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" [[package]] name = "byteorder" @@ -1219,25 +1227,6 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" -[[package]] -name = "bzip2" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47" -dependencies = [ - "bzip2-sys", -] - -[[package]] -name = "bzip2-sys" -version = "0.1.13+1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" -dependencies = [ - "cc", - "pkg-config", -] - [[package]] name = "cache-padded" version = "1.3.0" @@ -1257,15 +1246,22 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.34" +version = "1.2.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42bc4aea80032b7bf409b0bc7ccad88853858911b7713a8062fdc0623867bedc" +checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[package]] name = "cexpr" version = "0.6.0" @@ -1289,17 +1285,16 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", "wasm-bindgen", - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -1309,6 +1304,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eebd66744a15ded14960ab4ccdbfb51ad3b81f51f3f04a80adac98c985396c9" dependencies = [ "hashbrown 0.14.5", + "stacker", ] [[package]] @@ -1335,7 +1331,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" dependencies = [ "ciborium-io", - "half 2.6.0", + "half 2.7.0", ] [[package]] @@ -1371,9 +1367,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.46" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c5e4fcf9c21d2e544ca1ee9d8552de13019a42aa7dbf32747fa7aaf1df76e57" +checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" dependencies = [ "clap_builder", "clap_derive", @@ -1381,9 +1377,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.46" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fecb53a0e6fcfb055f686001bc2e2592fa527efaf38dbe81a6a9563562e57d41" +checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" dependencies = [ "anstream", "anstyle", @@ -1393,9 +1389,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.45" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -1462,6 +1458,16 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "concurrent-queue" version = "1.2.4" @@ -1489,7 +1495,7 @@ dependencies = [ "encode_unicode", "libc", "once_cell", - "unicode-width 0.2.1", + "unicode-width 0.2.2", "windows-sys 0.59.0", ] @@ -1540,9 +1546,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const_format" -version = "0.2.34" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" +checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" dependencies = [ "const_format_proc_macros", ] @@ -1564,6 +1570,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + [[package]] name = "convert_case" version = "0.6.0" @@ -1630,6 +1642,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -1770,14 +1792,14 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "crossterm_winapi", - "derive_more", + "derive_more 2.0.1", "document-features", "futures-core", "mio", "parking_lot", - "rustix 1.0.8", + "rustix 1.1.2", "signal-hook", "signal-hook-mio", "winapi", @@ -1820,6 +1842,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-mac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" +dependencies = [ + "generic-array", + "subtle", +] + [[package]] name = "csv" version = "1.3.1" @@ -1919,6 +1951,16 @@ dependencies = [ "darling_macro 0.20.11", ] +[[package]] +name = "darling" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +dependencies = [ + "darling_core 0.21.3", + "darling_macro 0.21.3", +] + [[package]] name = "darling_core" version = "0.14.4" @@ -1947,6 +1989,20 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "darling_core" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.11.1", + "syn 2.0.106", +] + [[package]] name = "darling_macro" version = "0.14.4" @@ -1969,18 +2025,23 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core 0.21.3", + "quote", + "syn 2.0.106", +] + [[package]] name = "data-encoding" version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" -[[package]] -name = "deflate64" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da692b8d1080ea3045efaab14434d40468c3d8657e42abddfffca87b428f4c1b" - [[package]] name = "deku" version = "0.18.1" @@ -2059,12 +2120,12 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.0" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071" dependencies = [ "powerfmt", - "serde", + "serde_core", ] [[package]] @@ -2094,12 +2155,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357422a457ccb850dc8f1c1680e0670079560feaad6c2e247e3f345c4fab8a3f" dependencies = [ "heck 0.5.0", - "indexmap 2.11.0", + "indexmap 2.11.4", "itertools 0.14.0", "proc-macro-crate", "proc-macro2", "quote", - "sha3", + "sha3 0.10.8", "strum", "syn 2.0.106", "void", @@ -2112,12 +2173,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea41269bd490d251b9eca50ccb43117e641cc68b129849757c15ece88fe0574" dependencies = [ "heck 0.5.0", - "indexmap 2.11.0", + "indexmap 2.11.4", "itertools 0.14.0", "proc-macro-crate", "proc-macro2", "quote", - "sha3", + "sha3 0.10.8", "strum", "syn 2.0.106", "void", @@ -2165,6 +2226,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_more" +version = "0.99.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" +dependencies = [ + "convert_case 0.4.0", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.106", +] + [[package]] name = "derive_more" version = "2.0.1" @@ -2245,7 +2319,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.2", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -2305,9 +2379,9 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "downcast-rs" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8a8b81cacc08888170eef4d13b775126db426d0b348bee9d18c2c1eaf123cf" +checksum = "117240f60069e65410b3ae1bb213295bd828f707b5bec6596a1afc8793ce0cbc" [[package]] name = "dunce" @@ -2327,7 +2401,7 @@ version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f7d4c414c94bc830797115b8e5f434d58e7e80cb42ba88508c14bc6ea270625" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "byteorder", "lazy_static", "proc-macro-error2", @@ -2454,6 +2528,22 @@ dependencies = [ "zeroize", ] +[[package]] +name = "email-encoding" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9298e6504d9b9e780ed3f7dfd43a61be8cd0e09eb07f7706a945b0072b6670b6" +dependencies = [ + "base64 0.22.1", + "memchr", +] + +[[package]] +name = "email_address" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e079f19b08ca6239f47f8ba8509c11cf3ea30095831f7fed61441475edd8c449" + [[package]] name = "emver" version = "0.1.6" @@ -2562,7 +2652,7 @@ dependencies = [ "arrayvec 0.7.6", "hashx", "num-traits", - "thiserror 2.0.16", + "thiserror 2.0.17", "visibility", ] @@ -2579,12 +2669,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -2731,6 +2821,12 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" + [[package]] name = "fixed-capacity-vec" version = "1.0.1" @@ -2745,9 +2841,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9" dependencies = [ "crc32fast", "libz-rs-sys", @@ -2815,7 +2911,7 @@ dependencies = [ "libc", "pwd-grp", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", "walkdir", ] @@ -2851,7 +2947,7 @@ version = "0.2.4" source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit#24730694701a83432d791d80802db8bda0699700" dependencies = [ "fslock-arti-fork", - "thiserror 2.0.16", + "thiserror 2.0.17", "winapi", ] @@ -2968,7 +3064,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb" dependencies = [ "futures-io", - "rustls 0.23.31", + "rustls 0.23.32", "rustls-pki-types", ] @@ -3032,16 +3128,6 @@ dependencies = [ "webpki-roots 0.26.11", ] -[[package]] -name = "gethostname" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" -dependencies = [ - "libc", - "windows-targets 0.48.5", -] - [[package]] name = "getrandom" version = "0.1.16" @@ -3076,15 +3162,15 @@ dependencies = [ "js-sys", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasi 0.14.7+wasi-0.2.4", "wasm-bindgen", ] [[package]] name = "gimli" -version = "0.31.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] name = "glob" @@ -3116,7 +3202,7 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3696fafb1ecdcc2ae3ce337de73e9202806068594b77d22fdf2f3573c5ec2219" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "crc", "simple-bytes", "uuid", @@ -3157,7 +3243,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.11.0", + "indexmap 2.11.4", "slab", "tokio", "tokio-util", @@ -3172,12 +3258,13 @@ checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" [[package]] name = "half" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +checksum = "e54c115d4f30f52c67202f079c5f9d8b49db4691f460fdb0b4c2e838261b2ba5" dependencies = [ "cfg-if", "crunchy", + "zerocopy", ] [[package]] @@ -3216,6 +3303,12 @@ dependencies = [ "foldhash", ] +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + [[package]] name = "hashlink" version = "0.10.0" @@ -3236,7 +3329,7 @@ dependencies = [ "fixed-capacity-vec", "hex", "rand_core 0.9.3", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -3303,43 +3396,15 @@ dependencies = [ "data-encoding", "futures-channel", "futures-util", - "hickory-proto 0.25.2", + "hickory-proto", "once_cell", "radix_trie", "rand 0.9.2", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tracing", ] -[[package]] -name = "hickory-proto" -version = "0.24.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92652067c9ce6f66ce53cc38d1169daa36e6e7eb7dd3b63b5103bd9d97117248" -dependencies = [ - "async-trait", - "cfg-if", - "data-encoding", - "enum-as-inner", - "futures-channel", - "futures-io", - "futures-util", - "idna", - "ipnet", - "once_cell", - "rand 0.8.5", - "ring", - "rustls 0.21.12", - "rustls-pemfile 1.0.4", - "thiserror 1.0.69", - "tinyvec", - "tokio", - "tokio-rustls 0.24.1", - "tracing", - "url", -] - [[package]] name = "hickory-proto" version = "0.25.2" @@ -3359,36 +3424,13 @@ dependencies = [ "rand 0.9.2", "ring", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", "tinyvec", "tokio", "tracing", "url", ] -[[package]] -name = "hickory-resolver" -version = "0.24.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbb117a1ca520e111743ab2f6688eddee69db4e0ea242545a604dce8a66fd22e" -dependencies = [ - "cfg-if", - "futures-util", - "hickory-proto 0.24.4", - "ipconfig", - "lru-cache", - "once_cell", - "parking_lot", - "rand 0.8.5", - "resolv-conf", - "rustls 0.21.12", - "smallvec", - "thiserror 1.0.69", - "tokio", - "tokio-rustls 0.24.1", - "tracing", -] - [[package]] name = "hickory-server" version = "0.25.2" @@ -3401,11 +3443,11 @@ dependencies = [ "data-encoding", "enum-as-inner", "futures-util", - "hickory-proto 0.25.2", + "hickory-proto", "ipnet", "prefix-trie", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", "time", "tokio", "tokio-util", @@ -3424,7 +3466,17 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ - "hmac", + "hmac 0.12.1", +] + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac", + "digest 0.9.0", ] [[package]] @@ -3445,6 +3497,17 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "hostname" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56f203cd1c76362b69e3863fd987520ac36cf70a8c92627449b2f64a8cf7d65" +dependencies = [ + "cfg-if", + "libc", + "windows-link 0.1.3", +] + [[package]] name = "hostname-validator" version = "1.1.1" @@ -3499,9 +3562,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" +checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" [[package]] name = "humantime-serde" @@ -3545,10 +3608,10 @@ dependencies = [ "http", "hyper", "hyper-util", - "rustls 0.23.31", + "rustls 0.23.32", "rustls-pki-types", "tokio", - "tokio-rustls 0.26.2", + "tokio-rustls 0.26.4", "tower-service", ] @@ -3583,9 +3646,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" dependencies = [ "base64 0.22.1", "bytes", @@ -3609,9 +3672,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.63" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -3619,7 +3682,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core", + "windows-core 0.62.2", ] [[package]] @@ -3755,20 +3818,21 @@ dependencies = [ [[package]] name = "image" -version = "0.25.6" +version = "0.25.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a" +checksum = "529feb3e6769d234375c4cf1ee2ce713682b8e76538cb13f9fc23e1400a591e7" dependencies = [ "bytemuck", "byteorder-lite", + "moxcms", "num-traits", ] [[package]] name = "imbl" -version = "6.0.0" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33afdc5d333c1a43f1f640bfc6ad3788729e5b2f18472e5d33a9187315257f8e" +checksum = "0fade8ae6828627ad1fa094a891eccfb25150b383047190a3648d66d06186501" dependencies = [ "archery", "bitmaps", @@ -3850,13 +3914,14 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.11.0" +version = "2.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" dependencies = [ "equivalent", - "hashbrown 0.15.5", + "hashbrown 0.16.0", "serde", + "serde_core", ] [[package]] @@ -3869,7 +3934,7 @@ dependencies = [ "number_prefix", "portable-atomic", "tokio", - "unicode-width 0.2.1", + "unicode-width 0.2.2", "web-time", ] @@ -3879,7 +3944,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "futures-core", "inotify-sys", "libc", @@ -3929,23 +3994,11 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "cfg-if", "libc", ] -[[package]] -name = "ipconfig" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" -dependencies = [ - "socket2 0.5.10", - "widestring", - "windows-sys 0.48.0", - "winreg", -] - [[package]] name = "ipnet" version = "2.11.0" @@ -4019,15 +4072,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.13.0" @@ -4090,6 +4134,28 @@ dependencies = [ "jaq-parse", ] +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + [[package]] name = "jobserver" version = "0.1.34" @@ -4113,15 +4179,15 @@ dependencies = [ "regex", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "time", ] [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" dependencies = [ "once_cell", "wasm-bindgen", @@ -4143,7 +4209,7 @@ dependencies = [ "imbl", "imbl-value 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -4164,7 +4230,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4dc5fdb62af2f520116927304f15d25b3c2667b4817b90efdc045194c912c54" dependencies = [ "digest 0.10.7", - "sha3", + "sha3 0.10.8", ] [[package]] @@ -4219,7 +4285,7 @@ dependencies = [ "petgraph", "pico-args", "regex", - "regex-syntax 0.8.6", + "regex-syntax 0.8.7", "string_cache", "term", "tiny-keccak", @@ -4233,7 +4299,7 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" dependencies = [ - "regex-automata 0.4.10", + "regex-automata", ] [[package]] @@ -4262,10 +4328,33 @@ dependencies = [ ] [[package]] -name = "lazycell" -version = "1.3.0" +name = "lettre" +version = "0.11.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +checksum = "9e13e10e8818f8b2a60f52cb127041d388b89f3a96a62be9ceaffa22262fef7f" +dependencies = [ + "async-trait", + "base64 0.22.1", + "chumsky", + "email-encoding", + "email_address", + "fastrand", + "futures-io", + "futures-util", + "hostname", + "httpdate", + "idna", + "mime", + "nom 8.0.0", + "percent-encoding", + "quoted_printable", + "rustls 0.23.32", + "rustls-platform-verifier", + "socket2 0.6.0", + "tokio", + "tokio-rustls 0.26.4", + "url", +] [[package]] name = "lexical-core" @@ -4282,9 +4371,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.175" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "libloading" @@ -4293,7 +4382,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.53.3", + "windows-targets 0.53.5", ] [[package]] @@ -4304,13 +4393,13 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "libc", - "redox_syscall 0.5.17", + "redox_syscall 0.5.18", ] [[package]] @@ -4336,19 +4425,13 @@ dependencies = [ [[package]] name = "libz-rs-sys" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "172a788537a2221661b480fee8dc5f96c580eb34fa88764d3205dc356c7e4221" +checksum = "840db8cf39d9ec4dd794376f38acc40d0fc65eec2a8f484f7fd375b84602becd" dependencies = [ "zlib-rs", ] -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -4357,9 +4440,9 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "linux-raw-sys" -version = "0.9.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" @@ -4375,48 +4458,28 @@ checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" dependencies = [ "value-bag", ] -[[package]] -name = "lru-cache" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" -dependencies = [ - "linked-hash-map", -] - [[package]] name = "lz4_flex" version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08ab2867e3eeeca90e844d1940eab391c9dc5228783db2ed999acbc0a9ed375a" -[[package]] -name = "lzma-rs" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" -dependencies = [ - "byteorder", - "crc", -] - [[package]] name = "lzma-sys" version = "0.1.20" @@ -4428,71 +4491,13 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "mail-auth" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bd9d657de66a3d5ac360c3eab8c9f5cac2565f2b97cc032d5de4c900ef470de" -dependencies = [ - "ahash 0.8.12", - "flate2", - "hickory-resolver", - "lru-cache", - "mail-builder", - "mail-parser", - "parking_lot", - "quick-xml", - "ring", - "rustls-pemfile 2.2.0", - "serde", - "serde_json", - "zip", -] - -[[package]] -name = "mail-builder" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25f5871d5270ed80f2ee750b95600c8d69b05f8653ad3be913b2ad2e924fefcb" -dependencies = [ - "gethostname", -] - -[[package]] -name = "mail-parser" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93c3b9e5d8b17faf573330bbc43b37d6e918c0a3bf8a88e7d0a220ebc84af9fc" -dependencies = [ - "encoding_rs", -] - -[[package]] -name = "mail-send" -version = "0.4.9" -source = "git+https://github.com/dr-bonez/mail-send.git?branch=main#57545dadab5808d59145d133de64f81b8ba01979" -dependencies = [ - "base64 0.22.1", - "gethostname", - "mail-auth", - "mail-builder", - "md5", - "rand 0.8.5", - "rustls 0.23.31", - "rustls-pki-types", - "smtp-proto", - "tokio", - "tokio-rustls 0.26.2", - "webpki-roots 0.26.11", -] - [[package]] name = "matchers" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" dependencies = [ - "regex-automata 0.1.10", + "regex-automata", ] [[package]] @@ -4517,7 +4522,7 @@ dependencies = [ "bitvec 1.0.1", "serde", "serde-big-array", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -4530,17 +4535,11 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "md5" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" - [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "memmap2" @@ -4600,6 +4599,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", ] [[package]] @@ -4619,7 +4619,7 @@ name = "models" version = "0.1.0" dependencies = [ "arti-client", - "axum 0.8.4", + "axum 0.8.6", "base64 0.22.1", "color-eyre", "ed25519-dalek 2.2.0", @@ -4627,6 +4627,7 @@ dependencies = [ "gpt", "ipnet", "lazy_static", + "lettre", "mbrman", "num_enum", "openssl", @@ -4635,12 +4636,13 @@ dependencies = [ "regex", "reqwest", "rpc-toolkit", - "rustls 0.23.31", + "rustls 0.23.32", "serde", "serde_json", "ssh-key", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", + "torut", "tracing", "ts-rs", "typeid", @@ -4648,6 +4650,16 @@ dependencies = [ "zbus", ] +[[package]] +name = "moxcms" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cc7d85f3d741164e8972ad355e26ac6e51b20fcae5f911c7da8f2d8bbbb3f33" +dependencies = [ + "num-traits", + "pxfm", +] + [[package]] name = "native-tls" version = "0.2.14" @@ -4660,7 +4672,7 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "security-framework", + "security-framework 2.11.1", "security-framework-sys", "tempfile", ] @@ -4721,7 +4733,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "cfg-if", "cfg_aliases", "libc", @@ -4775,7 +4787,7 @@ version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "inotify", "kqueue", "libc", @@ -4803,12 +4815,11 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.46.0" +version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "overload", - "winapi", + "windows-sys 0.61.2", ] [[package]] @@ -4954,18 +4965,18 @@ checksum = "6aa2c4e539b869820a2b82e1aef6ff40aa85e65decdd5185e83fb4b1249cd00f" [[package]] name = "objc2-core-foundation" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", ] [[package]] name = "objc2-io-kit" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71c1c64d6120e51cd86033f67176b1cb66780c2efe34dec55176f77befd93c0a" +checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15" dependencies = [ "libc", "objc2-core-foundation", @@ -4973,9 +4984,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.7" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "memchr", ] @@ -5044,7 +5055,7 @@ version = "0.10.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "cfg-if", "foreign-types", "libc", @@ -5072,9 +5083,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-src" -version = "300.5.2+3.5.2" +version = "300.5.3+3.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d270b79e2926f5150189d475bc7e9d2c69f9c4697b185fa917d5a32b792d21b4" +checksum = "dc6bad8cd0233b63971e232cc9c5e83039375b8586d2312f31fda85db8f888c2" dependencies = [ "cc", ] @@ -5126,17 +5137,11 @@ dependencies = [ "memchr", ] -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "owo-colors" -version = "4.2.2" +version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48dd4f4a2c8405440fd0462561f0e5806bd0f77e86f51c761481bdd4018b545e" +checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52" [[package]] name = "p256" @@ -5184,9 +5189,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -5194,15 +5199,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.17", + "redox_syscall 0.5.18", "smallvec", - "windows-targets 0.52.6", + "windows-link 0.2.1", ] [[package]] @@ -5227,7 +5232,7 @@ dependencies = [ "patch-db-macro", "serde", "serde_cbor", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tracing", "tracing-error", @@ -5259,17 +5264,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest 0.10.7", - "hmac", + "hmac 0.12.1", ] [[package]] name = "pem" -version = "3.0.5" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" +checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" dependencies = [ "base64 0.22.1", - "serde", + "serde_core", ] [[package]] @@ -5289,20 +5294,19 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.1" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" +checksum = "989e7521a040efde50c3ab6bbadafbe15ab6dc042686926be59ac35d74607df4" dependencies = [ "memchr", - "thiserror 2.0.16", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.8.1" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc" +checksum = "187da9a3030dbafabbbfb20cb323b976dc7b7ce91fcd84f2f74d6e31d378e2de" dependencies = [ "pest", "pest_generator", @@ -5310,9 +5314,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.1" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966" +checksum = "49b401d98f5757ebe97a26085998d6c0eecec4995cad6ab7fc30ffdf4b052843" dependencies = [ "pest", "pest_meta", @@ -5323,9 +5327,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.8.1" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5" +checksum = "72f27a2cfee9f9039c4d86faa5af122a0ac3851441a34865b8a043b46be0065a" dependencies = [ "pest", "sha2 0.10.9", @@ -5338,7 +5342,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.11.0", + "indexmap 2.11.4", ] [[package]] @@ -5499,16 +5503,16 @@ dependencies = [ [[package]] name = "polling" -version = "3.10.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5bd19146350fe804f7cb2669c851c03d69da628803dab0d98018142aaa5d829" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" dependencies = [ "cfg-if", "concurrent-queue 2.5.0", "hermit-abi", "pin-project-lite", - "rustix 1.0.8", - "windows-sys 0.60.2", + "rustix 1.1.2", + "windows-sys 0.61.2", ] [[package]] @@ -5534,9 +5538,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" dependencies = [ "zerovec", ] @@ -5607,22 +5611,22 @@ dependencies = [ [[package]] name = "priority-queue" -version = "2.5.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5676d703dda103cbb035b653a9f11448c0a7216c7926bd35fcb5865475d0c970" +checksum = "93980406f12d9f8140ed5abe7155acb10bb1e69ea55c88960b9c2f117445ef96" dependencies = [ - "autocfg", "equivalent", - "indexmap 2.11.0", + "indexmap 2.11.4", + "serde", ] [[package]] name = "proc-macro-crate" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ - "toml_edit", + "toml_edit 0.23.7", ] [[package]] @@ -5662,7 +5666,7 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc5b72d8145275d844d4b5f6d4e1eef00c8cd889edb6035c21675d1bb1f45c9f" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "chrono", "flate2", "hex", @@ -5676,26 +5680,26 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "chrono", "hex", ] [[package]] name = "proptest" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fcdab19deb5195a31cf7726a210015ff1496ba1464fd42cb4f537b8b01b471f" +checksum = "2bb0be07becd10686a0bb407298fb425360a5c44a663774406340c59a22de4ce" dependencies = [ "bit-set 0.8.0", "bit-vec 0.8.0", - "bitflags 2.9.3", + "bitflags 2.9.4", "lazy_static", "num-traits", "rand 0.9.2", "rand_chacha 0.9.0", "rand_xorshift", - "regex-syntax 0.8.6", + "regex-syntax 0.8.7", "rusty-fork", "tempfile", "unarray", @@ -5750,13 +5754,22 @@ version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" +[[package]] +name = "psm" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e66fcd288453b748497d8fb18bccc83a16b0518e3906d4b8df0a8d42d93dbb1c" +dependencies = [ + "cc", +] + [[package]] name = "pty-process" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71cec9e2670207c5ebb9e477763c74436af3b9091dd550b9fb3c1bec7f3ea266" dependencies = [ - "rustix 1.0.8", + "rustix 1.1.2", ] [[package]] @@ -5781,6 +5794,15 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "pxfm" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3cbdf373972bf78df4d3b518d07003938e2c7d1fb5891e55f9cb6df57009d84" +dependencies = [ + "num-traits", +] + [[package]] name = "qrcode" version = "0.14.1" @@ -5796,24 +5818,21 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" -[[package]] -name = "quick-xml" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2" -dependencies = [ - "memchr", -] - [[package]] name = "quote" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] +[[package]] +name = "quoted_printable" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "640c9bd8497b02465aeef5375144c26062e0dcd5939dfcbb0f5db76cb8c17c73" + [[package]] name = "r-efi" version = "5.3.0" @@ -6029,11 +6048,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.17" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", ] [[package]] @@ -6061,23 +6080,23 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.16", "libredox", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] name = "ref-cast" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", @@ -6086,34 +6105,25 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.2" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" +checksum = "4a52d8d02cacdb176ef4678de6c052efb4b3da14b78e4db683a4252762be5433" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.10", - "regex-syntax 0.8.6", + "regex-automata", + "regex-syntax 0.8.7", ] [[package]] name = "regex-automata" -version = "0.1.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", -] - -[[package]] -name = "regex-automata" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" +checksum = "722166aa0d7438abbaa4d5cc2c649dac844e8c56d82fb3d33e9c34b5cd268fc6" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.6", + "regex-syntax 0.8.7", ] [[package]] @@ -6124,9 +6134,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" +checksum = "c3160422bbd54dd5ecfdca71e5fd59b7b8fe2b1697ab2baf64f6d05dcc66d298" [[package]] name = "reqwest" @@ -6185,12 +6195,6 @@ dependencies = [ "url", ] -[[package]] -name = "resolv-conf" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95325155c684b1c89f7765e30bc1c42e4a6da51ca513615660cb8a62ef9a88e3" - [[package]] name = "retry-error" version = "0.6.5" @@ -6202,7 +6206,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "hmac", + "hmac 0.12.1", "subtle", ] @@ -6238,7 +6242,7 @@ source = "git+https://github.com/Start9Labs/rpc-toolkit.git?branch=master#23ecbd dependencies = [ "async-stream", "async-trait", - "axum 0.8.4", + "axum 0.8.6", "clap", "futures", "http", @@ -6252,7 +6256,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "url", @@ -6296,7 +6300,7 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "165ca6e57b20e1351573e3729b958bc62f0e48025386970b6e4d29e7a7e71f3f" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -6324,9 +6328,9 @@ checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] name = "rustc-hash" -version = "1.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustc_version" @@ -6352,8 +6356,8 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.3", - "errno 0.3.13", + "bitflags 2.9.4", + "errno 0.3.14", "libc", "linux-raw-sys 0.4.15", "windows-sys 0.59.0", @@ -6361,27 +6365,15 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.8" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.9.3", - "errno 0.3.13", + "bitflags 2.9.4", + "errno 0.3.14", "libc", - "linux-raw-sys 0.9.4", - "windows-sys 0.60.2", -] - -[[package]] -name = "rustls" -version = "0.21.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" -dependencies = [ - "log", - "ring", - "rustls-webpki 0.101.7", - "sct", + "linux-raw-sys 0.11.0", + "windows-sys 0.61.2", ] [[package]] @@ -6400,27 +6392,30 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.31" +version = "0.23.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" +checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" dependencies = [ "aws-lc-rs", "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.4", + "rustls-webpki 0.103.7", "subtle", "zeroize", ] [[package]] -name = "rustls-pemfile" -version = "1.0.4" +name = "rustls-native-certs" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" dependencies = [ - "base64 0.21.7", + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework 3.5.1", ] [[package]] @@ -6442,15 +6437,32 @@ dependencies = [ ] [[package]] -name = "rustls-webpki" -version = "0.101.7" +name = "rustls-platform-verifier" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +checksum = "be59af91596cac372a6942530653ad0c3a246cdd491aaa9dcaee47f88d67d5a0" dependencies = [ - "ring", - "untrusted", + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls 0.23.32", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki 0.103.7", + "security-framework 3.5.1", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.59.0", ] +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" version = "0.102.8" @@ -6464,9 +6476,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.4" +version = "0.103.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" dependencies = [ "aws-lc-rs", "ring", @@ -6482,9 +6494,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "rusty-fork" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" dependencies = [ "fnv", "quick-error", @@ -6503,7 +6515,7 @@ dependencies = [ "futures-util", "pin-project", "thingbuf", - "thiserror 2.0.16", + "thiserror 2.0.17", "unicode-segmentation", ] @@ -6518,11 +6530,11 @@ name = "safelog" version = "0.4.8" source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit#24730694701a83432d791d80802db8bda0699700" dependencies = [ - "derive_more", + "derive_more 2.0.1", "educe", "either", "fluid-let", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -6545,11 +6557,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -6582,16 +6594,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "sec1" version = "0.7.3" @@ -6612,8 +6614,21 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.3", - "core-foundation", + "bitflags 2.9.4", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +dependencies = [ + "bitflags 2.9.4", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -6621,9 +6636,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.14.0" +version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ "core-foundation-sys", "libc", @@ -6631,19 +6646,21 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" dependencies = [ "serde", + "serde_core", ] [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ] @@ -6668,11 +6685,12 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.17" +version = "0.11.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" dependencies = [ "serde", + "serde_core", ] [[package]] @@ -6684,10 +6702,19 @@ dependencies = [ ] [[package]] -name = "serde_derive" -version = "1.0.219" +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -6696,34 +6723,37 @@ dependencies = [ [[package]] name = "serde_ignored" -version = "0.1.12" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b516445dac1e3535b6d658a7b528d771153dfb272ed4180ca4617a20550365ff" +checksum = "115dffd5f3853e06e746965a20dcbae6ee747ae30b543d91b0e089668bb07798" dependencies = [ "serde", + "serde_core", ] [[package]] name = "serde_json" -version = "1.0.143" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ - "indexmap 2.11.0", + "indexmap 2.11.4", "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] name = "serde_path_to_error" -version = "0.1.17" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" dependencies = [ "itoa", "serde", + "serde_core", ] [[package]] @@ -6759,11 +6789,11 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.0.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83" +checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -6780,19 +6810,18 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5" +checksum = "6093cd8c01b25262b84927e0f7151692158fab02d961e04c979d3903eba7ecc5" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.11.0", + "indexmap 2.11.4", "schemars 0.9.0", "schemars 1.0.4", - "serde", - "serde_derive", + "serde_core", "serde_json", "serde_with_macros", "time", @@ -6800,11 +6829,11 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" +checksum = "a7e6c180db0816026a61afa1cff5344fb7ebded7e4d3062772179f2501481c27" dependencies = [ - "darling 0.20.11", + "darling 0.21.3", "proc-macro2", "quote", "syn 2.0.106", @@ -6816,7 +6845,7 @@ version = "0.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59e2dd588bf1597a252c3b920e0143eb99b0f76e4e082f4c92ce34fbc9e71ddd" dependencies = [ - "indexmap 2.11.0", + "indexmap 2.11.4", "itoa", "libyml", "memchr", @@ -6872,6 +6901,18 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "keccak", + "opaque-debug", +] + [[package]] name = "sha3" version = "0.10.8" @@ -7013,7 +7054,7 @@ dependencies = [ "paste", "serde", "slotmap", - "thiserror 2.0.16", + "thiserror 2.0.17", "void", ] @@ -7032,12 +7073,6 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" -[[package]] -name = "smtp-proto" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7d3950ab75b03c52f2f13fd52aab91c9d62698b231b67240e85c3ef5301e63e" - [[package]] name = "socket2" version = "0.5.10" @@ -7067,7 +7102,7 @@ dependencies = [ "async-trait", "bytes", "percent-encoding", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", ] @@ -7122,17 +7157,17 @@ dependencies = [ "futures-util", "hashbrown 0.15.5", "hashlink", - "indexmap 2.11.0", + "indexmap 2.11.4", "log", "memchr", "once_cell", "percent-encoding", - "rustls 0.23.31", + "rustls 0.23.32", "serde", "serde_json", "sha2 0.10.9", "smallvec", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tracing", @@ -7184,7 +7219,7 @@ checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" dependencies = [ "atoi", "base64 0.22.1", - "bitflags 2.9.3", + "bitflags 2.9.4", "byteorder", "crc", "dotenvy", @@ -7194,7 +7229,7 @@ dependencies = [ "futures-util", "hex", "hkdf", - "hmac", + "hmac 0.12.1", "home", "itoa", "log", @@ -7208,7 +7243,7 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror 2.0.16", + "thiserror 2.0.17", "tracing", "whoami", ] @@ -7284,13 +7319,26 @@ dependencies = [ [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "stacker" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1f8b29fb42aafcea4edeeb6b2f2d7ecd0d969c48b4cf0d2e64aafc471dd6e59" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "windows-sys 0.59.0", +] [[package]] name = "start-os" -version = "0.4.0-alpha.11" +version = "0.4.0-alpha.12" dependencies = [ "aes 0.7.5", "arti-client", @@ -7298,11 +7346,11 @@ dependencies = [ "async-compression", "async-stream", "async-trait", - "axum 0.8.4", + "axum 0.8.6", "backhand", "backtrace-on-stack-overflow", "barrage", - "base32", + "base32 0.5.1", "base64 0.22.1", "base64ct", "basic-cookies", @@ -7317,6 +7365,7 @@ dependencies = [ "const_format", "cookie", "cookie_store", + "curve25519-dalek 4.1.3", "der", "digest 0.10.7", "divrem", @@ -7333,7 +7382,7 @@ dependencies = [ "hex", "hickory-client", "hickory-server", - "hmac", + "hmac 0.12.1", "http", "http-body-util", "hyper", @@ -7342,7 +7391,7 @@ dependencies = [ "imbl", "imbl-value 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "include_dir", - "indexmap 2.11.0", + "indexmap 2.11.4", "indicatif", "inotify", "integer-encoding", @@ -7356,9 +7405,9 @@ dependencies = [ "lazy_async_pool", "lazy_format", "lazy_static", + "lettre", "libc", "log", - "mail-send", "mbrman", "mio", "models", @@ -7389,8 +7438,6 @@ dependencies = [ "rpassword", "rpc-toolkit", "rust-argon2", - "rustls 0.23.31", - "rustls-pki-types", "rustyline-async", "safelog", "semver", @@ -7412,12 +7459,12 @@ dependencies = [ "tar", "termion", "textwrap", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", - "tokio-rustls 0.26.2", + "tokio-rustls 0.26.4", "tokio-stream", "tokio-tar", - "tokio-tungstenite", + "tokio-tungstenite 0.26.2", "tokio-util", "toml 0.8.23", "tor-cell", @@ -7427,6 +7474,7 @@ dependencies = [ "tor-llcrypto", "tor-proto", "tor-rtcompat", + "torut", "tower-service", "tracing", "tracing-error", @@ -7574,8 +7622,8 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.9.3", - "core-foundation", + "bitflags 2.9.4", + "core-foundation 0.9.4", "system-configuration-sys", ] @@ -7603,20 +7651,20 @@ checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" dependencies = [ "filetime", "libc", - "xattr 1.5.1", + "xattr 1.6.1", ] [[package]] name = "tempfile" -version = "3.21.0" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", "getrandom 0.3.3", "once_cell", - "rustix 1.0.8", - "windows-sys 0.60.2", + "rustix 1.1.2", + "windows-sys 0.61.2", ] [[package]] @@ -7659,7 +7707,7 @@ checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" dependencies = [ "smawk", "unicode-linebreak", - "unicode-width 0.2.1", + "unicode-width 0.2.2", ] [[package]] @@ -7683,11 +7731,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.16", + "thiserror-impl 2.0.17", ] [[package]] @@ -7703,9 +7751,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", @@ -7734,9 +7782,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.41" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ "deranged", "itoa", @@ -7749,15 +7797,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" [[package]] name = "time-macros" -version = "0.2.22" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" dependencies = [ "num-conv", "time-core", @@ -7849,16 +7897,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls 0.21.12", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.25.0" @@ -7872,11 +7910,11 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls 0.23.31", + "rustls 0.23.32", "tokio", ] @@ -7917,7 +7955,19 @@ dependencies = [ "native-tls", "tokio", "tokio-native-tls", - "tungstenite", + "tungstenite 0.26.2", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite 0.28.0", ] [[package]] @@ -7943,19 +7993,19 @@ dependencies = [ "serde", "serde_spanned 0.6.9", "toml_datetime 0.6.11", - "toml_edit", + "toml_edit 0.22.27", ] [[package]] name = "toml" -version = "0.9.5" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8" +checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" dependencies = [ - "indexmap 2.11.0", - "serde", - "serde_spanned 1.0.0", - "toml_datetime 0.7.0", + "indexmap 2.11.4", + "serde_core", + "serde_spanned 1.0.3", + "toml_datetime 0.7.3", "toml_parser", "toml_writer", "winnow", @@ -7972,11 +8022,11 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3" +checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -7985,7 +8035,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.11.0", + "indexmap 2.11.4", "serde", "serde_spanned 0.6.9", "toml_datetime 0.6.11", @@ -7994,10 +8044,22 @@ dependencies = [ ] [[package]] -name = "toml_parser" -version = "1.0.2" +name = "toml_edit" +version = "0.23.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10" +checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" +dependencies = [ + "indexmap 2.11.4", + "toml_datetime 0.7.3", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" dependencies = [ "winnow", ] @@ -8010,9 +8072,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" [[package]] name = "toml_writer" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64" +checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" [[package]] name = "tonic" @@ -8055,7 +8117,7 @@ dependencies = [ "oneshot-fused-workaround", "pin-project", "postage", - "thiserror 2.0.16", + "thiserror 2.0.17", "void", ] @@ -8064,7 +8126,7 @@ name = "tor-basic-utils" version = "0.33.0" source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit#24730694701a83432d791d80802db8bda0699700" dependencies = [ - "derive_more", + "derive_more 2.0.1", "hex", "itertools 0.14.0", "libc", @@ -8074,7 +8136,7 @@ dependencies = [ "serde", "slab", "smallvec", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -8088,7 +8150,7 @@ dependencies = [ "educe", "getrandom 0.3.3", "safelog", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-error", "tor-llcrypto", "zeroize", @@ -8100,17 +8162,17 @@ version = "0.33.0" source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit#24730694701a83432d791d80802db8bda0699700" dependencies = [ "amplify", - "bitflags 2.9.3", + "bitflags 2.9.4", "bytes", "caret", "derive-deftly 1.2.0", - "derive_more", + "derive_more 2.0.1", "educe", "itertools 0.14.0", "paste", "rand 0.9.2", "smallvec", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-basic-utils", "tor-bytes", "tor-cert", @@ -8131,9 +8193,9 @@ source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit dependencies = [ "caret", "derive_builder_fork_arti", - "derive_more", + "derive_more 2.0.1", "digest 0.10.7", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-bytes", "tor-checkable", "tor-llcrypto", @@ -8147,7 +8209,7 @@ dependencies = [ "async-trait", "caret", "derive_builder_fork_arti", - "derive_more", + "derive_more 2.0.1", "educe", "futures", "oneshot-fused-workaround", @@ -8155,7 +8217,7 @@ dependencies = [ "rand 0.9.2", "safelog", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-async-utils", "tor-basic-utils", "tor-cell", @@ -8181,7 +8243,7 @@ source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit dependencies = [ "humantime", "signature 2.2.0", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-llcrypto", ] @@ -8196,7 +8258,7 @@ dependencies = [ "cfg-if", "derive-deftly 1.2.0", "derive_builder_fork_arti", - "derive_more", + "derive_more 2.0.1", "downcast-rs", "dyn-clone", "educe", @@ -8211,7 +8273,7 @@ dependencies = [ "safelog", "serde", "static_assertions", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-async-utils", "tor-basic-utils", "tor-cell", @@ -8257,8 +8319,8 @@ dependencies = [ "serde-value", "serde_ignored", "strum", - "thiserror 2.0.16", - "toml 0.9.5", + "thiserror 2.0.17", + "toml 0.9.8", "tor-basic-utils", "tor-error", "tor-rtcompat", @@ -8274,7 +8336,7 @@ dependencies = [ "directories", "serde", "shellexpand", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-error", "tor-general-addr", ] @@ -8286,7 +8348,7 @@ source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit dependencies = [ "digest 0.10.7", "hex", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-llcrypto", ] @@ -8297,7 +8359,7 @@ source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit dependencies = [ "async-compression", "base64ct", - "derive_more", + "derive_more 2.0.1", "futures", "hex", "http", @@ -8305,7 +8367,7 @@ dependencies = [ "httpdate", "itertools 0.14.0", "memchr", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-circmgr", "tor-error", "tor-hscrypto", @@ -8325,7 +8387,7 @@ dependencies = [ "async-trait", "base64ct", "derive_builder_fork_arti", - "derive_more", + "derive_more 2.0.1", "digest 0.10.7", "educe", "event-listener 5.4.1", @@ -8349,7 +8411,7 @@ dependencies = [ "signature 2.2.0", "static_assertions", "strum", - "thiserror 2.0.16", + "thiserror 2.0.17", "time", "tor-async-utils", "tor-basic-utils", @@ -8375,13 +8437,13 @@ name = "tor-error" version = "0.33.0" source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit#24730694701a83432d791d80802db8bda0699700" dependencies = [ - "derive_more", + "derive_more 2.0.1", "futures", "paste", "retry-error", "static_assertions", "strum", - "thiserror 2.0.16", + "thiserror 2.0.17", "tracing", "void", ] @@ -8392,8 +8454,8 @@ version = "0.33.0" source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit#24730694701a83432d791d80802db8bda0699700" dependencies = [ "arbitrary", - "derive_more", - "thiserror 2.0.16", + "derive_more 2.0.1", + "thiserror 2.0.17", "void", ] @@ -8406,7 +8468,7 @@ dependencies = [ "base64ct", "derive-deftly 1.2.0", "derive_builder_fork_arti", - "derive_more", + "derive_more 2.0.1", "dyn-clone", "educe", "futures", @@ -8421,7 +8483,7 @@ dependencies = [ "safelog", "serde", "strum", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-async-utils", "tor-basic-utils", "tor-config", @@ -8445,7 +8507,7 @@ source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit dependencies = [ "async-trait", "derive-deftly 1.2.0", - "derive_more", + "derive_more 2.0.1", "educe", "either", "futures", @@ -8457,7 +8519,7 @@ dependencies = [ "safelog", "slotmap-careful", "strum", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-async-utils", "tor-basic-utils", "tor-bytes", @@ -8489,7 +8551,7 @@ dependencies = [ "cipher 0.4.4", "data-encoding", "derive-deftly 1.2.0", - "derive_more", + "derive_more 2.0.1", "digest 0.10.7", "equix", "hex", @@ -8501,7 +8563,7 @@ dependencies = [ "serde", "signature 2.2.0", "subtle", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-basic-utils", "tor-bytes", "tor-error", @@ -8524,7 +8586,7 @@ dependencies = [ "cfg-if", "derive-deftly 1.2.0", "derive_builder_fork_arti", - "derive_more", + "derive_more 2.0.1", "digest 0.10.7", "educe", "fs-mistrust", @@ -8544,7 +8606,7 @@ dependencies = [ "serde", "serde_with", "strum", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-async-utils", "tor-basic-utils", "tor-bytes", @@ -8576,13 +8638,13 @@ version = "0.33.0" source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit#24730694701a83432d791d80802db8bda0699700" dependencies = [ "derive-deftly 1.2.0", - "derive_more", + "derive_more 2.0.1", "downcast-rs", "paste", "rand 0.9.2", "signature 2.2.0", "ssh-key", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-bytes", "tor-cert", "tor-checkable", @@ -8600,7 +8662,7 @@ dependencies = [ "cfg-if", "derive-deftly 1.2.0", "derive_builder_fork_arti", - "derive_more", + "derive_more 2.0.1", "downcast-rs", "dyn-clone", "fs-mistrust", @@ -8613,7 +8675,7 @@ dependencies = [ "serde", "signature 2.2.0", "ssh-key", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-basic-utils", "tor-bytes", "tor-config", @@ -8639,14 +8701,14 @@ dependencies = [ "caret", "derive-deftly 1.2.0", "derive_builder_fork_arti", - "derive_more", + "derive_more 2.0.1", "hex", "itertools 0.14.0", "safelog", "serde", "serde_with", "strum", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-basic-utils", "tor-bytes", "tor-config", @@ -8666,7 +8728,7 @@ dependencies = [ "curve25519-dalek 4.1.3", "der-parser 10.0.0", "derive-deftly 1.2.0", - "derive_more", + "derive_more 2.0.1", "digest 0.10.7", "ed25519-dalek 2.2.0", "educe", @@ -8683,10 +8745,10 @@ dependencies = [ "serde", "sha1", "sha2 0.10.9", - "sha3", + "sha3 0.10.8", "signature 2.2.0", "subtle", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-memquota", "visibility", "x25519-dalek", @@ -8700,7 +8762,7 @@ source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit dependencies = [ "futures", "humantime", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-error", "tor-rtcompat", "tracing", @@ -8714,7 +8776,7 @@ source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit dependencies = [ "cfg-if", "derive-deftly 1.2.0", - "derive_more", + "derive_more 2.0.1", "dyn-clone", "educe", "futures", @@ -8725,7 +8787,7 @@ dependencies = [ "slotmap-careful", "static_assertions", "sysinfo", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-async-utils", "tor-basic-utils", "tor-config", @@ -8742,8 +8804,8 @@ version = "0.33.0" source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit#24730694701a83432d791d80802db8bda0699700" dependencies = [ "async-trait", - "bitflags 2.9.3", - "derive_more", + "bitflags 2.9.4", + "derive_more 2.0.1", "digest 0.10.7", "futures", "hex", @@ -8754,7 +8816,7 @@ dependencies = [ "serde", "static_assertions", "strum", - "thiserror 2.0.16", + "thiserror 2.0.17", "time", "tor-basic-utils", "tor-error", @@ -8775,11 +8837,11 @@ source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit dependencies = [ "amplify", "base64ct", - "bitflags 2.9.3", + "bitflags 2.9.4", "cipher 0.4.4", "derive-deftly 1.2.0", "derive_builder_fork_arti", - "derive_more", + "derive_more 2.0.1", "digest 0.10.7", "educe", "hex", @@ -8795,7 +8857,7 @@ dependencies = [ "smallvec", "strum", "subtle", - "thiserror 2.0.16", + "thiserror 2.0.17", "time", "tinystr", "tor-basic-utils", @@ -8821,7 +8883,7 @@ source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit dependencies = [ "amplify", "derive-deftly 1.2.0", - "derive_more", + "derive_more 2.0.1", "filetime", "fs-mistrust", "fslock", @@ -8833,7 +8895,7 @@ dependencies = [ "sanitize-filename", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "time", "tor-async-utils", "tor-basic-utils", @@ -8858,13 +8920,13 @@ dependencies = [ "criterion-cycles-per-byte", "derive-deftly 1.2.0", "derive_builder_fork_arti", - "derive_more", + "derive_more 2.0.1", "digest 0.10.7", "educe", "futures", "futures-util", "hkdf", - "hmac", + "hmac 0.12.1", "itertools 0.14.0", "oneshot-fused-workaround", "pin-project", @@ -8877,7 +8939,7 @@ dependencies = [ "static_assertions", "subtle", "sync_wrapper", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-util", "tor-async-utils", @@ -8912,7 +8974,7 @@ dependencies = [ "caret", "paste", "serde_with", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-bytes", ] @@ -8942,7 +9004,7 @@ dependencies = [ "async_executors", "asynchronous-codec", "coarsetime", - "derive_more", + "derive_more 2.0.1", "dyn-clone", "educe", "futures", @@ -8953,8 +9015,8 @@ dependencies = [ "paste", "pin-project", "rustls-pki-types", - "rustls-webpki 0.103.4", - "thiserror 2.0.16", + "rustls-webpki 0.103.7", + "thiserror 2.0.17", "tokio", "tokio-util", "tor-error", @@ -8972,7 +9034,7 @@ dependencies = [ "assert_matches", "async-trait", "derive-deftly 1.2.0", - "derive_more", + "derive_more 2.0.1", "educe", "futures", "humantime", @@ -8982,7 +9044,7 @@ dependencies = [ "priority-queue", "slotmap-careful", "strum", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-error", "tor-general-addr", "tor-rtcompat", @@ -9002,7 +9064,7 @@ dependencies = [ "educe", "safelog", "subtle", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-bytes", "tor-error", ] @@ -9013,12 +9075,32 @@ version = "0.33.0" source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit#24730694701a83432d791d80802db8bda0699700" dependencies = [ "derive-deftly 1.2.0", - "derive_more", + "derive_more 2.0.1", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", "tor-memquota", ] +[[package]] +name = "torut" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99febc413f26cf855b3a309c5872edff5c31e0ffe9c2fce5681868761df36f69" +dependencies = [ + "base32 0.4.0", + "base64 0.13.1", + "derive_more 0.99.20", + "ed25519-dalek 1.0.1", + "hex", + "hmac 0.11.0", + "rand 0.7.3", + "serde", + "serde_derive", + "sha2 0.9.9", + "sha3 0.9.1", + "tokio", +] + [[package]] name = "tower" version = "0.4.13" @@ -9061,7 +9143,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "bytes", "futures-util", "http", @@ -9162,14 +9244,14 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ "matchers", "nu-ansi-term", "once_cell", - "regex", + "regex-automata", "sharded-slab", "smallvec", "thread_local", @@ -9241,11 +9323,28 @@ dependencies = [ "native-tls", "rand 0.9.2", "sha1", - "thiserror 2.0.16", + "thiserror 2.0.17", "url", "utf-8", ] +[[package]] +name = "tungstenite" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" +dependencies = [ + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.9.2", + "sha1", + "thiserror 2.0.17", + "utf-8", +] + [[package]] name = "typed-builder" version = "0.21.2" @@ -9284,9 +9383,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "ucd-trie" @@ -9334,9 +9433,9 @@ checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" [[package]] name = "unicode-linebreak" @@ -9373,9 +9472,9 @@ checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-width" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "unicode-xid" @@ -9443,9 +9542,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.18.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f33196643e165781c20a5ead5582283a7dacbb87855d867fbc2df3f81eddc1be" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ "getrandom 0.3.3", "js-sys", @@ -9541,11 +9640,20 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" -version = "0.14.2+wasi-0.2.4" +version = "0.14.7+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" dependencies = [ - "wit-bindgen-rt", + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", ] [[package]] @@ -9565,21 +9673,22 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" dependencies = [ "bumpalo", "log", @@ -9591,9 +9700,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" dependencies = [ "cfg-if", "js-sys", @@ -9604,9 +9713,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -9614,9 +9723,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" dependencies = [ "proc-macro2", "quote", @@ -9627,9 +9736,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" dependencies = [ "unicode-ident", ] @@ -9655,9 +9764,9 @@ checksum = "323f4da9523e9a669e1eaf9c6e763892769b1d38c623913647bfdc1532fe4549" [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" dependencies = [ "js-sys", "wasm-bindgen", @@ -9674,33 +9783,30 @@ dependencies = [ ] [[package]] -name = "webpki-roots" -version = "0.26.11" +name = "webpki-root-certs" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" -dependencies = [ - "webpki-roots 1.0.2", -] - -[[package]] -name = "webpki-roots" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" +checksum = "05d651ec480de84b762e7be71e6efa7461699c19d9e2c272c8d93455f567786e" dependencies = [ "rustls-pki-types", ] [[package]] -name = "which" -version = "4.4.2" +name = "webpki-roots" +version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "either", - "home", - "once_cell", - "rustix 0.38.44", + "webpki-roots 1.0.3", +] + +[[package]] +name = "webpki-roots" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" +dependencies = [ + "rustls-pki-types", ] [[package]] @@ -9713,12 +9819,6 @@ dependencies = [ "wasite", ] -[[package]] -name = "widestring" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" - [[package]] name = "winapi" version = "0.3.9" @@ -9737,11 +9837,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -9757,9 +9857,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ "windows-collections", - "windows-core", + "windows-core 0.61.2", "windows-future", - "windows-link", + "windows-link 0.1.3", "windows-numerics", ] @@ -9769,7 +9869,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" dependencies = [ - "windows-core", + "windows-core 0.61.2", ] [[package]] @@ -9780,9 +9880,22 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement", "windows-interface", - "windows-link", - "windows-result", - "windows-strings", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", ] [[package]] @@ -9791,16 +9904,16 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ - "windows-core", - "windows-link", + "windows-core 0.61.2", + "windows-link 0.1.3", "windows-threading", ] [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", @@ -9809,9 +9922,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", @@ -9824,14 +9937,20 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-numerics" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" dependencies = [ - "windows-core", - "windows-link", + "windows-core 0.61.2", + "windows-link 0.1.3", ] [[package]] @@ -9840,9 +9959,9 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" dependencies = [ - "windows-link", - "windows-result", - "windows-strings", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", ] [[package]] @@ -9851,7 +9970,16 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-link", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link 0.2.1", ] [[package]] @@ -9860,7 +9988,25 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-link", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", ] [[package]] @@ -9896,7 +10042,31 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.3", + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -9932,19 +10102,19 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.3" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows-link", - "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", + "windows-link 0.2.1", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -9953,9 +10123,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -9970,9 +10146,15 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" @@ -9988,9 +10170,15 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" @@ -10006,9 +10194,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" @@ -10018,9 +10206,15 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" @@ -10036,9 +10230,15 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" @@ -10054,9 +10254,15 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" @@ -10072,9 +10278,15 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" @@ -10090,9 +10302,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" @@ -10104,23 +10316,10 @@ dependencies = [ ] [[package]] -name = "winreg" -version = "0.50.0" +name = "wit-bindgen" +version = "0.46.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.3", -] +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" @@ -10183,12 +10382,12 @@ dependencies = [ [[package]] name = "xattr" -version = "1.5.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af3a19837351dc82ba89f8a125e22a3c475f05aba604acc023d62b2739ae2909" +checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" dependencies = [ "libc", - "rustix 1.0.8", + "rustix 1.1.2", ] [[package]] @@ -10220,16 +10419,16 @@ dependencies = [ [[package]] name = "yasi" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d8075d6829add5913054d2de87aec55a786599427d93ef3504a0b7f515a418" +checksum = "7b4752072f7740cdfce9c61da81760fbda4182cfe4fff6f7a21fb6470b3f20a0" dependencies = [ - "ahash 0.8.12", "hashbrown 0.13.2", "lazy_static", "serde", "tinyvec", "ts-rs", + "xxhash-rust", ] [[package]] @@ -10267,9 +10466,9 @@ dependencies = [ [[package]] name = "zbus" -version = "5.10.0" +version = "5.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a073be99ace1adc48af593701c8015cd9817df372e14a1a6b0ee8f8bf043be" +checksum = "2d07e46d035fb8e375b2ce63ba4e4ff90a7f73cf2ffb0138b29e1158d2eaadf7" dependencies = [ "async-broadcast", "async-executor", @@ -10300,9 +10499,9 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "5.10.0" +version = "5.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e80cd713a45a49859dcb648053f63265f4f2851b6420d47a958e5697c68b131" +checksum = "57e797a9c847ed3ccc5b6254e8bcce056494b375b511b3d6edcec0aeb4defaca" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -10327,18 +10526,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", @@ -10368,9 +10567,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" dependencies = [ "zeroize_derive", ] @@ -10419,53 +10618,11 @@ dependencies = [ "syn 2.0.106", ] -[[package]] -name = "zip" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50" -dependencies = [ - "aes 0.8.4", - "arbitrary", - "bzip2", - "constant_time_eq", - "crc32fast", - "crossbeam-utils", - "deflate64", - "displaydoc", - "flate2", - "getrandom 0.3.3", - "hmac", - "indexmap 2.11.0", - "lzma-rs", - "memchr", - "pbkdf2", - "sha1", - "thiserror 2.0.16", - "time", - "xz2", - "zeroize", - "zopfli", - "zstd", -] - [[package]] name = "zlib-rs" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626bd9fa9734751fc50d6060752170984d7053f5a39061f524cda68023d4db8a" - -[[package]] -name = "zopfli" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfc5ee405f504cd4984ecc6f14d02d55cfda60fa4b689434ef4102aae150cd7" -dependencies = [ - "bumpalo", - "crc32fast", - "log", - "simd-adler32", -] +checksum = "2f06ae92f42f5e5c42443fd094f245eb656abf56dd7cce9b8b263236565e00f2" [[package]] name = "zstd" @@ -10487,9 +10644,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.15+zstd.1.5.7" +version = "2.0.16+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" dependencies = [ "cc", "pkg-config", diff --git a/core/models/Cargo.toml b/core/models/Cargo.toml index b9d9cf8d5..635ce8da3 100644 --- a/core/models/Cargo.toml +++ b/core/models/Cargo.toml @@ -5,14 +5,18 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[features] +arti = ["arti-client"] + [dependencies] -arti-client = { version = "0.33", default-features = false, git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" } +arti-client = { version = "0.33", default-features = false, git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit", optional = true } axum = "0.8.4" base64 = "0.22.1" color-eyre = "0.6.2" ed25519-dalek = { version = "2.0.0", features = ["serde"] } gpt = "4.1.0" lazy_static = "1.4" +lettre = { version = "0.11", default-features = false } mbrman = "0.6.0" exver = { version = "0.2.0", git = "https://github.com/Start9Labs/exver-rs.git", features = [ "serde", @@ -34,6 +38,7 @@ ssh-key = "0.6.2" ts-rs = "9" thiserror = "2.0" tokio = { version = "1", features = ["full"] } +torut = "0.2.1" tracing = "0.1.39" typeid = "1" yasi = { version = "0.1.6", features = ["serde", "ts-rs"] } diff --git a/core/models/src/errors.rs b/core/models/src/errors.rs index 30ee64514..826da282b 100644 --- a/core/models/src/errors.rs +++ b/core/models/src/errors.rs @@ -94,6 +94,7 @@ pub enum ErrorKind { DBus = 75, InstallFailed = 76, UpdateFailed = 77, + Smtp = 78, } impl ErrorKind { pub fn as_str(&self) -> &'static str { @@ -176,6 +177,7 @@ impl ErrorKind { DBus => "DBus Error", InstallFailed => "Install Failed", UpdateFailed => "Update Failed", + Smtp => "SMTP Error", } } } @@ -347,11 +349,17 @@ impl From for Error { Error::new(e, kind) } } +#[cfg(feature = "arti")] impl From for Error { fn from(e: arti_client::Error) -> Self { Error::new(e, ErrorKind::Tor) } } +impl From for Error { + fn from(e: torut::control::ConnError) -> Self { + Error::new(e, ErrorKind::Tor) + } +} impl From for Error { fn from(e: zbus::Error) -> Self { Error::new(e, ErrorKind::DBus) @@ -362,6 +370,21 @@ impl From for Error { Error::new(e, ErrorKind::OpenSsl) } } +impl From for Error { + fn from(e: lettre::error::Error) -> Self { + Error::new(e, ErrorKind::Smtp) + } +} +impl From for Error { + fn from(e: lettre::transport::smtp::Error) -> Self { + Error::new(e, ErrorKind::Smtp) + } +} +impl From for Error { + fn from(e: lettre::address::AddressError) -> Self { + Error::new(e, ErrorKind::Smtp) + } +} impl From for Error { fn from(value: patch_db::value::Error) -> Self { match value.kind { diff --git a/core/startos/Cargo.toml b/core/startos/Cargo.toml index 8ecc317f9..fa2bc7c0a 100644 --- a/core/startos/Cargo.toml +++ b/core/startos/Cargo.toml @@ -14,7 +14,7 @@ keywords = [ name = "start-os" readme = "README.md" repository = "https://github.com/Start9Labs/start-os" -version = "0.4.0-alpha.11" # VERSION_BUMP +version = "0.4.0-alpha.12" # VERSION_BUMP license = "MIT" [lib] @@ -42,16 +42,28 @@ name = "tunnelbox" path = "src/main.rs" [features] +arti = [ + "arti-client", + "tor-rtcompat", + "tor-keymgr", + "tor-proto", + "tor-hscrypto", + "tor-llcrypto", + "tor-cell", + "tor-hsservice", + "safelog", + "models/arti", +] cli = ["cli-startd", "cli-registry", "cli-tunnel"] cli-container = ["procfs", "pty-process"] cli-registry = [] cli-startd = [] cli-tunnel = [] default = ["cli", "startd", "registry", "cli-container", "tunnel"] -dev = ["backtrace-on-stack-overflow"] +dev = [] docker = [] registry = [] -startd = ["mail-send"] +startd = [] test = [] tunnel = [] console = ["console-subscriber", "tokio/tracing"] @@ -67,7 +79,7 @@ arti-client = { version = "0.33", features = [ "ephemeral-keystore", "onion-service-client", "onion-service-service", -], default-features = false, git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" } +], default-features = false, git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit", optional = true } aes = { version = "0.7.5", features = ["ctr"] } async-acme = { version = "0.6.0", git = "https://github.com/dr-bonez/async-acme.git", features = [ "use_rustls", @@ -98,6 +110,7 @@ console-subscriber = { version = "0.4.1", optional = true } const_format = "0.2.34" cookie = "0.18.0" cookie_store = "0.21.0" +curve25519-dalek = "4.1.3" der = { version = "0.7.9", features = ["derive", "pem"] } digest = "0.10.7" divrem = "1.0.0" @@ -109,6 +122,7 @@ ed25519-dalek = { version = "2.2.0", features = [ "rand_core", "digest", "pkcs8", + "hazmat", ] } ed25519-dalek-v1 = { package = "ed25519-dalek", version = "1" } exver = { version = "0.2.0", git = "https://github.com/Start9Labs/exver-rs.git", features = [ @@ -156,6 +170,15 @@ jsonpath_lib = { git = "https://github.com/Start9Labs/jsonpath.git" } lazy_async_pool = "0.3.3" lazy_format = "2.0" lazy_static = "1.4.0" +lettre = { version = "0.11.18", default-features = false, features = [ + "smtp-transport", + "pool", + "hostname", + "builder", + "tokio1-rustls", + "rustls-platform-verifier", + "aws-lc-rs", +] } libc = "0.2.149" log = "0.4.20" mio = "1" @@ -199,7 +222,7 @@ rpassword = "7.2.0" rpc-toolkit = { git = "https://github.com/Start9Labs/rpc-toolkit.git", branch = "master" } rust-argon2 = "2.0.0" rustyline-async = "0.4.1" -safelog = { version = "0.4.8", git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" } +safelog = { version = "0.4.8", git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit", optional = true } semver = { version = "1.0.20", features = ["serde"] } serde = { version = "1.0", features = ["derive", "rc"] } serde_cbor = { package = "ciborium", version = "0.2.1" } @@ -214,7 +237,7 @@ shell-words = "1" signal-hook = "0.3.17" simple-logging = "2.0.2" socket2 = { version = "0.6.0", features = ["all"] } -socks5-impl = { version = "0.7.2", features = ["server"] } +socks5-impl = { version = "0.7.2", features = ["server", "client"] } sqlx = { version = "0.8.6", features = [ "runtime-tokio-rustls", "postgres", @@ -231,22 +254,23 @@ tokio-stream = { version = "0.1.14", features = ["io-util", "sync", "net"] } tokio-tar = { git = "https://github.com/dr-bonez/tokio-tar.git" } tokio-tungstenite = { version = "0.26.2", features = ["native-tls", "url"] } tokio-util = { version = "0.7.9", features = ["io"] } -tor-cell = { version = "0.33", git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" } +tor-cell = { version = "0.33", git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit", optional = true } tor-hscrypto = { version = "0.33", features = [ "full", -], git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" } -tor-hsservice = { version = "0.33", git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" } +], git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit", optional = true } +tor-hsservice = { version = "0.33", git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit", optional = true } tor-keymgr = { version = "0.33", features = [ "ephemeral-keystore", -], git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" } +], git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit", optional = true } tor-llcrypto = { version = "0.33", features = [ "full", -], git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" } -tor-proto = { version = "0.33", git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" } +], git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit", optional = true } +tor-proto = { version = "0.33", git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit", optional = true } tor-rtcompat = { version = "0.33", features = [ "tokio", "rustls", -], git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" } +], git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit", optional = true } +torut = "0.2.1" tower-service = "0.3.3" tracing = "0.1.39" tracing-error = "0.2.0" @@ -259,12 +283,9 @@ unix-named-pipe = "0.2.0" url = { version = "2.4.1", features = ["serde"] } urlencoding = "2.1.3" uuid = { version = "1.4.1", features = ["v4"] } -x25519-dalek = "2.0.1" +x25519-dalek = { version = "2.0.1", features = ["static_secrets"] } zbus = "5.1.1" zeroize = "1.6.0" -mail-send = { git = "https://github.com/dr-bonez/mail-send.git", branch = "main", optional = true } -rustls = "0.23.20" -rustls-pki-types = { version = "1.10.1", features = ["alloc"] } [profile.test] opt-level = 3 diff --git a/core/startos/src/disk/mount/filesystem/idmapped.rs b/core/startos/src/disk/mount/filesystem/idmapped.rs index b7393a722..093575924 100644 --- a/core/startos/src/disk/mount/filesystem/idmapped.rs +++ b/core/startos/src/disk/mount/filesystem/idmapped.rs @@ -80,23 +80,6 @@ impl FileSystem for IdMapped { } Ok(()) } - async fn mount + Send>( - &self, - mountpoint: P, - mount_type: MountType, - ) -> Result<(), Error> { - self.pre_mount(mountpoint.as_ref()).await?; - Command::new("mount.next") - .args( - default_mount_command(self, mountpoint, mount_type) - .await? - .get_args(), - ) - .invoke(ErrorKind::Filesystem) - .await?; - - Ok(()) - } async fn source_hash( &self, ) -> Result::OutputSize>, Error> { diff --git a/core/startos/src/net/dns.rs b/core/startos/src/net/dns.rs index 844d41764..f2d22de09 100644 --- a/core/startos/src/net/dns.rs +++ b/core/startos/src/net/dns.rs @@ -33,7 +33,7 @@ use serde::{Deserialize, Serialize}; use tokio::net::{TcpListener, UdpSocket}; use tracing::instrument; -use crate::context::RpcContext; +use crate::context::{CliContext, RpcContext}; use crate::db::model::public::NetworkInterfaceInfo; use crate::db::model::Database; use crate::net::gateway::NetworkInterfaceWatcher; @@ -66,7 +66,36 @@ pub fn dns_api() -> ParentHandler { "set-static", from_fn_async(set_static_dns) .no_display() - .with_about("Set static DNS servers"), + .with_about("Set static DNS servers") + .with_call_remote::(), + ) + .subcommand( + "dump-table", + from_fn_async(dump_table) + .with_display_serializable() + .with_custom_display_fn(|HandlerArgs { params, .. }, res| { + use prettytable::*; + + if let Some(format) = params.format { + return display_serializable(format, res); + } + + let mut table = Table::new(); + table.add_row(row![bc => "FQDN", "DESTINATION"]); + for (hostname, destination) in res { + if let Some(ip) = destination { + table.add_row(row![hostname, ip]); + } else { + table.add_row(row![hostname, "SELF"]); + } + } + + table.print_tty(false)?; + + Ok(()) + }) + .with_about("Dump address resolution table") + .with_call_remote::(), ) } @@ -142,6 +171,38 @@ pub async fn set_static_dns( .result } +pub async fn dump_table( + ctx: RpcContext, +) -> Result>, Error> { + Ok(ctx + .net_controller + .dns + .resolve + .upgrade() + .or_not_found("DnsController")? + .peek(|map| { + map.private_domains + .iter() + .map(|(d, _)| (d.clone(), None)) + .chain(map.services.iter().filter_map(|(svc, ip)| { + ip.iter() + .find(|(_, rc)| rc.strong_count() > 0) + .map(|(ip, _)| { + ( + svc.as_ref().map_or( + InternedString::from_static("startos"), + |svc| { + InternedString::from_display(&lazy_format!("{svc}.startos")) + }, + ), + Some(IpAddr::V4(*ip)), + ) + }) + })) + .collect() + })) +} + #[derive(Default)] struct ResolveMap { private_domains: BTreeMap>, @@ -222,9 +283,9 @@ impl DnsClient { }); loop { if let Err::<(), Error>(e) = async { - let mut static_changed = db + let mut dns_changed = db .subscribe( - "/public/serverInfo/network/dns/staticServers" + "/public/serverInfo/network/dns" .parse::() .with_kind(ErrorKind::Database)?, ) @@ -275,7 +336,7 @@ impl DnsClient { Client::new(stream, sender, None) .await .with_kind(ErrorKind::Network)?; - bg.insert(*addr, bg_thread.boxed()); + bg.insert(*addr, bg_thread.fuse().boxed()); client }; new.push((*addr, client)); @@ -286,7 +347,7 @@ impl DnsClient { client.replace(new); } futures::future::select( - static_changed.recv().boxed(), + dns_changed.recv().boxed(), futures::future::join( futures::future::join_all(bg.values_mut()), futures::future::pending::<()>(), @@ -333,10 +394,20 @@ struct Resolver { resolve: Arc>, } impl Resolver { - fn resolve(&self, name: &Name, src: IpAddr) -> Option> { + fn resolve(&self, name: &Name, mut src: IpAddr) -> Option> { if name.zone_of(&*LOCALHOST) { return Some(vec![Ipv4Addr::LOCALHOST.into(), Ipv6Addr::LOCALHOST.into()]); } + src = match src { + IpAddr::V6(v6) => { + if let Some(v4) = v6.to_ipv4_mapped() { + IpAddr::V4(v4) + } else { + IpAddr::V6(v6) + } + } + a => a, + }; self.resolve.peek(|r| { if r.private_domains .get(&*name.to_lowercase().to_utf8().trim_end_matches('.')) @@ -344,8 +415,11 @@ impl Resolver { { if let Some(res) = self.net_iface.peek(|i| { i.values() - .chain([NetworkInterfaceInfo::lxc_bridge().1]) - .flat_map(|i| i.ip_info.as_ref()) + .chain([ + NetworkInterfaceInfo::loopback().1, + NetworkInterfaceInfo::lxc_bridge().1, + ]) + .filter_map(|i| i.ip_info.as_ref()) .find(|i| i.subnets.iter().any(|s| s.contains(&src))) .map(|ip_info| { let mut res = ip_info.subnets.iter().collect::>(); @@ -354,6 +428,8 @@ impl Resolver { }) }) { return Some(res); + } else { + tracing::warn!("Could not determine source interface of {src}"); } } if STARTOS.zone_of(name) || EMBASSY.zone_of(name) { diff --git a/core/startos/src/net/host/address.rs b/core/startos/src/net/host/address.rs index 393936724..c09500601 100644 --- a/core/startos/src/net/host/address.rs +++ b/core/startos/src/net/host/address.rs @@ -357,15 +357,7 @@ pub async fn add_onion( OnionParams { onion }: OnionParams, inheritance: Kind::Inheritance, ) -> Result<(), Error> { - let onion = onion - .strip_suffix(".onion") - .ok_or_else(|| { - Error::new( - eyre!("onion hostname must end in .onion"), - ErrorKind::InvalidOnionAddress, - ) - })? - .parse::()?; + let onion = onion.parse::()?; ctx.db .mutate(|db| { db.as_private().as_key_store().as_onion().get_key(&onion)?; @@ -388,15 +380,7 @@ pub async fn remove_onion( OnionParams { onion }: OnionParams, inheritance: Kind::Inheritance, ) -> Result<(), Error> { - let onion = onion - .strip_suffix(".onion") - .ok_or_else(|| { - Error::new( - eyre!("onion hostname must end in .onion"), - ErrorKind::InvalidOnionAddress, - ) - })? - .parse::()?; + let onion = onion.parse::()?; ctx.db .mutate(|db| { Kind::host_for(&inheritance, db)? diff --git a/core/startos/src/net/net_controller.rs b/core/startos/src/net/net_controller.rs index 2f3793482..55333100a 100644 --- a/core/startos/src/net/net_controller.rs +++ b/core/startos/src/net/net_controller.rs @@ -688,7 +688,7 @@ impl NetServiceData { .collect::>(); for onion in all { let mut prev = binds.tor.remove(&onion); - if let Some((key, tor_binds)) = tor.remove(&onion) { + if let Some((key, tor_binds)) = tor.remove(&onion).filter(|(_, b)| !b.is_empty()) { prev = prev.filter(|(b, _)| b == &tor_binds); binds.tor.insert( onion, diff --git a/core/startos/src/net/tor.rs b/core/startos/src/net/tor/arti.rs similarity index 99% rename from core/startos/src/net/tor.rs rename to core/startos/src/net/tor/arti.rs index 2cb18e45b..775210395 100644 --- a/core/startos/src/net/tor.rs +++ b/core/startos/src/net/tor/arti.rs @@ -6,7 +6,7 @@ use std::sync::{Arc, Weak}; use std::time::{Duration, Instant}; use arti_client::config::onion_service::OnionServiceConfigBuilder; -use arti_client::{DataStream, TorClient, TorClientConfig}; +use arti_client::{TorClient, TorClientConfig}; use base64::Engine; use clap::Parser; use color_eyre::eyre::eyre; @@ -191,8 +191,7 @@ impl Model { Ok(key) } pub fn insert_key(&mut self, key: &TorSecretKey) -> Result<(), Error> { - self.insert(&key.onion_address(), &key)?; - Ok(()) + self.insert(&key.onion_address(), &key) } pub fn get_key(&self, address: &OnionAddress) -> Result { self.as_idx(address) @@ -862,11 +861,11 @@ impl OnionService { }))) } - pub fn proxy_all>>( + pub async fn proxy_all>>( &self, bindings: impl IntoIterator, - ) -> Rcs { - self.0.bindings.mutate(|b| { + ) -> Result { + Ok(self.0.bindings.mutate(|b| { bindings .into_iter() .map(|(port, target)| { @@ -880,7 +879,7 @@ impl OnionService { } }) .collect() - }) + })) } pub fn gc(&self) -> bool { diff --git a/core/startos/src/net/tor/ctor.rs b/core/startos/src/net/tor/ctor.rs new file mode 100644 index 000000000..18f987cb8 --- /dev/null +++ b/core/startos/src/net/tor/ctor.rs @@ -0,0 +1,1034 @@ +use std::collections::{BTreeMap, BTreeSet}; +use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; +use std::str::FromStr; +use std::sync::atomic::AtomicBool; +use std::sync::{Arc, Weak}; +use std::time::Duration; + +use base64::Engine; +use clap::Parser; +use color_eyre::eyre::eyre; +use futures::future::BoxFuture; +use futures::{FutureExt, TryFutureExt, TryStreamExt}; +use helpers::NonDetachingJoinHandle; +use imbl::OrdMap; +use imbl_value::InternedString; +use lazy_static::lazy_static; +use regex::Regex; +use rpc_toolkit::{from_fn_async, Context, Empty, HandlerExt, ParentHandler}; +use serde::{Deserialize, Serialize}; +use tokio::net::TcpStream; +use tokio::process::Command; +use tokio::sync::{mpsc, oneshot}; +use tokio::time::Instant; +use torut::control::{AsyncEvent, AuthenticatedConn, ConnError}; +use torut::onion::{OnionAddressV3, TorSecretKeyV3}; +use tracing::instrument; +use ts_rs::TS; + +use crate::context::{CliContext, RpcContext}; +use crate::logs::{journalctl, LogSource, LogsParams}; +use crate::prelude::*; +use crate::util::collections::ordmap_retain; +use crate::util::io::{write_file_atomic, ReadWriter}; +use crate::util::serde::{ + deserialize_from_str, display_serializable, serialize_display, Base64, HandlerExtSerde, + WithIoFormat, BASE64, +}; +use crate::util::sync::Watch; +use crate::util::Invoke; + +pub const SYSTEMD_UNIT: &str = "tor@default"; +const STARTING_HEALTH_TIMEOUT: u64 = 120; // 2min + +const TOR_CONTROL: SocketAddr = + SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 1, 1), 9051)); +const TOR_SOCKS: SocketAddr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 1, 1), 9050)); + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct OnionAddress(OnionAddressV3); +impl std::fmt::Display for OnionAddress { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} +impl FromStr for OnionAddress { + type Err = Error; + fn from_str(s: &str) -> Result { + Ok(Self( + s.strip_suffix(".onion") + .unwrap_or(s) + .parse::() + .with_kind(ErrorKind::Tor)?, + )) + } +} +impl Serialize for OnionAddress { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serialize_display(self, serializer) + } +} +impl<'de> Deserialize<'de> for OnionAddress { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + deserialize_from_str(deserializer) + } +} +impl Ord for OnionAddress { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.0.get_raw_bytes().cmp(&other.0.get_raw_bytes()) + } +} +impl PartialOrd for OnionAddress { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct TorSecretKey(pub TorSecretKeyV3); +impl TorSecretKey { + pub fn onion_address(&self) -> OnionAddress { + OnionAddress(self.0.public().get_onion_address()) + } + pub fn from_bytes(bytes: [u8; 64]) -> Result { + Ok(Self(TorSecretKeyV3::from(bytes))) + } + pub fn generate() -> Self { + Self(TorSecretKeyV3::generate()) + } + pub fn is_valid(&self) -> bool { + let bytes = self.0.as_bytes()[..32].try_into().unwrap(); + curve25519_dalek::scalar::clamp_integer(bytes) == bytes + } +} +impl std::fmt::Display for TorSecretKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", BASE64.encode(self.0.as_bytes())) + } +} +impl FromStr for TorSecretKey { + type Err = Error; + fn from_str(s: &str) -> Result { + Self::from_bytes(Base64::<[u8; 64]>::from_str(s)?.0) + } +} +impl Serialize for TorSecretKey { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serialize_display(self, serializer) + } +} +impl<'de> Deserialize<'de> for TorSecretKey { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + deserialize_from_str(deserializer) + } +} + +#[test] +fn test_generated_is_valid() { + for _ in 0..100 { + assert!(TorSecretKey::generate().is_valid()); + } +} + +#[test] +fn test_tor_key() { + // let key = crate::util::crypto::ed25519_expand_key( + // &hex::decode("c4b1a617bfdbcfb3f31e98c95542ce61718100e81cc6766eeebaa0dab42f0a93") + // .unwrap() + // .try_into() + // .unwrap(), + // ); + let key = + "4FpKpT4GZeEkUvH32AWMsndW+EG3XH46EmSFTh286G4AfG2U/Cc7y7L6k1dW5bl996QGDwe8gnaglq2hR2aD2w" + .parse::() + .unwrap(); + assert_eq!( + InternedString::from_display(&key.onion_address()), + InternedString::from("ja24lucrzgcusm72r2kmiujaa2g6b5o2w4wrwt5crfrhaz2qek5ozhqd.onion") + ); + eprintln!("{:?}", key.0.as_bytes()); + dbg!(key.to_string()); + dbg!(key.0.as_bytes()[0] & 0b111); + dbg!(key.onion_address()); + assert!(key.is_valid()); +} + +#[derive(Default, Deserialize, Serialize)] +pub struct OnionStore(BTreeMap); +impl Map for OnionStore { + type Key = OnionAddress; + type Value = TorSecretKey; + fn key_str(key: &Self::Key) -> Result, Error> { + Self::key_string(key) + } + fn key_string(key: &Self::Key) -> Result { + Ok(InternedString::from_display(key)) + } +} +impl OnionStore { + pub fn new() -> Self { + Self::default() + } + pub fn insert(&mut self, key: TorSecretKey) { + self.0.insert(key.onion_address(), key); + } +} +impl Model { + pub fn new_key(&mut self) -> Result { + let key = TorSecretKey::generate(); + self.insert_key(&key)?; + Ok(key) + } + pub fn insert_key(&mut self, key: &TorSecretKey) -> Result<(), Error> { + self.insert(&key.onion_address(), &key).map(|_| ()) + } + pub fn get_key(&self, address: &OnionAddress) -> Result { + self.as_idx(address) + .or_not_found(lazy_format!("private key for {address}"))? + .de() + } +} +impl std::fmt::Debug for OnionStore { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + struct OnionStoreMap<'a>(&'a BTreeMap); + impl<'a> std::fmt::Debug for OnionStoreMap<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + #[derive(Debug)] + struct KeyFor(#[allow(unused)] OnionAddress); + let mut map = f.debug_map(); + for (k, v) in self.0 { + map.key(k); + map.value(&KeyFor(v.onion_address())); + } + map.finish() + } + } + f.debug_tuple("OnionStore") + .field(&OnionStoreMap(&self.0)) + .finish() + } +} + +enum ErrorLogSeverity { + Fatal { wipe_state: bool }, + Unknown { wipe_state: bool }, +} + +lazy_static! { + static ref LOG_REGEXES: Vec<(Regex, ErrorLogSeverity)> = vec![( + Regex::new("This could indicate a route manipulation attack, network overload, bad local network connectivity, or a bug\\.").unwrap(), + ErrorLogSeverity::Unknown { wipe_state: true } + ),( + Regex::new("died due to an invalid selected path").unwrap(), + ErrorLogSeverity::Fatal { wipe_state: false } + ),( + Regex::new("Tor has not observed any network activity for the past").unwrap(), + ErrorLogSeverity::Unknown { wipe_state: false } + )]; + static ref PROGRESS_REGEX: Regex = Regex::new("PROGRESS=([0-9]+)").unwrap(); +} + +pub fn tor_api() -> ParentHandler { + ParentHandler::new() + .subcommand( + "list-services", + from_fn_async(list_services) + .with_display_serializable() + .with_custom_display_fn(|handle, result| display_services(handle.params, result)) + .with_about("Display Tor V3 Onion Addresses") + .with_call_remote::(), + ) + .subcommand("logs", logs().with_about("Display Tor logs")) + .subcommand( + "logs", + from_fn_async(crate::logs::cli_logs::) + .no_display() + .with_about("Display Tor logs"), + ) + .subcommand( + "reset", + from_fn_async(reset) + .no_display() + .with_about("Reset Tor daemon") + .with_call_remote::(), + ) + .subcommand( + "key", + key::().with_about("Manage the onion service key store"), + ) +} + +pub fn key() -> ParentHandler { + ParentHandler::new() + .subcommand( + "generate", + from_fn_async(generate_key) + .with_about("Generate an onion service key and add it to the key store") + .with_call_remote::(), + ) + .subcommand( + "add", + from_fn_async(add_key) + .with_about("Add an onion service key to the key store") + .with_call_remote::(), + ) + .subcommand( + "list", + from_fn_async(list_keys) + .with_custom_display_fn(|_, res| { + for addr in res { + println!("{addr}"); + } + Ok(()) + }) + .with_about("List onion services with keys in the key store") + .with_call_remote::(), + ) +} + +pub async fn generate_key(ctx: RpcContext) -> Result { + ctx.db + .mutate(|db| { + Ok(db + .as_private_mut() + .as_key_store_mut() + .as_onion_mut() + .new_key()? + .onion_address()) + }) + .await + .result +} + +#[derive(Deserialize, Serialize, Parser)] +pub struct AddKeyParams { + pub key: Base64<[u8; 64]>, +} + +pub async fn add_key( + ctx: RpcContext, + AddKeyParams { key }: AddKeyParams, +) -> Result { + let key = TorSecretKey::from_bytes(key.0)?; + ctx.db + .mutate(|db| { + db.as_private_mut() + .as_key_store_mut() + .as_onion_mut() + .insert_key(&key) + }) + .await + .result?; + Ok(key.onion_address()) +} + +pub async fn list_keys(ctx: RpcContext) -> Result, Error> { + ctx.db + .peek() + .await + .into_private() + .into_key_store() + .into_onion() + .keys() +} + +#[derive(Deserialize, Serialize, Parser, TS)] +#[serde(rename_all = "camelCase")] +#[command(rename_all = "kebab-case")] +pub struct ResetParams { + #[arg(name = "wipe-state", short = 'w', long = "wipe-state")] + wipe_state: bool, + reason: String, +} + +pub async fn reset( + ctx: RpcContext, + ResetParams { reason, wipe_state }: ResetParams, +) -> Result<(), Error> { + ctx.net_controller + .tor + .reset(wipe_state, Error::new(eyre!("{reason}"), ErrorKind::Tor)) + .await +} + +pub fn display_services( + params: WithIoFormat, + services: Vec, +) -> Result<(), Error> { + use prettytable::*; + + if let Some(format) = params.format { + return display_serializable(format, services); + } + + let mut table = Table::new(); + for service in services { + let row = row![&service.to_string()]; + table.add_row(row); + } + table.print_tty(false)?; + Ok(()) +} + +pub async fn list_services(ctx: RpcContext, _: Empty) -> Result, Error> { + ctx.net_controller.tor.list_services().await +} + +pub fn logs() -> ParentHandler { + crate::logs::logs::(|_: &RpcContext, _| async { + Ok(LogSource::Unit(SYSTEMD_UNIT)) + }) +} + +fn event_handler(_event: AsyncEvent<'static>) -> BoxFuture<'static, Result<(), ConnError>> { + async move { Ok(()) }.boxed() +} + +#[derive(Clone)] +pub struct TorController(Arc); +impl TorController { + pub fn new() -> Result { + Ok(TorController(Arc::new(TorControl::new( + TOR_CONTROL, + TOR_SOCKS, + )))) + } + + pub fn service(&self, key: TorSecretKey) -> Result { + Ok(TorService { + services: self.0.services.clone(), + key, + }) + } + + pub async fn gc(&self, addr: Option) -> Result<(), Error> { + self.0.services.send_if_modified(|services| { + let mut changed = false; + let mut gc = |bindings: &mut OrdMap>>| { + ordmap_retain(bindings, |_, targets| { + let start_len = targets.len(); + targets.retain(|_, rc| rc.strong_count() > 0); + changed |= start_len != targets.len(); + !targets.is_empty() + }); + if bindings.is_empty() { + changed = true; + false + } else { + true + } + }; + if let Some(addr) = addr { + if !if let Some((_, bindings, needs_sync)) = services.get_mut(&addr) { + let keep = gc(bindings); + if !keep { + *needs_sync = Some(SyncState::Remove); + } + keep + } else { + true + } { + services.remove(&addr); + } + } else { + services.retain(|_, (_, bindings, _)| gc(bindings)); + } + changed + }); + Ok(()) + } + + pub async fn reset(&self, wipe_state: bool, context: Error) -> Result<(), Error> { + self.0 + .send + .send(TorCommand::Reset { + wipe_state, + context, + }) + .ok() + .ok_or_else(|| Error::new(eyre!("TorControl died"), ErrorKind::Tor)) + } + + pub async fn list_services(&self) -> Result, Error> { + let (reply, res) = oneshot::channel(); + self.0 + .send + .send(TorCommand::GetInfo { + query: "onions/current".into(), + reply, + }) + .ok() + .ok_or_else(|| Error::new(eyre!("TorControl died"), ErrorKind::Tor))?; + res.await + .ok() + .ok_or_else(|| Error::new(eyre!("TorControl died"), ErrorKind::Tor))?? + .lines() + .map(|l| l.trim()) + .filter(|l| !l.is_empty()) + .map(|l| l.parse::().with_kind(ErrorKind::Tor)) + .collect() + } + + pub async fn connect_onion( + &self, + addr: &OnionAddress, + port: u16, + ) -> Result, Error> { + if let Some(target) = self.0.services.peek(|s| { + s.get(addr).and_then(|(_, bindings, _)| { + bindings.get(&port).and_then(|b| { + b.iter() + .find(|(_, rc)| rc.strong_count() > 0) + .map(|(a, _)| *a) + }) + }) + }) { + tracing::debug!("Resolving {addr} internally to {target}"); + Ok(Box::new( + TcpStream::connect(target) + .await + .with_kind(ErrorKind::Network)?, + )) + } else { + let mut stream = TcpStream::connect(TOR_SOCKS) + .await + .with_kind(ErrorKind::Tor)?; + socks5_impl::client::connect(&mut stream, (addr.to_string(), port), None) + .await + .with_kind(ErrorKind::Tor)?; + Ok(Box::new(stream)) + } + } +} + +#[derive(Clone, Copy, PartialEq, Eq)] +enum SyncState { + Add, + Update, + Remove, +} + +pub struct TorService { + services: Watch< + BTreeMap< + OnionAddress, + ( + TorSecretKey, + OrdMap>>, + Option, + ), + >, + >, + key: TorSecretKey, +} + +impl TorService { + pub fn proxy_all>>( + &self, + bindings: impl IntoIterator, + ) -> Rcs { + self.services.send_modify(|services| { + let (_, entry, needs_sync) = services + .entry(self.key.onion_address()) + .or_insert_with(|| (self.key.clone(), OrdMap::new(), Some(SyncState::Add))); + let rcs = bindings + .into_iter() + .map(|(external, target)| { + let binding = entry.entry(external).or_default(); + let target = binding.entry(target).or_default(); + let rc = if let Some(rc) = Weak::upgrade(&*target) { + rc + } else { + if needs_sync.is_none() { + *needs_sync = Some(SyncState::Update); + } + Arc::new(()) + }; + *target = Arc::downgrade(&rc); + rc + }) + .collect(); + + rcs + }) + } +} + +type AuthenticatedConnection = AuthenticatedConn< + TcpStream, + Box) -> BoxFuture<'static, Result<(), ConnError>> + Send + Sync>, +>; + +enum TorCommand { + GetInfo { + query: String, + reply: oneshot::Sender>, + }, + Reset { + wipe_state: bool, + context: Error, + }, +} + +#[instrument(skip_all)] +async fn torctl( + tor_control: SocketAddr, + tor_socks: SocketAddr, + recv: &mut mpsc::UnboundedReceiver, + services: &mut Watch< + BTreeMap< + OnionAddress, + ( + TorSecretKey, + OrdMap>>, + Option, + ), + >, + >, + wipe_state: &AtomicBool, + health_timeout: &mut Duration, +) -> Result<(), Error> { + let bootstrap = async { + if Command::new("systemctl") + .arg("is-active") + .arg("--quiet") + .arg("tor") + .invoke(ErrorKind::Tor) + .await + .is_ok() + { + Command::new("systemctl") + .arg("stop") + .arg("tor") + .invoke(ErrorKind::Tor) + .await?; + for _ in 0..30 { + if TcpStream::connect(tor_control).await.is_err() { + break; + } + tokio::time::sleep(Duration::from_secs(1)).await; + } + if TcpStream::connect(tor_control).await.is_ok() { + return Err(Error::new( + eyre!("Tor is failing to shut down"), + ErrorKind::Tor, + )); + } + } + if wipe_state.load(std::sync::atomic::Ordering::SeqCst) { + tokio::fs::remove_dir_all("/var/lib/tor").await?; + wipe_state.store(false, std::sync::atomic::Ordering::SeqCst); + } + write_file_atomic( + "/etc/tor/torrc", + format!("SocksPort {TOR_SOCKS}\nControlPort {TOR_CONTROL}\nCookieAuthentication 1\n"), + ) + .await?; + tokio::fs::create_dir_all("/var/lib/tor").await?; + Command::new("chown") + .arg("-R") + .arg("debian-tor") + .arg("/var/lib/tor") + .invoke(ErrorKind::Filesystem) + .await?; + Command::new("systemctl") + .arg("start") + .arg("tor") + .invoke(ErrorKind::Tor) + .await?; + + let logs = journalctl( + LogSource::Unit(SYSTEMD_UNIT), + Some(0), + None, + Some("0"), + false, + true, + ) + .await?; + + let mut tcp_stream = None; + for _ in 0..60 { + if let Ok(conn) = TcpStream::connect(tor_control).await { + tcp_stream = Some(conn); + break; + } + tokio::time::sleep(Duration::from_secs(1)).await; + } + let tcp_stream = tcp_stream.ok_or_else(|| { + Error::new(eyre!("Timed out waiting for tor to start"), ErrorKind::Tor) + })?; + tracing::info!("Tor is started"); + + let mut conn = torut::control::UnauthenticatedConn::new(tcp_stream); + let auth = conn + .load_protocol_info() + .await? + .make_auth_data()? + .ok_or_else(|| eyre!("Cookie Auth Not Available")) + .with_kind(crate::ErrorKind::Tor)?; + conn.authenticate(&auth).await?; + let mut connection: AuthenticatedConnection = conn.into_authenticated().await; + connection.set_async_event_handler(Some(Box::new(|event| event_handler(event)))); + + let mut bootstrapped = false; + let mut last_increment = (String::new(), Instant::now()); + for _ in 0..300 { + match connection.get_info("status/bootstrap-phase").await { + Ok(a) => { + if a.contains("TAG=done") { + bootstrapped = true; + break; + } + if let Some(p) = PROGRESS_REGEX.captures(&a) { + if let Some(p) = p.get(1) { + if p.as_str() != &*last_increment.0 { + last_increment = (p.as_str().into(), Instant::now()); + } + } + } + } + Err(e) => { + let e = Error::from(e); + tracing::error!("{}", e); + tracing::debug!("{:?}", e); + } + } + if last_increment.1.elapsed() > Duration::from_secs(30) { + return Err(Error::new( + eyre!("Tor stuck bootstrapping at {}%", last_increment.0), + ErrorKind::Tor, + )); + } + tokio::time::sleep(Duration::from_secs(1)).await; + } + if !bootstrapped { + return Err(Error::new( + eyre!("Timed out waiting for tor to bootstrap"), + ErrorKind::Tor, + )); + } + Ok((connection, logs)) + }; + let pre_handler = async { + while let Some(command) = recv.recv().await { + match command { + TorCommand::GetInfo { reply, .. } => { + reply + .send(Err(Error::new( + eyre!("Tor has not finished bootstrapping..."), + ErrorKind::Tor, + ))) + .unwrap_or_default(); + } + TorCommand::Reset { + wipe_state: new_wipe_state, + context, + } => { + wipe_state.fetch_or(new_wipe_state, std::sync::atomic::Ordering::SeqCst); + return Err(context); + } + } + } + Ok(()) + }; + + let (mut connection, mut logs) = tokio::select! { + res = bootstrap => res?, + res = pre_handler => return res, + }; + + let hck_key = TorSecretKeyV3::generate(); + connection + .add_onion_v3( + &hck_key, + false, + false, + false, + None, + &mut [(80, SocketAddr::from(([127, 0, 0, 1], 80)))].iter(), + ) + .await?; + + let handler = async { + loop { + let recv = recv.recv(); + tokio::pin!(recv); + let mut changed = services.changed().boxed(); + + match futures::future::select(recv, &mut changed).await { + futures::future::Either::Left((Some(command), _)) => match command { + TorCommand::GetInfo { query, reply } => { + reply + .send(connection.get_info(&query).await.with_kind(ErrorKind::Tor)) + .unwrap_or_default(); + } + TorCommand::Reset { + wipe_state: new_wipe_state, + context, + } => { + wipe_state.fetch_or(new_wipe_state, std::sync::atomic::Ordering::SeqCst); + return Err(context); + } + }, + futures::future::Either::Left((None, _)) => break, + futures::future::Either::Right(_) => { + drop(changed); + let to_add = services.peek_and_mark_seen(|services| { + services + .iter() + .filter(|(_, (_, _, s))| s.is_some()) + .map(|(k, v)| (k.clone(), (*v).clone())) + .collect::>() + }); + + for (addr, (key, bindings, state)) in &to_add { + if matches!(state, Some(SyncState::Update) | Some(SyncState::Remove)) { + connection + .del_onion(&addr.0.get_address_without_dot_onion()) + .await + .with_kind(ErrorKind::Tor)?; + } + let bindings = bindings + .iter() + .filter_map(|(external, targets)| { + targets + .iter() + .find(|(_, rc)| rc.strong_count() > 0) + .map(|(target, _)| (*external, *target)) + }) + .collect::>(); + if !bindings.is_empty() { + connection + .add_onion_v3( + &key.0, + false, + false, + false, + None, + &mut bindings.iter(), + ) + .await?; + } + } + services.send_if_modified(|services| { + for (addr, (_, bindings_a, _)) in to_add { + if let Some((_, bindings_b, needs_sync)) = services.get_mut(&addr) { + if OrdMap::ptr_eq(&bindings_a, bindings_b) + || bindings_a.len() == bindings_b.len() + && bindings_a.iter().zip(bindings_b.iter()).all( + |((a_port, a), (b_port, b))| { + a_port == b_port + && a.len() == b.len() + && a.keys().zip(b.keys()).all(|(a, b)| a == b) + }, + ) + { + *needs_sync = None; + } else { + *needs_sync = Some(SyncState::Update); + } + } + } + false + }); + } + } + } + + Ok(()) + }; + let log_parser = async { + while let Some(log) = logs.try_next().await? { + for (regex, severity) in &*LOG_REGEXES { + if regex.is_match(&log.message) { + let (check, wipe_state) = match severity { + ErrorLogSeverity::Fatal { wipe_state } => (false, *wipe_state), + ErrorLogSeverity::Unknown { wipe_state } => (true, *wipe_state), + }; + let addr = hck_key.public().get_onion_address().to_string(); + if !check + || TcpStream::connect(tor_socks) + .map_err(|e| Error::new(e, ErrorKind::Tor)) + .and_then(|mut tor_socks| async move { + tokio::time::timeout( + Duration::from_secs(30), + socks5_impl::client::connect(&mut tor_socks, (addr, 80), None) + .map_err(|e| Error::new(e, ErrorKind::Tor)), + ) + .map_err(|e| Error::new(e, ErrorKind::Tor)) + .await? + }) + .await + .with_ctx(|_| (ErrorKind::Tor, "Tor is confirmed to be down")) + .log_err() + .is_some() + { + if wipe_state { + Command::new("systemctl") + .arg("stop") + .arg("tor") + .invoke(ErrorKind::Tor) + .await?; + tokio::fs::remove_dir_all("/var/lib/tor").await?; + } + return Err(Error::new(eyre!("{}", log.message), ErrorKind::Tor)); + } + } + } + } + Err(Error::new(eyre!("Log stream terminated"), ErrorKind::Tor)) + }; + let health_checker = async { + let mut last_success = Instant::now(); + loop { + tokio::time::sleep(Duration::from_secs(30)).await; + let addr = hck_key.public().get_onion_address().to_string(); + if TcpStream::connect(tor_socks) + .map_err(|e| Error::new(e, ErrorKind::Tor)) + .and_then(|mut tor_socks| async move { + tokio::time::timeout( + Duration::from_secs(30), + socks5_impl::client::connect(&mut tor_socks, (addr, 80), None) + .map_err(|e| Error::new(e, ErrorKind::Tor)), + ) + .map_err(|e| Error::new(e, ErrorKind::Tor)) + .await + }) + .await + .is_err() + { + if last_success.elapsed() > *health_timeout { + let err = Error::new(eyre!("Tor health check failed for longer than current timeout ({health_timeout:?})"), crate::ErrorKind::Tor); + *health_timeout *= 2; + wipe_state.store(true, std::sync::atomic::Ordering::SeqCst); + return Err(err); + } + } else { + last_success = Instant::now(); + } + } + }; + + tokio::select! { + res = handler => res?, + res = log_parser => res?, + res = health_checker => res?, + } + + Ok(()) +} + +struct TorControl { + _thread: NonDetachingJoinHandle<()>, + send: mpsc::UnboundedSender, + services: Watch< + BTreeMap< + OnionAddress, + ( + TorSecretKey, + OrdMap>>, + Option, + ), + >, + >, +} +impl TorControl { + pub fn new(tor_control: SocketAddr, tor_socks: SocketAddr) -> Self { + let (send, mut recv) = mpsc::unbounded_channel(); + let services = Watch::new(BTreeMap::new()); + let mut thread_services = services.clone(); + Self { + _thread: tokio::spawn(async move { + let wipe_state = AtomicBool::new(false); + let mut health_timeout = Duration::from_secs(STARTING_HEALTH_TIMEOUT); + while let Err(e) = torctl( + tor_control, + tor_socks, + &mut recv, + &mut thread_services, + &wipe_state, + &mut health_timeout, + ) + .await + { + tracing::error!("{e}: Restarting tor"); + tracing::debug!("{e:?}"); + } + tracing::info!("TorControl is shut down.") + }) + .into(), + send, + services, + } + } +} + +#[tokio::test] +#[ignore] +async fn test_connection() { + let mut conn = torut::control::UnauthenticatedConn::new( + TcpStream::connect(SocketAddr::from(([127, 0, 0, 1], 9051))) + .await + .unwrap(), + ); + let auth = conn + .load_protocol_info() + .await + .unwrap() + .make_auth_data() + .unwrap() + .ok_or_else(|| eyre!("Cookie Auth Not Available")) + .with_kind(crate::ErrorKind::Tor) + .unwrap(); + conn.authenticate(&auth).await.unwrap(); + let mut connection: AuthenticatedConn< + TcpStream, + fn(AsyncEvent<'static>) -> BoxFuture<'static, Result<(), ConnError>>, + > = conn.into_authenticated().await; + let tor_key = torut::onion::TorSecretKeyV3::generate(); + connection.get_conf("SocksPort").await.unwrap(); + connection + .add_onion_v3( + &tor_key, + false, + false, + false, + None, + &mut [(443_u16, SocketAddr::from(([127, 0, 0, 1], 8443)))].iter(), + ) + .await + .unwrap(); + connection + .del_onion( + &tor_key + .public() + .get_onion_address() + .get_address_without_dot_onion(), + ) + .await + .unwrap(); + connection + .add_onion_v3( + &tor_key, + false, + false, + false, + None, + &mut [(8443_u16, SocketAddr::from(([127, 0, 0, 1], 8443)))].iter(), + ) + .await + .unwrap(); +} diff --git a/core/startos/src/net/tor/mod.rs b/core/startos/src/net/tor/mod.rs new file mode 100644 index 000000000..06b57ae2a --- /dev/null +++ b/core/startos/src/net/tor/mod.rs @@ -0,0 +1,10 @@ +#[cfg(feature = "arti")] +mod arti; + +#[cfg(not(feature = "arti"))] +mod ctor; + +#[cfg(feature = "arti")] +pub use arti::{tor_api, OnionAddress, OnionStore, TorController, TorSecretKey}; +#[cfg(not(feature = "arti"))] +pub use ctor::{tor_api, OnionAddress, OnionStore, TorController, TorSecretKey}; diff --git a/core/startos/src/registry/context.rs b/core/startos/src/registry/context.rs index 35b19207c..0d50641f1 100644 --- a/core/startos/src/registry/context.rs +++ b/core/startos/src/registry/context.rs @@ -169,17 +169,23 @@ impl CallRemote for CliContext { let url = if let Some(url) = self.registry_url.clone() { url } else if self.registry_hostname.is_some() { - format!( + let mut url: Url = format!( "http://{}", self.registry_listen.unwrap_or(DEFAULT_REGISTRY_LISTEN) ) .parse() - .map_err(Error::from)? + .map_err(Error::from)?; + url.path_segments_mut() + .map_err(|_| Error::new(eyre!("cannot extend URL path"), ErrorKind::ParseUrl))? + .push("rpc") + .push("v0"); + url } else { return Err( Error::new(eyre!("`--registry` required"), ErrorKind::InvalidRequest).into(), ); }; + method = method.strip_prefix("registry.").unwrap_or(method); let sig_context = self .registry_hostname @@ -203,7 +209,7 @@ impl CallRemote for RpcContext { &self, mut method: &str, params: Value, - RegistryUrlParams { registry }: RegistryUrlParams, + RegistryUrlParams { mut registry }: RegistryUrlParams, ) -> Result { let mut headers = HeaderMap::new(); headers.insert( @@ -211,6 +217,12 @@ impl CallRemote for RpcContext { DeviceInfo::load(self).await?.to_header_value(), ); + registry + .path_segments_mut() + .map_err(|_| Error::new(eyre!("cannot extend URL path"), ErrorKind::ParseUrl))? + .push("rpc") + .push("v0"); + method = method.strip_prefix("registry.").unwrap_or(method); let sig_context = registry.host_str().map(InternedString::from); diff --git a/core/startos/src/system.rs b/core/startos/src/system.rs index 01b85066e..07a44da64 100644 --- a/core/startos/src/system.rs +++ b/core/startos/src/system.rs @@ -1,6 +1,5 @@ use std::collections::BTreeSet; use std::fmt; -use std::sync::Arc; use std::time::Duration; use chrono::Utc; @@ -10,8 +9,6 @@ use futures::{FutureExt, TryStreamExt}; use imbl::vector; use imbl_value::InternedString; use rpc_toolkit::{from_fn_async, Context, Empty, HandlerExt, ParentHandler}; -use rustls::RootCertStore; -use rustls_pki_types::CertificateDer; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use tokio::process::Command; use tokio::sync::broadcast::Receiver; @@ -498,7 +495,7 @@ pub struct MetricsFollowResponse { #[command(rename_all = "kebab-case")] pub struct MetricsFollowParams { #[ts(skip)] - #[serde(rename = "__Auth_session")] // from Auth middleware + #[serde(rename = "__auth_session")] // from Auth middleware session: Option, } @@ -1024,7 +1021,7 @@ pub struct TestSmtpParams { #[arg(long)] pub login: String, #[arg(long)] - pub password: Option, + pub password: String, } pub async fn test_smtp( _: RpcContext, @@ -1037,74 +1034,23 @@ pub async fn test_smtp( password, }: TestSmtpParams, ) -> Result<(), Error> { - #[cfg(feature = "mail-send")] - { - use mail_send::mail_builder::{self, MessageBuilder}; - use mail_send::SmtpClientBuilder; - use rustls_pki_types::pem::PemObject; + use lettre::message::header::ContentType; + use lettre::transport::smtp::authentication::Credentials; + use lettre::{AsyncSmtpTransport, AsyncTransport, Message, Tokio1Executor}; - let Some(pass_val) = password else { - return Err(Error::new( - eyre!("mail-send requires a password"), - ErrorKind::InvalidRequest, - )); - }; - - let mut root_cert_store = RootCertStore::empty(); - let pem = tokio::fs::read("/etc/ssl/certs/ca-certificates.crt").await?; - for cert in CertificateDer::pem_slice_iter(&pem) { - root_cert_store.add_parsable_certificates([cert.with_kind(ErrorKind::OpenSsl)?]); - } - - let cfg = Arc::new( - rustls::ClientConfig::builder_with_provider(Arc::new( - rustls::crypto::ring::default_provider(), - )) - .with_safe_default_protocol_versions()? - .with_root_certificates(root_cert_store) - .with_no_client_auth(), - ); - let client = SmtpClientBuilder::new_with_tls_config(server, port, cfg) - .implicit_tls(false) - .credentials((login.split("@").next().unwrap().to_owned(), pass_val)); - - fn parse_address<'a>(addr: &'a str) -> mail_builder::headers::address::Address<'a> { - if addr.find("<").map_or(false, |start| { - addr.find(">").map_or(false, |end| start < end) - }) { - addr.split_once("<") - .map(|(name, addr)| (name.trim(), addr.strip_suffix(">").unwrap_or(addr))) - .unwrap() - .into() - } else { - addr.into() - } - } - - let message = MessageBuilder::new() - .from(parse_address(&from)) - .to(parse_address(&to)) - .subject("StartOS Test Email") - .text_body("This is a test email sent from your StartOS Server"); - client - .connect() - .await - .map_err(|e| { - Error::new( - eyre!("mail-send connection error: {:?}", e), - ErrorKind::Unknown, - ) - })? - .send(message) - .await - .map_err(|e| Error::new(eyre!("mail-send send error: {:?}", e), ErrorKind::Unknown))?; - Ok(()) - } - #[cfg(not(feature = "mail-send"))] - Err(Error::new( - eyre!("test-smtp requires mail-send feature to be enabled"), - ErrorKind::InvalidRequest, - )) + AsyncSmtpTransport::::relay(&server)? + .credentials(Credentials::new(login, password)) + .build() + .send( + Message::builder() + .from(from.parse()?) + .to(to.parse()?) + .subject("StartOS Test Email") + .header(ContentType::TEXT_PLAIN) + .body("This is a test email sent from your StartOS Server".to_owned())?, + ) + .await?; + Ok(()) } #[tokio::test] diff --git a/core/startos/src/util/collections/mod.rs b/core/startos/src/util/collections/mod.rs index 2070343bd..0873b9da6 100644 --- a/core/startos/src/util/collections/mod.rs +++ b/core/startos/src/util/collections/mod.rs @@ -8,6 +8,30 @@ pub use eq_map::EqMap; pub use eq_set::EqSet; use imbl::OrdMap; +pub fn ordmap_retain bool>( + map: &mut OrdMap, + mut f: F, +) { + let mut prev = None; + loop { + let next = if let Some(k) = prev.take() { + map.range((Bound::Excluded(k), Bound::Unbounded)).next() + } else { + map.get_min().map(|(k, v)| (k, v)) + }; + let Some((k, _)) = next else { + break; + }; + let k = k.clone(); // hate that I have to do this but whatev + let v = map.get_mut(&k).unwrap(); + + if !f(&k, v) { + map.remove(&k); + } + prev = Some(k); + } +} + pub struct OrdMapIterMut<'a, K: 'a, V: 'a> { map: *mut OrdMap, prev: Option<&'a K>, diff --git a/core/startos/src/version/mod.rs b/core/startos/src/version/mod.rs index 761a96952..b18bdc993 100644 --- a/core/startos/src/version/mod.rs +++ b/core/startos/src/version/mod.rs @@ -51,8 +51,9 @@ mod v0_4_0_alpha_9; mod v0_4_0_alpha_10; mod v0_4_0_alpha_11; +mod v0_4_0_alpha_12; -pub type Current = v0_4_0_alpha_11::Version; // VERSION_BUMP +pub type Current = v0_4_0_alpha_12::Version; // VERSION_BUMP impl Current { #[instrument(skip(self, db))] @@ -97,8 +98,8 @@ pub async fn post_init( .as_server_info() .as_post_init_migration_todos() .de()?; + progress.start(); if !todos.is_empty() { - progress.set_total(todos.len() as u64); while let Some((version, input)) = { peek = ctx.db.peek().await; peek.as_public() @@ -121,7 +122,6 @@ pub async fn post_init( }) .await .result?; - progress += 1; } } progress.complete(); @@ -166,7 +166,8 @@ enum Version { V0_4_0_alpha_8(Wrapper), V0_4_0_alpha_9(Wrapper), V0_4_0_alpha_10(Wrapper), - V0_4_0_alpha_11(Wrapper), // VERSION_BUMP + V0_4_0_alpha_11(Wrapper), + V0_4_0_alpha_12(Wrapper), // VERSION_BUMP Other(exver::Version), } @@ -220,7 +221,8 @@ impl Version { Self::V0_4_0_alpha_8(v) => DynVersion(Box::new(v.0)), Self::V0_4_0_alpha_9(v) => DynVersion(Box::new(v.0)), Self::V0_4_0_alpha_10(v) => DynVersion(Box::new(v.0)), - Self::V0_4_0_alpha_11(v) => DynVersion(Box::new(v.0)), // VERSION_BUMP + Self::V0_4_0_alpha_11(v) => DynVersion(Box::new(v.0)), + Self::V0_4_0_alpha_12(v) => DynVersion(Box::new(v.0)), // VERSION_BUMP Self::Other(v) => { return Err(Error::new( eyre!("unknown version {v}"), @@ -266,7 +268,8 @@ impl Version { Version::V0_4_0_alpha_8(Wrapper(x)) => x.semver(), Version::V0_4_0_alpha_9(Wrapper(x)) => x.semver(), Version::V0_4_0_alpha_10(Wrapper(x)) => x.semver(), - Version::V0_4_0_alpha_11(Wrapper(x)) => x.semver(), // VERSION_BUMP + Version::V0_4_0_alpha_11(Wrapper(x)) => x.semver(), + Version::V0_4_0_alpha_12(Wrapper(x)) => x.semver(), // VERSION_BUMP Version::Other(x) => x.clone(), } } diff --git a/core/startos/src/version/v0_3_6_alpha_0.rs b/core/startos/src/version/v0_3_6_alpha_0.rs index 0edc98677..ebcd9ae16 100644 --- a/core/startos/src/version/v0_3_6_alpha_0.rs +++ b/core/startos/src/version/v0_3_6_alpha_0.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; use std::ffi::OsStr; use std::path::Path; @@ -6,8 +6,8 @@ use chrono::{DateTime, Utc}; use const_format::formatcp; use ed25519_dalek::SigningKey; use exver::{PreReleaseSegment, VersionRange}; -use imbl_value::{InternedString, json}; -use models::{PackageId, ReplayId}; +use imbl_value::{json, InternedString}; +use models::{HostId, Id, PackageId, ReplayId}; use openssl::pkey::PKey; use openssl::x509::X509; use sqlx::postgres::PgConnectOptions; @@ -15,7 +15,7 @@ use sqlx::{PgPool, Row}; use tokio::process::Command; use super::v0_3_5::V0_3_0_COMPAT; -use super::{VersionT, v0_3_5_2}; +use super::{v0_3_5_2, VersionT}; use crate::account::AccountInfo; use crate::auth::Sessions; use crate::backup::target::cifs::CifsTargets; @@ -24,15 +24,16 @@ use crate::disk::mount::filesystem::cifs::Cifs; use crate::disk::mount::util::unmount; use crate::hostname::Hostname; use crate::net::forward::AvailablePorts; +use crate::net::host::Host; use crate::net::keys::KeyStore; -use crate::net::tor::TorSecretKey; +use crate::net::tor::{OnionAddress, TorSecretKey}; use crate::notifications::Notifications; use crate::prelude::*; use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile; use crate::ssh::{SshKeys, SshPubKey}; -use crate::util::Invoke; use crate::util::crypto::ed25519_expand_key; use crate::util::serde::Pem; +use crate::util::Invoke; use crate::{DATA_DIR, PACKAGE_DATA}; lazy_static::lazy_static! { @@ -93,69 +94,6 @@ async fn init_postgres(datadir: impl AsRef) -> Result { crate::disk::mount::util::bind(&db_dir, "/var/lib/postgresql", false).await?; - let pg_version_string = pg_version.to_string(); - let pg_version_path = db_dir.join(&pg_version_string); - if exists - // maybe migrate - { - let incomplete_path = db_dir.join(format!("{pg_version}.migration.incomplete")); - if tokio::fs::metadata(&incomplete_path).await.is_ok() // previous migration was incomplete - && tokio::fs::metadata(&pg_version_path).await.is_ok() - { - tokio::fs::remove_dir_all(&pg_version_path).await?; - } - if tokio::fs::metadata(&pg_version_path).await.is_err() - // need to migrate - { - let conf_dir = Path::new("/etc/postgresql").join(pg_version.to_string()); - let conf_dir_tmp = { - let mut tmp = conf_dir.clone(); - tmp.set_extension("tmp"); - tmp - }; - if tokio::fs::metadata(&conf_dir).await.is_ok() { - Command::new("mv") - .arg(&conf_dir) - .arg(&conf_dir_tmp) - .invoke(ErrorKind::Filesystem) - .await?; - } - let mut old_version = pg_version; - while old_version > 13 - /* oldest pg version included in startos */ - { - old_version -= 1; - let old_datadir = db_dir.join(old_version.to_string()); - if tokio::fs::metadata(&old_datadir).await.is_ok() { - tokio::fs::File::create(&incomplete_path) - .await? - .sync_all() - .await?; - Command::new("pg_upgradecluster") - .arg(old_version.to_string()) - .arg("main") - .invoke(crate::ErrorKind::Database) - .await?; - break; - } - } - if tokio::fs::metadata(&conf_dir).await.is_ok() { - if tokio::fs::metadata(&conf_dir).await.is_ok() { - tokio::fs::remove_dir_all(&conf_dir).await?; - } - Command::new("mv") - .arg(&conf_dir_tmp) - .arg(&conf_dir) - .invoke(ErrorKind::Filesystem) - .await?; - } - tokio::fs::remove_file(&incomplete_path).await?; - } - if tokio::fs::metadata(&incomplete_path).await.is_ok() { - unreachable!() // paranoia - } - } - Command::new("systemctl") .arg("start") .arg(format!("postgresql@{pg_version}-main.service")) @@ -209,7 +147,12 @@ pub struct Version; impl VersionT for Version { type Previous = v0_3_5_2::Version; - type PreUpRes = (AccountInfo, SshKeys, CifsTargets); + type PreUpRes = ( + AccountInfo, + SshKeys, + CifsTargets, + BTreeMap>, + ); fn semver(self) -> exver::Version { V0_3_6_alpha_0.clone() } @@ -224,9 +167,15 @@ impl VersionT for Version { let cifs = previous_cifs(&pg).await?; - Ok((account, ssh_keys, cifs)) + let tor_keys = previous_tor_keys(&pg).await?; + + Ok((account, ssh_keys, cifs, tor_keys)) } - fn up(self, db: &mut Value, (account, ssh_keys, cifs): Self::PreUpRes) -> Result { + fn up( + self, + db: &mut Value, + (account, ssh_keys, cifs, tor_keys): Self::PreUpRes, + ) -> Result { let prev_package_data = db["package-data"].clone(); let wifi = json!({ @@ -259,12 +208,10 @@ impl VersionT for Version { let tor_address: String = from_value(db["server-info"]["tor-address"].clone())?; // Maybe we do this like the Public::init does server_info["torAddress"] = json!(tor_address); - server_info["onionAddress"] = json!( - tor_address - .replace("https://", "") - .replace("http://", "") - .replace(".onion/", "") - ); + server_info["onionAddress"] = json!(tor_address + .replace("https://", "") + .replace("http://", "") + .replace(".onion/", "")); server_info["networkInterfaces"] = json!({}); server_info["statusInfo"] = status_info; server_info["wifi"] = wifi; @@ -288,9 +235,15 @@ impl VersionT for Version { "ui": db["ui"], }); + let mut keystore = KeyStore::new(&account)?; + for key in tor_keys.values().flat_map(|v| v.values()) { + assert!(key.is_valid()); + keystore.onion.insert(key.clone()); + } + let private = { let mut value = json!({}); - value["keyStore"] = to_value(&KeyStore::new(&account)?)?; + value["keyStore"] = crate::dbg!(to_value(&keystore)?); value["password"] = to_value(&account.password)?; value["compatS9pkKey"] = to_value(&crate::db::model::private::generate_developer_key())?; @@ -373,6 +326,20 @@ impl VersionT for Version { false }; + let onions = input[&*id]["installed"]["interface-addresses"] + .as_object() + .into_iter() + .flatten() + .filter_map(|(id, addrs)| { + addrs["tor-address"].as_str().map(|addr| { + Ok(( + HostId::from(Id::try_from(id.clone())?), + addr.parse::()?, + )) + }) + }) + .collect::, Error>>()?; + if let Err(e) = async { let package_s9pk = tokio::fs::File::open(path).await?; let file = MultiCursorFile::open(&package_s9pk).await?; @@ -390,19 +357,44 @@ impl VersionT for Version { .await? .await?; - if configured { - ctx.db - .mutate(|db| { - db.as_public_mut() - .as_package_data_mut() - .as_idx_mut(&id) - .or_not_found(&id)? + let to_sync = ctx + .db + .mutate(|db| { + let mut to_sync = BTreeSet::new(); + + let package = db + .as_public_mut() + .as_package_data_mut() + .as_idx_mut(&id) + .or_not_found(&id)?; + if configured { + package .as_tasks_mut() - .remove(&ReplayId::from("needs-config")) - }) - .await - .result?; + .remove(&ReplayId::from("needs-config"))?; + } + for (id, onion) in onions { + package + .as_hosts_mut() + .upsert(&id, || Ok(Host::new()))? + .as_onions_mut() + .mutate(|o| { + o.clear(); + o.insert(onion); + Ok(()) + })?; + to_sync.insert(id); + } + Ok(to_sync) + }) + .await + .result?; + + if let Some(service) = &*ctx.services.get(&id).await { + for host_id in to_sync { + service.sync_host(host_id.clone()).await?; + } } + Ok::<_, Error>(()) } .await @@ -470,14 +462,12 @@ async fn previous_account_info(pg: &sqlx::Pool) -> Result>, _>("tor_key") .with_ctx(|_| (ErrorKind::Database, "tor_key"))? { - <[u8; 64]>::try_from(bytes) - .map_err(|e| { - Error::new( - eyre!("expected vec of len 64, got len {}", e.len()), - ErrorKind::ParseDbField, - ) - }) - .with_ctx(|_| (ErrorKind::Database, "password.u8 64"))? + <[u8; 64]>::try_from(bytes).map_err(|e| { + Error::new( + eyre!("expected vec of len 64, got len {}", e.len()), + ErrorKind::ParseDbField, + ) + })? } else { ed25519_expand_key( &<[u8; 32]>::try_from( @@ -490,8 +480,7 @@ async fn previous_account_info(pg: &sqlx::Pool) -> Result) -> Result, +) -> Result>, Error> { + let mut res = BTreeMap::>::new(); + let net_key_query = sqlx::query(r#"SELECT * FROM network_keys"#) + .fetch_all(pg) + .await + .with_kind(ErrorKind::Database)?; + + for row in net_key_query { + let package_id: PackageId = row + .try_get::("package") + .with_ctx(|_| (ErrorKind::Database, "network_keys::package"))? + .parse()?; + let interface_id: HostId = row + .try_get::("interface") + .with_ctx(|_| (ErrorKind::Database, "network_keys::interface"))? + .parse()?; + let key = TorSecretKey::from_bytes(ed25519_expand_key( + &<[u8; 32]>::try_from( + row.try_get::, _>("key") + .with_ctx(|_| (ErrorKind::Database, "network_keys::key"))?, + ) + .map_err(|e| { + Error::new( + eyre!("expected vec of len 32, got len {}", e.len()), + ErrorKind::ParseDbField, + ) + })?, + ))?; + res.entry(package_id).or_default().insert(interface_id, key); + } + + let tor_key_query = sqlx::query(r#"SELECT * FROM tor"#) + .fetch_all(pg) + .await + .with_kind(ErrorKind::Database)?; + + for row in tor_key_query { + let package_id: PackageId = row + .try_get::("package") + .with_ctx(|_| (ErrorKind::Database, "tor::package"))? + .parse()?; + let interface_id: HostId = row + .try_get::("interface") + .with_ctx(|_| (ErrorKind::Database, "tor::interface"))? + .parse()?; + let key = TorSecretKey::from_bytes( + <[u8; 64]>::try_from( + row.try_get::, _>("key") + .with_ctx(|_| (ErrorKind::Database, "tor::key"))?, + ) + .map_err(|e| { + Error::new( + eyre!("expected vec of len 64, got len {}", e.len()), + ErrorKind::ParseDbField, + ) + })?, + )?; + res.entry(package_id).or_default().insert(interface_id, key); + } + + Ok(res) +} diff --git a/core/startos/src/version/v0_4_0_alpha_10.rs b/core/startos/src/version/v0_4_0_alpha_10.rs index ece6fcefc..2fb3f3e61 100644 --- a/core/startos/src/version/v0_4_0_alpha_10.rs +++ b/core/startos/src/version/v0_4_0_alpha_10.rs @@ -31,7 +31,7 @@ impl VersionT for Version { fn compat(self) -> &'static VersionRange { &V0_3_0_COMPAT } - #[instrument] + #[instrument(skip_all)] fn up(self, db: &mut Value, _: Self::PreUpRes) -> Result { let default_gateway = db["public"]["serverInfo"]["network"]["networkInterfaces"] .as_object() diff --git a/core/startos/src/version/v0_4_0_alpha_11.rs b/core/startos/src/version/v0_4_0_alpha_11.rs index 9f59f478a..4834ab362 100644 --- a/core/startos/src/version/v0_4_0_alpha_11.rs +++ b/core/startos/src/version/v0_4_0_alpha_11.rs @@ -27,7 +27,7 @@ impl VersionT for Version { fn compat(self) -> &'static VersionRange { &V0_3_0_COMPAT } - #[instrument] + #[instrument(skip_all)] fn up(self, db: &mut Value, _: Self::PreUpRes) -> Result { Ok(Value::Null) } diff --git a/core/startos/src/version/v0_4_0_alpha_12.rs b/core/startos/src/version/v0_4_0_alpha_12.rs new file mode 100644 index 000000000..32fce1c2e --- /dev/null +++ b/core/startos/src/version/v0_4_0_alpha_12.rs @@ -0,0 +1,83 @@ +use std::collections::BTreeSet; + +use exver::{PreReleaseSegment, VersionRange}; +use imbl_value::InternedString; + +use super::v0_3_5::V0_3_0_COMPAT; +use super::{v0_4_0_alpha_11, VersionT}; +use crate::net::tor::TorSecretKey; +use crate::prelude::*; + +lazy_static::lazy_static! { + static ref V0_4_0_alpha_12: exver::Version = exver::Version::new( + [0, 4, 0], + [PreReleaseSegment::String("alpha".into()), 12.into()] + ); +} + +#[derive(Clone, Copy, Debug, Default)] +pub struct Version; + +impl VersionT for Version { + type Previous = v0_4_0_alpha_11::Version; + type PreUpRes = (); + + async fn pre_up(self) -> Result { + Ok(()) + } + fn semver(self) -> exver::Version { + V0_4_0_alpha_12.clone() + } + fn compat(self) -> &'static VersionRange { + &V0_3_0_COMPAT + } + #[instrument(skip_all)] + fn up(self, db: &mut Value, _: Self::PreUpRes) -> Result { + let mut err = None; + let onion_store = db["private"]["keyStore"]["onion"] + .as_object_mut() + .or_not_found("private.keyStore.onion")?; + onion_store.retain(|o, v| match from_value::(v.clone()) { + Ok(k) => k.is_valid() && &InternedString::from_display(&k.onion_address()) == o, + Err(e) => { + err = Some(e); + true + } + }); + if let Some(e) = err { + return Err(e); + } + let allowed_addresses = onion_store.keys().cloned().collect::>(); + let fix_host = |host: &mut Value| { + Ok::<_, Error>( + host["onions"] + .as_array_mut() + .or_not_found("host.onions")? + .retain(|addr| { + addr.as_str() + .map(|s| allowed_addresses.contains(s)) + .unwrap_or(false) + }), + ) + }; + for (_, pde) in db["public"]["packageData"] + .as_object_mut() + .or_not_found("public.packageData")? + .iter_mut() + { + for (_, host) in pde["hosts"] + .as_object_mut() + .or_not_found("public.packageData[].hosts")? + .iter_mut() + { + fix_host(host)?; + } + } + fix_host(&mut db["public"]["serverInfo"]["network"]["host"])?; + + Ok(Value::Null) + } + fn down(self, _db: &mut Value) -> Result<(), Error> { + Ok(()) + } +} diff --git a/core/startos/src/version/v0_4_0_alpha_4.rs b/core/startos/src/version/v0_4_0_alpha_4.rs index ffc83fe65..a89902824 100644 --- a/core/startos/src/version/v0_4_0_alpha_4.rs +++ b/core/startos/src/version/v0_4_0_alpha_4.rs @@ -1,7 +1,7 @@ use exver::{PreReleaseSegment, VersionRange}; use super::v0_3_5::V0_3_0_COMPAT; -use super::{VersionT, v0_4_0_alpha_3}; +use super::{v0_4_0_alpha_3, VersionT}; use crate::context::RpcContext; use crate::prelude::*; use crate::util::io::create_file_mod; @@ -29,7 +29,7 @@ impl VersionT for Version { fn compat(self) -> &'static VersionRange { &V0_3_0_COMPAT } - #[instrument] + #[instrument(skip_all)] fn up(self, db: &mut Value, _: Self::PreUpRes) -> Result { db["public"]["serverInfo"] .as_object_mut() diff --git a/core/startos/src/version/v0_4_0_alpha_5.rs b/core/startos/src/version/v0_4_0_alpha_5.rs index 4ff950e5e..aa71640f6 100644 --- a/core/startos/src/version/v0_4_0_alpha_5.rs +++ b/core/startos/src/version/v0_4_0_alpha_5.rs @@ -1,7 +1,7 @@ use exver::{PreReleaseSegment, VersionRange}; use super::v0_3_5::V0_3_0_COMPAT; -use super::{VersionT, v0_4_0_alpha_4}; +use super::{v0_4_0_alpha_4, VersionT}; use crate::prelude::*; lazy_static::lazy_static! { @@ -27,7 +27,7 @@ impl VersionT for Version { fn compat(self) -> &'static VersionRange { &V0_3_0_COMPAT } - #[instrument] + #[instrument(skip_all)] fn up(self, _db: &mut Value, _: Self::PreUpRes) -> Result { Ok(Value::Null) } diff --git a/core/startos/src/version/v0_4_0_alpha_6.rs b/core/startos/src/version/v0_4_0_alpha_6.rs index d75aceb19..1b5566f7f 100644 --- a/core/startos/src/version/v0_4_0_alpha_6.rs +++ b/core/startos/src/version/v0_4_0_alpha_6.rs @@ -1,7 +1,7 @@ use exver::{PreReleaseSegment, VersionRange}; use super::v0_3_5::V0_3_0_COMPAT; -use super::{VersionT, v0_4_0_alpha_5}; +use super::{v0_4_0_alpha_5, VersionT}; use crate::prelude::*; lazy_static::lazy_static! { @@ -27,7 +27,7 @@ impl VersionT for Version { fn compat(self) -> &'static VersionRange { &V0_3_0_COMPAT } - #[instrument] + #[instrument(skip_all)] fn up(self, db: &mut Value, _: Self::PreUpRes) -> Result { let ui = db["public"]["ui"] .as_object_mut() diff --git a/core/startos/src/version/v0_4_0_alpha_7.rs b/core/startos/src/version/v0_4_0_alpha_7.rs index bd8a226e1..085375fc8 100644 --- a/core/startos/src/version/v0_4_0_alpha_7.rs +++ b/core/startos/src/version/v0_4_0_alpha_7.rs @@ -1,7 +1,7 @@ use exver::{PreReleaseSegment, VersionRange}; use super::v0_3_5::V0_3_0_COMPAT; -use super::{VersionT, v0_4_0_alpha_6}; +use super::{v0_4_0_alpha_6, VersionT}; use crate::prelude::*; lazy_static::lazy_static! { @@ -27,7 +27,7 @@ impl VersionT for Version { fn compat(self) -> &'static VersionRange { &V0_3_0_COMPAT } - #[instrument] + #[instrument(skip_all)] fn up(self, _db: &mut Value, _: Self::PreUpRes) -> Result { Ok(Value::Null) } diff --git a/core/startos/src/version/v0_4_0_alpha_8.rs b/core/startos/src/version/v0_4_0_alpha_8.rs index fa2c87a0a..6431c0d66 100644 --- a/core/startos/src/version/v0_4_0_alpha_8.rs +++ b/core/startos/src/version/v0_4_0_alpha_8.rs @@ -1,7 +1,7 @@ use exver::{PreReleaseSegment, VersionRange}; use super::v0_3_5::V0_3_0_COMPAT; -use super::{VersionT, v0_4_0_alpha_7}; +use super::{v0_4_0_alpha_7, VersionT}; use crate::prelude::*; lazy_static::lazy_static! { @@ -27,7 +27,7 @@ impl VersionT for Version { fn compat(self) -> &'static VersionRange { &V0_3_0_COMPAT } - #[instrument] + #[instrument(skip_all)] fn up(self, _db: &mut Value, _: Self::PreUpRes) -> Result { Ok(Value::Null) } diff --git a/core/startos/src/version/v0_4_0_alpha_9.rs b/core/startos/src/version/v0_4_0_alpha_9.rs index ffb5ad5be..a79c77104 100644 --- a/core/startos/src/version/v0_4_0_alpha_9.rs +++ b/core/startos/src/version/v0_4_0_alpha_9.rs @@ -7,13 +7,13 @@ use imbl_value::{InOMap, InternedString}; use models::PackageId; use super::v0_3_5::V0_3_0_COMPAT; -use super::{VersionT, v0_4_0_alpha_8}; -use crate::DATA_DIR; +use super::{v0_4_0_alpha_8, VersionT}; use crate::context::RpcContext; use crate::install::PKG_ARCHIVE_DIR; use crate::prelude::*; use crate::util::io::write_file_atomic; use crate::volume::PKG_VOLUME_DIR; +use crate::DATA_DIR; lazy_static::lazy_static! { static ref V0_4_0_alpha_9: exver::Version = exver::Version::new( @@ -38,7 +38,7 @@ impl VersionT for Version { fn compat(self) -> &'static VersionRange { &V0_3_0_COMPAT } - #[instrument] + #[instrument(skip_all)] fn up(self, db: &mut Value, _: Self::PreUpRes) -> Result { let mut res = InOMap::new(); let todos = db diff --git a/debian/startos/postinst b/debian/startos/postinst index a8d4ee729..cca71d3e8 100755 --- a/debian/startos/postinst +++ b/debian/startos/postinst @@ -114,16 +114,6 @@ sed -i '/\(^\|#\)RootDistanceMaxSec=/c\RootDistanceMaxSec=10' /etc/systemd/times mkdir -p /etc/nginx/ssl -cat << EOF > /etc/tor/torrc -SocksPort 0.0.0.0:9050 -SocksPolicy accept 127.0.0.1 -SocksPolicy accept 172.18.0.0/16 -SocksPolicy accept 10.0.3.0/24 -SocksPolicy reject * -ControlPort 9051 -CookieAuthentication 1 -EOF - rm -rf /var/lib/tor/* ln -sf /usr/lib/startos/scripts/chroot-and-upgrade /usr/bin/chroot-and-upgrade ln -sf /usr/lib/startos/scripts/tor-check /usr/bin/tor-check @@ -132,11 +122,7 @@ ln -sf /usr/lib/startos/scripts/wireguard-vps-proxy-setup /usr/bin/wireguard-vps echo "fs.inotify.max_user_watches=1048576" > /etc/sysctl.d/97-startos.conf -# Old pi was set with this locale, because of pg we are now stuck with including that locale -locale-gen en_GB en_GB.UTF-8 -echo "locales locales/locales_to_be_generated multiselect en_GB.UTF-8 UTF-8" | debconf-set-selections -update-locale LANGUAGE -rm -f "/etc/locale.gen" +locale-gen en_US.UTF-8 dpkg-reconfigure --frontend noninteractive locales if ! getent group | grep '^startos:'; then diff --git a/image-recipe/Dockerfile b/image-recipe/Dockerfile new file mode 100644 index 000000000..5bef21e29 --- /dev/null +++ b/image-recipe/Dockerfile @@ -0,0 +1,29 @@ +ARG SUITE=trixie + +FROM debian:${SUITE} + +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && \ + apt-get install -yq \ + live-build \ + procps \ + binfmt-support \ + qemu-utils \ + qemu-user-static \ + xorriso \ + isolinux \ + ca-certificates \ + curl \ + wget \ + gpg \ + fdisk \ + dosfstools \ + e2fsprogs \ + squashfs-tools \ + rsync \ + b3sum \ + dpkg-dev +RUN echo 'retry_connrefused = on' > /etc/wgetrc && \ + echo 'tries = 100' >> /etc/wgetrc + +WORKDIR /root \ No newline at end of file diff --git a/image-recipe/build.sh b/image-recipe/build.sh index abbb71127..0576a4af2 100755 --- a/image-recipe/build.sh +++ b/image-recipe/build.sh @@ -7,33 +7,50 @@ echo "==== StartOS Image Build ====" echo "Building for architecture: $IB_TARGET_ARCH" -base_dir="$(dirname "$(readlink -f "$0")")" +SOURCE_DIR="$(realpath $(dirname "${BASH_SOURCE[0]}"))" + +base_dir="$(pwd -P)" prep_results_dir="$base_dir/images-prep" -if systemd-detect-virt -qc; then - RESULTS_DIR="/srv/artifacts" -else - RESULTS_DIR="$base_dir/results" -fi +RESULTS_DIR="$base_dir/results" echo "Saving results in: $RESULTS_DIR" +DEB_PATH="$base_dir/$1" + +VERSION="$(dpkg-deb --fsys-tarfile $DEB_PATH | tar --to-stdout -xvf - ./usr/lib/startos/VERSION.txt)" +GIT_HASH="$(dpkg-deb --fsys-tarfile $DEB_PATH | tar --to-stdout -xvf - ./usr/lib/startos/GIT_HASH.txt)" +if [[ "$GIT_HASH" =~ ^@ ]]; then + GIT_HASH="unknown" +else + GIT_HASH="$(echo -n "$GIT_HASH" | head -c 7)" +fi +IB_OS_ENV="$(dpkg-deb --fsys-tarfile $DEB_PATH | tar --to-stdout -xvf - ./usr/lib/startos/ENVIRONMENT.txt)" +IB_TARGET_PLATFORM="$(dpkg-deb --fsys-tarfile $DEB_PATH | tar --to-stdout -xvf - ./usr/lib/startos/PLATFORM.txt)" + +VERSION_FULL="${VERSION}-${GIT_HASH}" +if [ -n "$IB_OS_ENV" ]; then + VERSION_FULL="$VERSION_FULL~${IB_OS_ENV}" +fi + IMAGE_BASENAME=startos-${VERSION_FULL}_${IB_TARGET_PLATFORM} -QEMU_ARCH=${IB_TARGET_ARCH} -BOOTLOADERS=grub-efi,syslinux -if [ "$QEMU_ARCH" = 'amd64' ]; then +BOOTLOADERS=grub-efi +if [ "$IB_TARGET_PLATFORM" = "x86_64" ] || [ "$IB_TARGET_PLATFORM" = "x86_64-nonfree" ]; then + IB_TARGET_ARCH=amd64 QEMU_ARCH=x86_64 -elif [ "$QEMU_ARCH" = 'arm64' ]; then + BOOTLOADERS=grub-efi,syslinux +elif [ "$IB_TARGET_PLATFORM" = "aarch64" ] || [ "$IB_TARGET_PLATFORM" = "aarch64-nonfree" ] || [ "$IB_TARGET_PLATFORM" = "raspberrypi" ] || [ "$IB_TARGET_PLATFORM" = "rockchip64" ]; then + IB_TARGET_ARCH=arm64 QEMU_ARCH=aarch64 - BOOTLOADERS=grub-efi +else + IB_TARGET_ARCH="$IB_TARGET_PLATFORM" + QEMU_ARCH="$IB_TARGET_PLATFORM" fi -# TODO: remove when util-linux is released at v2.39 -cd $base_dir -git clone --depth=1 --branch=v2.39.3 https://github.com/util-linux/util-linux.git -cd util-linux -./autogen.sh -CC=$QEMU_ARCH-linux-gnu-gcc ./configure --host=$QEMU_ARCH-linux-gnu --disable-all-programs --enable-mount --enable-libmount --enable-libblkid --enable-libuuid --enable-static-programs -CC=$QEMU_ARCH-linux-gnu-gcc make -j mount.static +QEMU_ARGS=() +if [ "$QEMU_ARCH" != $(uname -m) ]; then + QEMU_ARGS+=(--bootstrap-qemu-arch ${IB_TARGET_ARCH}) + QEMU_ARGS+=(--bootstrap-qemu-static /usr/bin/qemu-${QEMU_ARCH}-static) +fi mkdir -p $prep_results_dir @@ -80,27 +97,21 @@ lb config \ --backports true \ --bootappend-live "boot=live noautologin" \ --bootloaders $BOOTLOADERS \ + --cache false \ --mirror-bootstrap "https://deb.debian.org/debian/" \ --mirror-chroot "https://deb.debian.org/debian/" \ --mirror-chroot-security "https://security.debian.org/debian-security" \ -d ${IB_SUITE} \ -a ${IB_TARGET_ARCH} \ - --bootstrap-qemu-arch ${IB_TARGET_ARCH} \ - --bootstrap-qemu-static /usr/bin/qemu-${QEMU_ARCH}-static \ + ${QEMU_ARGS[@]} \ --archive-areas "${ARCHIVE_AREAS}" \ ${PLATFORM_CONFIG_EXTRAS[@]} # Overlays -mkdir -p config/includes.chroot/deb -cp $base_dir/deb/${IMAGE_BASENAME}.deb config/includes.chroot/deb/ - -mkdir -p config/includes.chroot/usr/local/bin -cp $base_dir/util-linux/mount.static config/includes.chroot/usr/local/bin/mount.next - -if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then - cp -r $base_dir/raspberrypi/squashfs/* config/includes.chroot/ -fi +mkdir -p config/packages.chroot/ +cp $RESULTS_DIR/$IMAGE_BASENAME.deb config/packages.chroot/ +dpkg-name config/packages.chroot/*.deb mkdir -p config/includes.chroot/etc echo start > config/includes.chroot/etc/hostname @@ -111,6 +122,10 @@ ff02::1 ip6-allnodes ff02::2 ip6-allrouters EOT +if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then + cp -r $SOURCE_DIR/raspberrypi/squashfs/* config/includes.chroot/ +fi + # Bootloaders rm -rf config/bootloaders @@ -130,10 +145,9 @@ prompt 0 timeout 50 EOF -rm config/bootloaders/syslinux_common/splash.svg -cp $base_dir/splash.png config/bootloaders/syslinux_common/splash.png -cp $base_dir/splash.png config/bootloaders/isolinux/splash.png -cp $base_dir/splash.png config/bootloaders/grub-pc/splash.png +cp $SOURCE_DIR/splash.png config/bootloaders/syslinux_common/splash.png +cp $SOURCE_DIR/splash.png config/bootloaders/isolinux/splash.png +cp $SOURCE_DIR/splash.png config/bootloaders/grub-pc/splash.png sed -i -e '2i set timeout=5' config/bootloaders/grub-pc/config.cfg @@ -146,16 +160,6 @@ if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then echo "deb [arch=${IB_TARGET_ARCH} signed-by=/etc/apt/trusted.gpg.d/raspi.key.gpg] https://archive.raspberrypi.com/debian/ ${IB_SUITE} main" > config/archives/raspi.list fi -cat > config/archives/backports.pref <<- EOF -Package: linux-image-* -Pin: release n=${IB_SUITE}-backports -Pin-Priority: 500 - -Package: linux-base -Pin: release n=${IB_SUITE}-backports -Pin-Priority: 500 -EOF - if [ "${IB_TARGET_PLATFORM}" = "rockchip64" ]; then curl -fsSL https://apt.armbian.com/armbian.key | gpg --dearmor -o config/archives/armbian.key echo "deb https://apt.armbian.com/ ${IB_SUITE} main" > config/archives/armbian.list @@ -163,37 +167,25 @@ fi # Dependencies -## Base dependencies -dpkg-deb --fsys-tarfile $base_dir/deb/${IMAGE_BASENAME}.deb | tar --to-stdout -xvf - ./usr/lib/startos/depends > config/package-lists/startos-depends.list.chroot - ## Firmware if [ "$NON_FREE" = 1 ]; then echo 'firmware-iwlwifi firmware-misc-nonfree firmware-brcm80211 firmware-realtek firmware-atheros firmware-libertas firmware-amd-graphics' > config/package-lists/nonfree.list.chroot fi -if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then - echo 'raspberrypi-net-mods raspberrypi-sys-mods raspi-config raspi-firmware raspi-gpio raspi-utils rpi-eeprom rpi-update rpi.gpio-common parted' > config/package-lists/bootloader.list.chroot -else - echo 'grub-efi grub2-common' > config/package-lists/bootloader.list.chroot -fi -if [ "${IB_TARGET_ARCH}" = "amd64" ] || [ "${IB_TARGET_ARCH}" = "i386" ]; then - echo 'grub-pc-bin' >> config/package-lists/bootloader.list.chroot -fi - cat > config/hooks/normal/9000-install-startos.hook.chroot << EOF #!/bin/bash set -e -apt-get install -y /deb/${IMAGE_BASENAME}.deb -rm -rf /deb +cp /etc/resolv.conf /etc/resolv.conf.bak -if [ "${IB_SUITE}" = bookworm ]; then - echo 'deb https://deb.debian.org/debian/ bullseye main' > /etc/apt/sources.list.d/bullseye.list +if [ "${IB_SUITE}" = trixie ]; then + echo 'deb https://deb.debian.org/debian/ bookworm main' > /etc/apt/sources.list.d/bookworm.list apt-get update - apt-get install -y postgresql-13 - rm /etc/apt/sources.list.d/bullseye.list + apt-get install -y postgresql-15 + rm /etc/apt/sources.list.d/bookworm.list apt-get update + systemctl mask postgresql fi if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then @@ -231,8 +223,7 @@ lb chroot lb installer lb binary_chroot lb chroot_prep install all mode-apt-install-binary mode-archives-chroot -echo "nameserver 127.0.0.1" > chroot/chroot/etc/resolv.conf -echo "nameserver 1.1.1.1" >> chroot/chroot/etc/resolv.conf # Cloudflare DNS Fallback +mv chroot/chroot/etc/resolv.conf.bak chroot/chroot/etc/resolv.conf lb binary_rootfs cp $prep_results_dir/binary/live/filesystem.squashfs $RESULTS_DIR/$IMAGE_BASENAME.squashfs @@ -325,7 +316,7 @@ elif [ "${IMAGE_TYPE}" = img ]; then if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then sed -i 's| boot=startos| boot=startos init=/usr/lib/startos/scripts/init_resize\.sh|' $TMPDIR/boot/cmdline.txt - rsync -a $base_dir/raspberrypi/img/ $TMPDIR/next/ + rsync -a $SOURCE_DIR/raspberrypi/img/ $TMPDIR/next/ fi umount $TMPDIR/next @@ -361,3 +352,5 @@ elif [ "${IMAGE_TYPE}" = img ]; then mv $TARGET_NAME $RESULTS_DIR/$IMAGE_BASENAME.img fi + +chown $IB_UID:$IB_UID $RESULTS_DIR/$IMAGE_BASENAME.* \ No newline at end of file diff --git a/image-recipe/run-local-build.sh b/image-recipe/run-local-build.sh index e5cf7645c..96cad26c0 100755 --- a/image-recipe/run-local-build.sh +++ b/image-recipe/run-local-build.sh @@ -1,85 +1,22 @@ #!/bin/bash set -e -DEB_PATH="$(realpath $1)" - cd "$(dirname "${BASH_SOURCE[0]}")"/.. BASEDIR="$(pwd -P)" -VERSION="$(dpkg-deb --fsys-tarfile $DEB_PATH | tar --to-stdout -xvf - ./usr/lib/startos/VERSION.txt)" -GIT_HASH="$(dpkg-deb --fsys-tarfile $DEB_PATH | tar --to-stdout -xvf - ./usr/lib/startos/GIT_HASH.txt)" -if [[ "$GIT_HASH" =~ ^@ ]]; then - GIT_HASH="unknown" -else - GIT_HASH="$(echo -n "$GIT_HASH" | head -c 7)" -fi -STARTOS_ENV="$(dpkg-deb --fsys-tarfile $DEB_PATH | tar --to-stdout -xvf - ./usr/lib/startos/ENVIRONMENT.txt)" -PLATFORM="$(dpkg-deb --fsys-tarfile $DEB_PATH | tar --to-stdout -xvf - ./usr/lib/startos/PLATFORM.txt)" +SUITE=trixie -if [ "$PLATFORM" = "x86_64" ] || [ "$PLATFORM" = "x86_64-nonfree" ]; then - ARCH=amd64 - QEMU_ARCH=x86_64 -elif [ "$PLATFORM" = "aarch64" ] || [ "$PLATFORM" = "aarch64-nonfree" ] || [ "$PLATFORM" = "raspberrypi" ] || [ "$PLATFORM" = "rockchip64" ]; then - ARCH=arm64 - QEMU_ARCH=aarch64 -else - ARCH="$PLATFORM" - QEMU_ARCH="$PLATFORM" +dockerfile_hash=$(sha256sum ${BASEDIR}/image-recipe/prepare.sh | head -c 7) + +docker_img_name="startos_build:${SUITE}-${dockerfile_hash}" + +if [ -z "$(docker images -q "${docker_img_name}")" ]; then + docker build --build-arg=SUITE=${SUITE} -t "${docker_img_name}" ./image-recipe fi -SUITE=bookworm - -debspawn list | grep $SUITE || debspawn create $SUITE - -VERSION_FULL="${VERSION}-${GIT_HASH}" -if [ -n "$STARTOS_ENV" ]; then - VERSION_FULL="$VERSION_FULL~${STARTOS_ENV}" -fi - -if [ -z "$DSNAME" ]; then - DSNAME="$SUITE" -fi - -if [ "$QEMU_ARCH" != "$(uname -m)" ]; then - sudo update-binfmts --import qemu-$QEMU_ARCH -fi - -imgbuild_fname="$(mktemp /tmp/exec-mkimage.XXXXXX)" -cat > $imgbuild_fname < = diff --git a/web/package-lock.json b/web/package-lock.json index d3b9c7fab..c455e26c6 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,12 +1,12 @@ { "name": "startos-ui", - "version": "0.4.0-alpha.11", + "version": "0.4.0-alpha.12", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "startos-ui", - "version": "0.4.0-alpha.11", + "version": "0.4.0-alpha.12", "license": "MIT", "dependencies": { "@angular/animations": "^20.1.0", diff --git a/web/package.json b/web/package.json index 546eb64ad..d30d18141 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "startos-ui", - "version": "0.4.0-alpha.11", + "version": "0.4.0-alpha.12", "author": "Start9 Labs, Inc", "homepage": "https://start9.com/", "license": "MIT", diff --git a/web/projects/ui/src/app/services/api/api.fixures.ts b/web/projects/ui/src/app/services/api/api.fixures.ts index 66a06710c..6f11dc2cd 100644 --- a/web/projects/ui/src/app/services/api/api.fixures.ts +++ b/web/projects/ui/src/app/services/api/api.fixures.ts @@ -110,7 +110,7 @@ export namespace Mock { squashfs: { aarch64: { publishedAt: '2025-04-21T20:58:48.140749883Z', - url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.11/startos-0.4.0-alpha.11-33ae46f~dev_aarch64.squashfs', + url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.12/startos-0.4.0-alpha.12-33ae46f~dev_aarch64.squashfs', commitment: { hash: '4elBFVkd/r8hNadKmKtLIs42CoPltMvKe2z3LRqkphk=', size: 1343500288, @@ -122,7 +122,7 @@ export namespace Mock { }, 'aarch64-nonfree': { publishedAt: '2025-04-21T21:07:00.249285116Z', - url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.11/startos-0.4.0-alpha.11-33ae46f~dev_aarch64-nonfree.squashfs', + url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.12/startos-0.4.0-alpha.12-33ae46f~dev_aarch64-nonfree.squashfs', commitment: { hash: 'MrCEi4jxbmPS7zAiGk/JSKlMsiuKqQy6RbYOxlGHOIQ=', size: 1653075968, @@ -134,7 +134,7 @@ export namespace Mock { }, raspberrypi: { publishedAt: '2025-04-21T21:16:12.933319237Z', - url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.11/startos-0.4.0-alpha.11-33ae46f~dev_raspberrypi.squashfs', + url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.12/startos-0.4.0-alpha.12-33ae46f~dev_raspberrypi.squashfs', commitment: { hash: '/XTVQRCqY3RK544PgitlKu7UplXjkmzWoXUh2E4HCw0=', size: 1490731008, @@ -146,7 +146,7 @@ export namespace Mock { }, x86_64: { publishedAt: '2025-04-21T21:14:20.246908903Z', - url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.11/startos-0.4.0-alpha.11-33ae46f~dev_x86_64.squashfs', + url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.12/startos-0.4.0-alpha.12-33ae46f~dev_x86_64.squashfs', commitment: { hash: '/6romKTVQGSaOU7FqSZdw0kFyd7P+NBSYNwM3q7Fe44=', size: 1411657728, @@ -158,7 +158,7 @@ export namespace Mock { }, 'x86_64-nonfree': { publishedAt: '2025-04-21T21:15:17.955265284Z', - url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.11/startos-0.4.0-alpha.11-33ae46f~dev_x86_64-nonfree.squashfs', + url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.12/startos-0.4.0-alpha.12-33ae46f~dev_x86_64-nonfree.squashfs', commitment: { hash: 'HCRq9sr/0t85pMdrEgNBeM4x11zVKHszGnD1GDyZbSE=', size: 1731035136,