diff --git a/Cargo.lock b/Cargo.lock index 15bb8f3..0618d44 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,6 +61,21 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse 0.2.7", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + [[package]] name = "anstream" version = "1.0.0" @@ -68,7 +83,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", - "anstyle-parse", + "anstyle-parse 1.0.0", "anstyle-query", "anstyle-wincon", "colorchoice", @@ -82,6 +97,15 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + [[package]] name = "anstyle-parse" version = "1.0.0" @@ -328,7 +352,7 @@ version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ - "anstream", + "anstream 1.0.0", "anstyle", "clap_lex", "strsim", @@ -383,6 +407,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "const-oid" version = "0.10.2" @@ -488,6 +518,18 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.7" @@ -534,9 +576,9 @@ dependencies = [ "cfg-if", "cpufeatures 0.2.17", "curve25519-dalek-derive", - "digest", - "fiat-crypto", - "rand_core", + "digest 0.11.0-rc.10", + "fiat-crypto 0.3.0", + "rand_core 0.9.5", "rustc_version", "serde", "subtle", @@ -615,14 +657,24 @@ dependencies = [ "syn", ] +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid 0.9.6", + "zeroize", +] + [[package]] name = "der" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71fd89660b2dc699704064e59e9dba0147b903e85319429e131620d022be411b" dependencies = [ - "const-oid", - "pem-rfc7468", + "const-oid 0.10.2", + "pem-rfc7468 1.0.0", "zeroize", ] @@ -701,11 +753,32 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" dependencies = [ - "block-buffer", - "const-oid", + "block-buffer 0.11.0", + "const-oid 0.10.2", "crypto-common 0.2.1", ] +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.61.2", +] + [[package]] name = "dispatch2" version = "0.3.1" @@ -761,11 +834,12 @@ dependencies = [ "duct", "hex", "iroh", + "iroh-persist", "iroh-tickets", "n0-error", "nix", "noq", - "rand", + "rand 0.9.2", "tempfile", "tokio", "tokio-util", @@ -773,15 +847,53 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der 0.7.10", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature 2.2.0", + "spki 0.7.3", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8 0.10.2", + "signature 2.2.0", +] + [[package]] name = "ed25519" version = "3.0.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6e914c7c52decb085cea910552e24c63ac019e3ab8bf001ff736da9a9d9d890" dependencies = [ - "pkcs8", + "pkcs8 0.11.0-rc.11", + "serde", + "signature 3.0.0-rc.10", +] + +[[package]] +name = "ed25519-dalek" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek 4.1.3", + "ed25519 2.2.3", "serde", - "signature", + "sha2 0.10.9", + "subtle", + "zeroize", ] [[package]] @@ -790,12 +902,31 @@ version = "3.0.0-pre.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "053618a4c3d3bc24f188aa660ae75a46eeab74ef07fb415c61431e5e7cd4749b" dependencies = [ - "curve25519-dalek", - "ed25519", - "rand_core", + "curve25519-dalek 5.0.0-pre.1", + "ed25519 3.0.0-rc.4", + "rand_core 0.9.5", "serde", - "sha2", - "signature", + "sha2 0.11.0-rc.2", + "signature 3.0.0-rc.10", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1", "subtle", "zeroize", ] @@ -829,6 +960,27 @@ dependencies = [ "syn", ] +[[package]] +name = "env_filter" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a1c3cc8e57274ec99de65301228b537f1e4eedc1b8e0f9411c6caac8ae7308f" +dependencies = [ + "log", +] + +[[package]] +name = "env_logger" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2daee4ea451f429a58296525ddf28b45a3b64f1acf6587e2067437bb11e218d" +dependencies = [ + "anstream 0.6.21", + "anstyle", + "env_filter", + "log", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -863,6 +1015,22 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "fiat-crypto" version = "0.3.0" @@ -1039,6 +1207,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -1092,6 +1261,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "h2" version = "0.4.13" @@ -1238,7 +1418,7 @@ dependencies = [ "ndk-context", "once_cell", "parking_lot", - "rand", + "rand 0.9.2", "resolv-conf", "rustls", "smallvec", @@ -1249,6 +1429,15 @@ dependencies = [ "tracing", ] +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "http" version = "1.4.0" @@ -1573,7 +1762,7 @@ dependencies = [ "ctutils", "data-encoding", "derive_more", - "ed25519-dalek", + "ed25519-dalek 3.0.0-pre.1", "futures-util", "getrandom 0.4.2", "hickory-resolver", @@ -1594,7 +1783,7 @@ dependencies = [ "pin-project", "pkcs8", "portable-atomic", - "rand", + "rand 0.9.2", "reqwest", "rustc-hash", "rustls", @@ -1619,7 +1808,7 @@ version = "0.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "738865784637830fb14204ebd3047922db83bc1816a59027af29579b9c27bd99" dependencies = [ - "curve25519-dalek", + "curve25519-dalek 5.0.0-pre.1", "data-encoding", "data-encoding-macro", "derive_more", @@ -1629,7 +1818,7 @@ dependencies = [ "n0-error", "rand", "serde", - "sha2", + "sha2 0.11.0-rc.2", "url", "zeroize", "zeroize_derive", @@ -1677,6 +1866,23 @@ dependencies = [ "syn", ] +[[package]] +name = "iroh-persist" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222e4c81746dd5d98bb3de94233a37014e53714ef72149c6a0b68f08475a9901" +dependencies = [ + "dirs", + "ed25519-dalek 2.2.0", + "iroh", + "n0-error", + "rand 0.9.2", + "ssh-key", + "test-log", + "tokio", + "tracing", +] + [[package]] name = "iroh-relay" version = "0.98.0" @@ -1705,7 +1911,7 @@ dependencies = [ "num_enum", "pin-project", "postcard", - "rand", + "rand 0.9.2", "reqwest", "rustls", "rustls-pki-types", @@ -1840,6 +2046,9 @@ name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin 0.9.8", +] [[package]] name = "leb128fmt" @@ -1859,6 +2068,15 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" +[[package]] +name = "libredox" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a" +dependencies = [ + "libc", +] + [[package]] name = "linux-raw-sys" version = "0.12.1" @@ -2188,7 +2406,7 @@ dependencies = [ "getrandom 0.4.2", "identity-hash", "lru-slab", - "rand", + "rand 0.9.2", "ring", "rustc-hash", "rustls", @@ -2224,12 +2442,48 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "num-bigint-dig" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" +dependencies = [ + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + [[package]] name = "num-conv" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -2237,6 +2491,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -2351,6 +2606,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "os_pipe" version = "1.2.3" @@ -2361,6 +2622,44 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2 0.10.9", +] + +[[package]] +name = "p384" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2 0.10.9", +] + +[[package]] +name = "p521" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc9e2161f1f215afdfce23677034ae137bbd45016a880c2eb3ba8eb95f085b2" +dependencies = [ + "base16ct", + "ecdsa", + "elliptic-curve", + "primeorder", + "rand_core 0.6.4", + "sha2 0.10.9", +] + [[package]] name = "papaya" version = "0.2.4" @@ -2406,6 +2705,15 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "pem-rfc7468" version = "1.0.0" @@ -2463,8 +2771,8 @@ version = "0.11.0-rc.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12922b6296c06eb741b02d7b5161e3aaa22864af38dfa025a1a3ba3f68c84577" dependencies = [ - "der", - "spki", + "der 0.8.0", + "spki 0.8.0-rc.4", ] [[package]] @@ -2562,6 +2870,15 @@ dependencies = [ "syn", ] +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "proc-macro-crate" version = "3.5.0" @@ -2630,6 +2947,17 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_users" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +dependencies = [ + "getrandom 0.2.17", + "libredox", + "thiserror 2.0.18", +] + [[package]] name = "regex-automata" version = "0.4.14" @@ -2690,6 +3018,16 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7" +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "ring" version = "0.17.14" @@ -2704,6 +3042,27 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rsa" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" +dependencies = [ + "const-oid 0.9.6", + "digest 0.10.7", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sha2 0.10.9", + "signature 2.2.0", + "spki 0.7.3", + "subtle", + "zeroize", +] + [[package]] name = "rustc-hash" version = "2.1.2" @@ -2849,6 +3208,20 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der 0.7.10", + "generic-array", + "pkcs8 0.10.2", + "subtle", + "zeroize", +] + [[package]] name = "security-framework" version = "3.7.0" @@ -3027,6 +3400,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + [[package]] name = "signature" version = "3.0.0-rc.10" @@ -3125,7 +3508,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" dependencies = [ "base64ct", - "der", + "der 0.8.0", +] + +[[package]] +name = "ssh-cipher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caac132742f0d33c3af65bfcde7f6aa8f62f0e991d80db99149eb9d44708784f" +dependencies = [ + "cipher", + "ssh-encoding", +] + +[[package]] +name = "ssh-encoding" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9242b9ef4108a78e8cd1a2c98e193ef372437f8c22be363075233321dd4a15" +dependencies = [ + "base64ct", + "pem-rfc7468 0.7.0", + "sha2 0.10.9", +] + +[[package]] +name = "ssh-key" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b86f5297f0f04d08cabaa0f6bff7cb6aec4d9c3b49d87990d63da9d9156a8c3" +dependencies = [ + "ed25519-dalek 2.2.0", + "p256", + "p384", + "p521", + "rand_core 0.6.4", + "rsa", + "sec1", + "sha2 0.10.9", + "signature 2.2.0", + "ssh-cipher", + "ssh-encoding", + "subtle", + "zeroize", ] [[package]] @@ -3238,6 +3663,28 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "test-log" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d53ac171c92a39e4769491c4b4dde7022c60042254b5fc044ae409d34a24d4" +dependencies = [ + "env_logger", + "test-log-macros", + "tracing-subscriber", +] + +[[package]] +name = "test-log-macros" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be35209fd0781c5401458ab66e4f98accf63553e8fae7425503e92fdd319783b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "thiserror" version = "1.0.69" @@ -3423,7 +3870,7 @@ dependencies = [ "getrandom 0.4.2", "http", "httparse", - "rand", + "rand 0.9.2", "ring", "rustls-pki-types", "sha1_smol", diff --git a/Cargo.toml b/Cargo.toml index ca5b07a..cf9de2b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,9 @@ clap = { version = "4.4.10", features = ["derive"] } hex = "0.4.3" iroh = { version = "0.98", default-features = false, features = ["tls-ring"] } iroh-tickets = { version = "0.5" } +iroh-persist = "0.1.6" noq = "0.18" +rand = "0.9.2" tokio = { version = "1.34.0", features = ["full"] } tokio-util = "0.7.10" tracing = "0.1.40" diff --git a/src/main.rs b/src/main.rs index 097b12d..a6efe06 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ use std::{ io, net::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs}, - str::FromStr, + path::PathBuf, time::Duration, }; @@ -12,18 +12,18 @@ use iroh::{ endpoint::{presets, Accepting}, Endpoint, EndpointAddr, SecretKey, }; +use iroh_persist::KeyRetriever; use n0_error::{bail_any, ensure_any, AnyError, Result, StdResultExt}; + +#[cfg(unix)] +use tokio::net::{UnixListener, UnixStream}; + use tokio::{ io::{AsyncRead, AsyncWrite, AsyncWriteExt}, select, time::timeout, }; use tokio_util::sync::CancellationToken; -#[cfg(unix)] -use { - std::path::PathBuf, - tokio::net::{UnixListener, UnixStream}, -}; const ONLINE_TIMEOUT: Duration = Duration::from_secs(5); @@ -39,6 +39,11 @@ const ONLINE_TIMEOUT: Duration = Duration::from_secs(5); /// For all subcommands, you can specify a secret key using the IROH_SECRET /// environment variable. If you don't, a random one will be generated. /// +/// For all subcommands, you can specify that the generated key should be +/// persisted at either a default location or a explicitly given file. In that +/// case the key will be read from that location on subsequent runs that specify +/// the same location. If you don't, a fresh key will be generated each time. +/// /// You can also specify a port for the endpoint. If you don't, a random one /// will be chosen. #[derive(Parser, Debug)] @@ -54,7 +59,7 @@ pub enum Commands { /// /// This command only really makes sense when you are providing dumbpipe with a /// secret key. - GenerateTicket, + GenerateTicket(CommonArgs), /// Listen on an endpoint and forward stdin/stdout to the first incoming /// bidi stream. @@ -136,6 +141,13 @@ pub struct CommonArgs { #[clap(long)] pub custom_alpn: Option, + /// Use a persistent node key pair + #[arg(long)] + persist: bool, + /// Write and read the node keys at the given location + #[arg(long)] + persist_at: Option, + /// The verbosity level. Repeat to increase verbosity. #[clap(short = 'v', long, action = clap::ArgAction::Count)] pub verbose: u8, @@ -283,20 +295,13 @@ async fn copy_from_noq( } /// Get the secret key or generate a new one. -/// -/// Print the secret key to stderr if it was generated, so the user can save it. -fn get_or_create_secret() -> Result { - match std::env::var("IROH_SECRET") { - Ok(secret) => SecretKey::from_str(&secret).std_context("invalid secret"), - Err(_) => { - let key = SecretKey::generate(); - eprintln!( - "using secret key {}", - data_encoding::HEXLOWER.encode(&key.to_bytes()) - ); - Ok(key) - } - } +async fn get_or_create_secret(common: &CommonArgs) -> Result { + KeyRetriever::new("dumbpipe") + .persist(common.persist) + .persist_at(common.persist_at.as_ref()) + .get() + .await + .map_err(n0_error::AnyError::from) } /// Create a new iroh endpoint. @@ -358,7 +363,7 @@ async fn forward_bidi( } async fn listen_stdio(args: ListenArgs) -> Result<()> { - let secret_key = get_or_create_secret()?; + let secret_key = get_or_create_secret(&args.common).await?; let endpoint = create_endpoint(secret_key, &args.common, vec![args.common.alpn()?]).await?; // wait for the endpoint to figure out its home relay and addresses before making a ticket if (timeout(ONLINE_TIMEOUT, endpoint.online()).await).is_err() { @@ -422,7 +427,7 @@ async fn listen_stdio(args: ListenArgs) -> Result<()> { } async fn connect_stdio(args: ConnectArgs) -> Result<()> { - let secret_key = get_or_create_secret()?; + let secret_key = get_or_create_secret(&args.common).await?; let endpoint = create_endpoint(secret_key, &args.common, vec![]).await?; let addr = args.ticket.endpoint_addr(); let remote_endpoint_id = addr.id; @@ -462,7 +467,7 @@ async fn connect_tcp(args: ConnectTcpArgs) -> Result<()> { .addr .to_socket_addrs() .std_context(format!("invalid host string {}", args.addr))?; - let secret_key = get_or_create_secret()?; + let secret_key = get_or_create_secret(&args.common).await?; let endpoint = create_endpoint(secret_key, &args.common, vec![]) .await .std_context("unable to bind endpoint")?; @@ -544,7 +549,7 @@ async fn listen_tcp(args: ListenTcpArgs) -> Result<()> { Ok(addrs) => addrs.collect::>(), Err(e) => bail_any!("invalid host string {}: {}", args.host, e), }; - let secret_key = get_or_create_secret()?; + let secret_key = get_or_create_secret(&args.common).await?; let endpoint = create_endpoint(secret_key, &args.common, vec![args.common.alpn()?]).await?; // wait for the endpoint to figure out its address before making a ticket if (timeout(ONLINE_TIMEOUT, endpoint.online()).await).is_err() { @@ -642,7 +647,7 @@ fn create_short_ticket(addr: &EndpointAddr) -> EndpointTicket { /// Listen on an endpoint and forward incoming connections to a Unix socket. async fn listen_unix(args: ListenUnixArgs) -> Result<()> { let socket_path = args.socket_path.clone(); - let secret_key = get_or_create_secret()?; + let secret_key = get_or_create_secret(&args.common).await?; let endpoint = create_endpoint(secret_key, &args.common, vec![args.common.alpn()?]).await?; // wait for the endpoint to figure out its address before making a ticket if (timeout(ONLINE_TIMEOUT, endpoint.online()).await).is_err() { @@ -760,7 +765,7 @@ impl Drop for UnixSocketGuard { /// Listen on a Unix socket and forward connections to an endpoint. async fn connect_unix(args: ConnectUnixArgs) -> Result<()> { let socket_path = args.socket_path.clone(); - let secret_key = get_or_create_secret()?; + let secret_key = get_or_create_secret(&args.common).await?; let endpoint = create_endpoint(secret_key, &args.common, vec![]) .await .std_context("unable to bind endpoint")?; @@ -858,8 +863,8 @@ async fn connect_unix(args: ConnectUnixArgs) -> Result<()> { Ok(()) } -async fn generate_ticket() -> Result<()> { - let secret_key = get_or_create_secret()?; +async fn generate_ticket(args: CommonArgs) -> Result<()> { + let secret_key = get_or_create_secret(&args).await?; let public_key = secret_key.public(); let addr = EndpointAddr::new(public_key); let ticket = EndpointTicket::new(addr); @@ -872,7 +877,7 @@ async fn main() -> Result<()> { tracing_subscriber::fmt::init(); let args = Args::parse(); let res = match args.command { - Commands::GenerateTicket => generate_ticket().await, + Commands::GenerateTicket(args) => generate_ticket(args).await, Commands::Listen(args) => listen_stdio(args).await, Commands::ListenTcp(args) => listen_tcp(args).await, Commands::Connect(args) => connect_stdio(args).await, diff --git a/tests/cli.rs b/tests/cli.rs index cfecd56..98b63f8 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -64,8 +64,8 @@ fn connect_listen_happy() { .stderr_to_stdout() // .reader() .unwrap(); - // read the first 3 lines of the header, and parse the last token as a ticket - let header = read_ascii_lines(3, &mut listen).unwrap(); + // read the first 2 lines of the header, and parse the last token as a ticket + let header = read_ascii_lines(2, &mut listen).unwrap(); let header = String::from_utf8(header).unwrap(); let ticket = header.split_ascii_whitespace().last().unwrap(); let ticket = EndpointTicket::from_str(ticket).unwrap(); @@ -105,8 +105,8 @@ fn connect_listen_custom_alpn_happy() { .stderr_to_stdout() // .reader() .unwrap(); - // read the first 3 lines of the header, and parse the last token as a ticket - let header = read_ascii_lines(3, &mut listen).unwrap(); + // read the first 2 lines of the header, and parse the last token as a ticket + let header = read_ascii_lines(2, &mut listen).unwrap(); let header = String::from_utf8(header).unwrap(); let ticket = header.split_ascii_whitespace().last().unwrap(); let ticket = EndpointTicket::from_str(ticket).unwrap(); @@ -149,8 +149,8 @@ fn connect_listen_ctrlc_connect() { .stderr_to_stdout() // .reader() .unwrap(); - // read the first 3 lines of the header, and parse the last token as a ticket - let header = read_ascii_lines(3, &mut listen).unwrap(); + // read the first 2 lines of the header, and parse the last token as a ticket + let header = read_ascii_lines(2, &mut listen).unwrap(); let header = String::from_utf8(header).unwrap(); let ticket = header.split_ascii_whitespace().last().unwrap(); let ticket = EndpointTicket::from_str(ticket).unwrap(); @@ -189,8 +189,8 @@ fn connect_listen_ctrlc_listen() { .stderr_to_stdout() .reader() .unwrap(); - // read the first 3 lines of the header, and parse the last token as a ticket - let header = read_ascii_lines(3, &mut listen).unwrap(); + // read the first 2 lines of the header, and parse the last token as a ticket + let header = read_ascii_lines(2, &mut listen).unwrap(); let header = String::from_utf8(header).unwrap(); let ticket = header.split_ascii_whitespace().last().unwrap(); let ticket = EndpointTicket::from_str(ticket).unwrap(); @@ -240,7 +240,7 @@ fn listen_tcp_happy() { .stderr_to_stdout() // .reader() .unwrap(); - let header = read_ascii_lines(4, &mut listen_tcp).unwrap(); + let header = read_ascii_lines(3, &mut listen_tcp).unwrap(); let header = String::from_utf8(header).unwrap(); let ticket = header.split_ascii_whitespace().last().unwrap(); let ticket = EndpointTicket::from_str(ticket).unwrap(); @@ -267,7 +267,7 @@ fn connect_tcp_happy() { .stderr_to_stdout() // .reader() .unwrap(); - let header = read_ascii_lines(3, &mut listen).unwrap(); + let header = read_ascii_lines(2, &mut listen).unwrap(); let header = String::from_utf8(header).unwrap(); let ticket = header.split_ascii_whitespace().last().unwrap(); let ticket = EndpointTicket::from_str(ticket).unwrap();