diff --git a/Cargo.lock b/Cargo.lock index 95dbb65e7f..c63481dcb0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,41 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + [[package]] name = "aho-corasick" version = "1.0.2" @@ -115,6 +150,7 @@ dependencies = [ "scopetime", "serde", "serial_test", + "ssh-key", "tempfile", "thiserror", "unicode-truncate", @@ -142,12 +178,35 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bcrypt-pbkdf" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aeac2e1fe888769f34f05ac343bbef98b14d1ffb292ab69d4608b3abc86f2a2" +dependencies = [ + "blowfish", + "pbkdf2", + "sha2", +] + [[package]] name = "bincode" version = "1.3.3" @@ -178,6 +237,34 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blowfish" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" +dependencies = [ + "byteorder", + "cipher", +] + [[package]] name = "bugreport" version = "0.5.0" @@ -204,6 +291,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytesize" version = "1.3.0" @@ -216,6 +309,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + [[package]] name = "cc" version = "1.0.79" @@ -231,6 +333,17 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + [[package]] name = "chrono" version = "0.4.32" @@ -243,6 +356,16 @@ dependencies = [ "windows-targets 0.52.0", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "clap" version = "4.4.18" @@ -286,12 +409,27 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "core-foundation-sys" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.3.2" @@ -369,6 +507,64 @@ dependencies = [ "winapi", ] +[[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", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f711ade317dd348950a9910f81c5947e3d8907ebd2b83f76203ff1807e6a2bc2" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.32", +] + [[package]] name = "cxx" version = "1.0.90" @@ -393,7 +589,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn", + "syn 1.0.107", ] [[package]] @@ -410,7 +606,7 @@ checksum = "ebf883b7aacd7b2aeb2a7b338648ee19f57c140d4ee8e52c68979c6b2f7f2263" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -426,12 +622,34 @@ dependencies = [ "parking_lot_core", ] +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "diff" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + [[package]] name = "dirs" version = "5.0.1" @@ -459,12 +677,65 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10936778145f3bea71fd9bf61332cce28c28e96a380714f7ab34838b80733fd6" +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +dependencies = [ + "curve25519-dalek", + "ed25519", + "sha2", +] + [[package]] name = "either" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +[[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", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "env_logger" version = "0.10.2" @@ -507,6 +778,22 @@ dependencies = [ "instant", ] +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" + [[package]] name = "filetime" version = "0.2.20" @@ -647,6 +934,17 @@ dependencies = [ "thread_local", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + [[package]] name = "getrandom" version = "0.2.8" @@ -668,6 +966,16 @@ dependencies = [ "regex", ] +[[package]] +name = "ghash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +dependencies = [ + "opaque-debug", + "polyval", +] + [[package]] name = "gimli" version = "0.27.3" @@ -693,7 +1001,7 @@ dependencies = [ "proc-macro-hack", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -778,6 +1086,17 @@ dependencies = [ "which", ] +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -790,6 +1109,15 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + [[package]] name = "humantime" version = "2.1.0" @@ -860,6 +1188,16 @@ dependencies = [ "libc", ] +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "block-padding", + "generic-array", +] + [[package]] name = "instant" version = "0.1.12" @@ -953,12 +1291,15 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin", +] [[package]] name = "libc" -version = "0.2.139" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libgit2-sys" @@ -974,6 +1315,12 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + [[package]] name = "libssh2-sys" version = "0.3.0" @@ -1095,6 +1442,44 @@ dependencies = [ "notify", ] +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.15" @@ -1102,6 +1487,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -1141,6 +1527,12 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "openssl-probe" version = "0.1.5" @@ -1175,6 +1567,44 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[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", +] + +[[package]] +name = "p384" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[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", + "sha2", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -1198,6 +1628,24 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -1234,12 +1682,68 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +[[package]] +name = "platforms" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "pretty_assertions" version = "1.4.0" @@ -1250,6 +1754,15 @@ dependencies = [ "yansi", ] +[[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-error" version = "1.0.4" @@ -1259,7 +1772,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.107", "version_check", ] @@ -1298,6 +1811,35 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "ratatui" version = "0.21.0" @@ -1381,6 +1923,16 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "ron" version = "0.8.0" @@ -1392,12 +1944,42 @@ dependencies = [ "serde", ] +[[package]] +name = "rsa" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "sha2", + "signature", + "spki", + "subtle", + "zeroize", +] + [[package]] name = "rustc-demangle" version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.36.16" @@ -1446,6 +2028,26 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" + [[package]] name = "serde" version = "1.0.156" @@ -1463,7 +2065,7 @@ checksum = "d7e29c4601e36bcec74a223228dce795f4cd3616341a4af93520ca1a837c087d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1499,7 +2101,18 @@ checksum = "079a83df15f85d89a68d64ae1238f142f172b1fa915d0d76b26a7cba1b659a69" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", ] [[package]] @@ -1547,6 +2160,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + [[package]] name = "simplelog" version = "0.12.1" @@ -1578,6 +2201,73 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "ssh-cipher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caac132742f0d33c3af65bfcde7f6aa8f62f0e991d80db99149eb9d44708784f" +dependencies = [ + "aes", + "aes-gcm", + "cbc", + "chacha20", + "cipher", + "ctr", + "poly1305", + "ssh-encoding", + "subtle", +] + +[[package]] +name = "ssh-encoding" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9242b9ef4108a78e8cd1a2c98e193ef372437f8c22be363075233321dd4a15" +dependencies = [ + "base64ct", + "pem-rfc7468", + "sha2", +] + +[[package]] +name = "ssh-key" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01f8f4ea73476c0aa5d5e6a75ce1e8634e2c3f82005ef3bbed21547ac57f2bf7" +dependencies = [ + "bcrypt-pbkdf", + "ed25519-dalek", + "num-bigint-dig", + "p256", + "p384", + "p521", + "rand_core", + "rsa", + "sec1", + "sha2", + "signature", + "ssh-cipher", + "ssh-encoding", + "subtle", + "zeroize", +] + [[package]] name = "strsim" version = "0.10.0" @@ -1602,9 +2292,15 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + [[package]] name = "syn" version = "1.0.107" @@ -1616,6 +2312,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syntect" version = "5.1.0" @@ -1685,7 +2392,7 @@ checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1740,6 +2447,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "unicode-bidi" version = "0.3.10" @@ -1782,6 +2495,16 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + [[package]] name = "url" version = "2.5.0" @@ -1848,7 +2571,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.107", "wasm-bindgen-shared", ] @@ -1870,7 +2593,7 @@ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2141,3 +2864,9 @@ name = "yansi" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/Cargo.toml b/Cargo.toml index 970fe46409..84fc80774a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,7 +59,7 @@ tempfile = "3.4" maintenance = { status = "actively-developed" } [features] -default = ["ghemoji", "regex-fancy", "trace-libgit", "vendor-openssl"] +default = ["asyncgit/common-lib", "ghemoji", "regex-fancy", "trace-libgit", "vendor-openssl"] ghemoji = ["gh-emoji"] # regex-* features are mutually exclusive. regex-fancy = ["syntect/regex-fancy"] diff --git a/asyncgit/Cargo.toml b/asyncgit/Cargo.toml index 67fedb9e5a..5a7c5bd67b 100644 --- a/asyncgit/Cargo.toml +++ b/asyncgit/Cargo.toml @@ -27,6 +27,7 @@ rayon = "1.8" rayon-core = "1.12" scopetime = { path = "../scopetime", version = "0.1" } serde = { version = "1.0", features = ["derive"] } +ssh-key = { version = "0.6.4", features = ["crypto", "encryption"] } thiserror = "1.0" unicode-truncate = "0.2.0" url = "2.5" @@ -39,6 +40,7 @@ serial_test = "1.0" tempfile = "3.4" [features] -default = ["trace-libgit"] +common-lib = [] +default = ["common-lib", "trace-libgit"] trace-libgit = [] vendor-openssl = ["openssl-sys"] diff --git a/asyncgit/src/error.rs b/asyncgit/src/error.rs index 6ede042230..0cbaf28d96 100644 --- a/asyncgit/src/error.rs +++ b/asyncgit/src/error.rs @@ -84,6 +84,10 @@ pub enum Error { /// #[error("git hook error: {0}")] Hooks(#[from] git2_hooks::HooksError), + + /// + #[error("ssh key error: {0}")] + SshKeyError(#[from] ssh_key::Error), } /// diff --git a/asyncgit/src/lib.rs b/asyncgit/src/lib.rs index d03ed30d5e..a93582a2de 100644 --- a/asyncgit/src/lib.rs +++ b/asyncgit/src/lib.rs @@ -75,6 +75,8 @@ pub use crate::{ treefiles::AsyncTreeFilesJob, }; pub use git2::message_prettify; +#[cfg(feature = "common-lib")] +pub use ssh_key; use std::{ collections::hash_map::DefaultHasher, hash::{Hash, Hasher}, diff --git a/asyncgit/src/sync/blame.rs b/asyncgit/src/sync/blame.rs index 92edc991d0..9ff0e5259f 100644 --- a/asyncgit/src/sync/blame.rs +++ b/asyncgit/src/sync/blame.rs @@ -175,7 +175,7 @@ mod tests { File::create(root.join(file_path))?.write_all(b"line 1\n")?; stage_add_file(repo_path, file_path)?; - commit(repo_path, "first commit")?; + commit(repo_path, "first commit", None)?; let blame = blame_file(repo_path, "foo", None)?; @@ -199,7 +199,7 @@ mod tests { file.write(b"line 2\n")?; stage_add_file(repo_path, file_path)?; - commit(repo_path, "second commit")?; + commit(repo_path, "second commit", None)?; let blame = blame_file(repo_path, "foo", None)?; @@ -233,7 +233,7 @@ mod tests { assert_eq!(blame.lines.len(), 2); stage_add_file(repo_path, file_path)?; - commit(repo_path, "third commit")?; + commit(repo_path, "third commit", None)?; let blame = blame_file(repo_path, "foo", None)?; @@ -258,7 +258,7 @@ mod tests { .unwrap(); stage_add_file(repo_path, file_path).unwrap(); - commit(repo_path, "first commit").unwrap(); + commit(repo_path, "first commit", None).unwrap(); assert!(blame_file(repo_path, "bar\\foo", None).is_ok()); } diff --git a/asyncgit/src/sync/commit.rs b/asyncgit/src/sync/commit.rs index d1af74d85d..b37be0a5da 100644 --- a/asyncgit/src/sync/commit.rs +++ b/asyncgit/src/sync/commit.rs @@ -5,6 +5,7 @@ use crate::{ }; use git2::{ErrorCode, ObjectType, Repository, Signature}; use scopetime::scope_time; +use ssh_key::{HashAlg, LineEnding, PrivateKey}; /// pub fn amend( @@ -61,7 +62,11 @@ pub(crate) fn signature_allow_undefined_name( } /// this does not run any git hooks, git-hooks have to be executed manually, checkout `hooks_commit_msg` for example -pub fn commit(repo_path: &RepoPath, msg: &str) -> Result { +pub fn commit( + repo_path: &RepoPath, + msg: &str, + sk: Option<&PrivateKey>, +) -> Result { scope_time!("commit"); let repo = repo(repo_path)?; @@ -78,17 +83,49 @@ pub fn commit(repo_path: &RepoPath, msg: &str) -> Result { }; let parents = parents.iter().collect::>(); - - Ok(repo - .commit( - Some("HEAD"), + if let Some(sk) = sk { + let buffer = repo.commit_create_buffer( &signature, &signature, msg, &tree, parents.as_slice(), - )? - .into()) + )?; + let content = String::from_utf8(buffer.to_vec())?; + let sig = sk + .sign("git", HashAlg::Sha256, &buffer)? + .to_pem(LineEnding::LF)?; + let commit_id = repo.commit_signed(&content, &sig, None)?; + match repo.head() { + Ok(mut head) => { + head.set_target(commit_id, msg)?; + } + Err(_) => { + let config = repo.config()?; + let default_branch_name = config + .get_str("init.defaultBranch") + .unwrap_or("master"); + repo.reference( + &format!("refs/heads/{}", default_branch_name), + commit_id, + true, + msg, + )?; + } + } + Ok(commit_id.into()) + } else { + Ok(repo + .commit( + Some("HEAD"), + &signature, + &signature, + msg, + &tree, + parents.as_slice(), + )? + .into()) + } } /// Tag a commit. @@ -162,7 +199,7 @@ mod tests { assert_eq!(get_statuses(repo_path), (0, 1)); - commit(repo_path, "commit msg").unwrap(); + commit(repo_path, "commit msg", None).unwrap(); assert_eq!(get_statuses(repo_path), (0, 0)); } @@ -188,7 +225,7 @@ mod tests { assert_eq!(get_statuses(repo_path), (0, 1)); - commit(repo_path, "commit msg").unwrap(); + commit(repo_path, "commit msg", None).unwrap(); assert_eq!(get_statuses(repo_path), (0, 0)); } @@ -205,7 +242,7 @@ mod tests { File::create(root.join(file_path1))?.write_all(b"test1")?; stage_add_file(repo_path, file_path1)?; - let id = commit(repo_path, "commit msg")?; + let id = commit(repo_path, "commit msg", None)?; assert_eq!(count_commits(&repo, 10), 1); @@ -244,7 +281,7 @@ mod tests { stage_add_file(repo_path, file_path)?; - let new_id = commit(repo_path, "commit msg")?; + let new_id = commit(repo_path, "commit msg", None)?; tag_commit(repo_path, &new_id, "tag", None)?; @@ -286,7 +323,7 @@ mod tests { stage_add_file(repo_path, file_path)?; - let new_id = commit(repo_path, "commit msg")?; + let new_id = commit(repo_path, "commit msg", None)?; tag_commit(repo_path, &new_id, "tag", Some("tag-message"))?; @@ -322,13 +359,13 @@ mod tests { repo.config()?.remove("user.email")?; - let error = commit(repo_path, "commit msg"); + let error = commit(repo_path, "commit msg", None); assert!(matches!(error, Err(_))); repo.config()?.set_str("user.email", "email")?; - let success = commit(repo_path, "commit msg"); + let success = commit(repo_path, "commit msg", None); assert!(matches!(success, Ok(_))); assert_eq!(count_commits(&repo, 10), 1); @@ -358,7 +395,7 @@ mod tests { repo.config()?.remove("user.name")?; - let mut success = commit(repo_path, "commit msg"); + let mut success = commit(repo_path, "commit msg", None); assert!(matches!(success, Ok(_))); assert_eq!(count_commits(&repo, 10), 1); @@ -371,7 +408,7 @@ mod tests { repo.config()?.set_str("user.name", "name")?; - success = commit(repo_path, "commit msg"); + success = commit(repo_path, "commit msg", None); assert!(matches!(success, Ok(_))); assert_eq!(count_commits(&repo, 10), 2); diff --git a/asyncgit/src/sync/commit_details.rs b/asyncgit/src/sync/commit_details.rs index 8de0894b71..4b516b1f12 100644 --- a/asyncgit/src/sync/commit_details.rs +++ b/asyncgit/src/sync/commit_details.rs @@ -144,7 +144,7 @@ mod tests { stage_add_file(repo_path, file_path).unwrap(); let msg = invalidstring::invalid_utf8("test msg"); - let id = commit(repo_path, msg.as_str()).unwrap(); + let id = commit(repo_path, msg.as_str(), None).unwrap(); let res = get_commit_details(repo_path, id).unwrap(); diff --git a/asyncgit/src/sync/commit_files.rs b/asyncgit/src/sync/commit_files.rs index 772b910e2f..35ed76d3a9 100644 --- a/asyncgit/src/sync/commit_files.rs +++ b/asyncgit/src/sync/commit_files.rs @@ -180,7 +180,7 @@ mod tests { stage_add_file(repo_path, file_path)?; - let id = commit(repo_path, "commit msg")?; + let id = commit(repo_path, "commit msg", None)?; let diff = get_commit_files(repo_path, id, None)?; @@ -222,7 +222,7 @@ mod tests { File::create(root.join(file_path1))?.write_all(b"test")?; stage_add_file(repo_path, file_path1)?; - commit(repo_path, "c1")?; + commit(repo_path, "c1", None)?; File::create(root.join(file_path1))? .write_all(b"modified")?; diff --git a/asyncgit/src/sync/commit_revert.rs b/asyncgit/src/sync/commit_revert.rs index 2d66a2a1d4..75faa54dc9 100644 --- a/asyncgit/src/sync/commit_revert.rs +++ b/asyncgit/src/sync/commit_revert.rs @@ -4,6 +4,7 @@ use crate::{ sync::{repository::repo, utils::read_file}, }; use scopetime::scope_time; +use ssh_key::PrivateKey; const GIT_REVERT_HEAD_FILE: &str = "REVERT_HEAD"; @@ -40,10 +41,11 @@ pub fn revert_head(repo_path: &RepoPath) -> Result { pub fn commit_revert( repo_path: &RepoPath, msg: &str, + sk: Option<&PrivateKey>, ) -> Result { scope_time!("commit_revert"); - let id = crate::sync::commit(repo_path, msg)?; + let id = crate::sync::commit(repo_path, msg, sk)?; repo(repo_path)?.cleanup_state()?; diff --git a/asyncgit/src/sync/commits_info.rs b/asyncgit/src/sync/commits_info.rs index 1f049e9003..f813fb7c10 100644 --- a/asyncgit/src/sync/commits_info.rs +++ b/asyncgit/src/sync/commits_info.rs @@ -172,10 +172,10 @@ mod tests { File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - let c1 = commit(repo_path, "commit1").unwrap(); + let c1 = commit(repo_path, "commit1", None).unwrap(); File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - let c2 = commit(repo_path, "commit2").unwrap(); + let c2 = commit(repo_path, "commit2", None).unwrap(); let res = get_commits_info(repo_path, &[c2, c1], 50).unwrap(); @@ -197,7 +197,7 @@ mod tests { File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - let c1 = commit(repo_path, "subject\nbody").unwrap(); + let c1 = commit(repo_path, "subject\nbody", None).unwrap(); let res = get_commits_info(repo_path, &[c1], 50).unwrap(); @@ -219,7 +219,7 @@ mod tests { stage_add_file(repo_path, file_path).unwrap(); let msg = invalidstring::invalid_utf8("test msg"); - commit(repo_path, msg.as_str()).unwrap(); + commit(repo_path, msg.as_str(), None).unwrap(); let res = get_commits_info( repo_path, @@ -245,7 +245,8 @@ mod tests { let foo_file = Path::new("foo"); File::create(root.join(foo_file))?.write_all(b"a")?; stage_add_file(repo_path, foo_file).unwrap(); - let c1 = commit(repo_path, "subject: foo\nbody").unwrap(); + let c1 = + commit(repo_path, "subject: foo\nbody", None).unwrap(); let c1_rev = c1.get_short_string(); assert_eq!( diff --git a/asyncgit/src/sync/diff.rs b/asyncgit/src/sync/diff.rs index f02e1be3df..fb2de7e466 100644 --- a/asyncgit/src/sync/diff.rs +++ b/asyncgit/src/sync/diff.rs @@ -599,7 +599,7 @@ mod tests { stage_add_file(repo_path, file_path).unwrap(); - commit(repo_path, "commit").unwrap(); + commit(repo_path, "commit", None).unwrap(); File::create(root.join(file_path))?.write_all(b"\x00\x02")?; @@ -655,13 +655,13 @@ mod tests { stage_add_file(repo_path, file_path).unwrap(); - commit(repo_path, "").unwrap(); + commit(repo_path, "", None).unwrap(); File::create(root.join(file_path))?.write_all(b"\x00\x02")?; stage_add_file(repo_path, file_path).unwrap(); - let id = commit(repo_path, "").unwrap(); + let id = commit(repo_path, "", None).unwrap(); let diff = get_diff_commit(repo_path, id, String::new(), None) diff --git a/asyncgit/src/sync/logwalker.rs b/asyncgit/src/sync/logwalker.rs index b13a9e5a26..a0eb33b2d6 100644 --- a/asyncgit/src/sync/logwalker.rs +++ b/asyncgit/src/sync/logwalker.rs @@ -135,10 +135,10 @@ mod tests { File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - commit(repo_path, "commit1").unwrap(); + commit(repo_path, "commit1", None).unwrap(); File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - let oid2 = commit(repo_path, "commit2").unwrap(); + let oid2 = commit(repo_path, "commit2", None).unwrap(); let mut items = Vec::new(); let mut walk = LogWalker::new(&repo, 1)?; @@ -160,10 +160,10 @@ mod tests { File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - commit(repo_path, "commit1").unwrap(); + commit(repo_path, "commit1", None).unwrap(); File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - let oid2 = commit(repo_path, "commit2").unwrap(); + let oid2 = commit(repo_path, "commit2", None).unwrap(); let mut items = Vec::new(); let mut walk = LogWalker::new(&repo, 100)?; @@ -195,17 +195,20 @@ mod tests { File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(&repo_path, file_path).unwrap(); - let _first_commit_id = commit(&repo_path, "commit1").unwrap(); + let _first_commit_id = + commit(&repo_path, "commit1", None).unwrap(); File::create(root.join(second_file_path))?.write_all(b"a")?; stage_add_file(&repo_path, second_file_path).unwrap(); - let second_commit_id = commit(&repo_path, "commit2").unwrap(); + let second_commit_id = + commit(&repo_path, "commit2", None).unwrap(); File::create(root.join(file_path))?.write_all(b"b")?; stage_add_file(&repo_path, file_path).unwrap(); - let _third_commit_id = commit(&repo_path, "commit3").unwrap(); + let _third_commit_id = + commit(&repo_path, "commit3", None).unwrap(); let diff_contains_baz = diff_contains_file("baz".into()); diff --git a/asyncgit/src/sync/mod.rs b/asyncgit/src/sync/mod.rs index 83683a9ea0..8285129de2 100644 --- a/asyncgit/src/sync/mod.rs +++ b/asyncgit/src/sync/mod.rs @@ -162,6 +162,7 @@ mod tests { commit( &repo.workdir().unwrap().to_str().unwrap().into(), commit_name, + None, ) .unwrap() } diff --git a/asyncgit/src/sync/remotes/push.rs b/asyncgit/src/sync/remotes/push.rs index 37cdd4a9ca..a48c1d369a 100644 --- a/asyncgit/src/sync/remotes/push.rs +++ b/asyncgit/src/sync/remotes/push.rs @@ -226,6 +226,7 @@ mod tests { sync::commit( &tmp_repo_dir.path().to_str().unwrap().into(), "repo_1_commit", + None, ) .unwrap(); @@ -249,6 +250,7 @@ mod tests { sync::commit( &tmp_other_repo_dir.path().to_str().unwrap().into(), "repo_2_commit", + None, ) .unwrap(); @@ -323,6 +325,7 @@ mod tests { let repo_1_commit = sync::commit( &tmp_repo_dir.path().to_str().unwrap().into(), "repo_1_commit", + None, ) .unwrap(); @@ -367,6 +370,7 @@ mod tests { let repo_2_commit = sync::commit( &tmp_other_repo_dir.path().to_str().unwrap().into(), "repo_2_commit", + None, ) .unwrap(); diff --git a/asyncgit/src/sync/reset.rs b/asyncgit/src/sync/reset.rs index 4142255954..518fd11e03 100644 --- a/asyncgit/src/sync/reset.rs +++ b/asyncgit/src/sync/reset.rs @@ -189,7 +189,7 @@ mod tests { } stage_add_all(repo_path, "*", None).unwrap(); - commit(repo_path, "msg").unwrap(); + commit(repo_path, "msg", None).unwrap(); { File::create(root.join("foo/file1.txt"))? diff --git a/asyncgit/src/sync/reword.rs b/asyncgit/src/sync/reword.rs index 4259498d79..419a71654c 100644 --- a/asyncgit/src/sync/reword.rs +++ b/asyncgit/src/sync/reword.rs @@ -34,7 +34,7 @@ pub fn reword( /// Gets the current branch the user is on. /// Returns none if they are not on a branch /// and Err if there was a problem finding the branch -fn get_current_branch( +pub fn get_current_branch( repo: &Repository, ) -> Result> { for b in repo.branches(None)? { diff --git a/asyncgit/src/sync/stash.rs b/asyncgit/src/sync/stash.rs index fc5d69b73d..da67e0ecfe 100644 --- a/asyncgit/src/sync/stash.rs +++ b/asyncgit/src/sync/stash.rs @@ -222,7 +222,7 @@ mod tests { File::create(root.join(file_path1))?.write_all(b"test")?; stage_add_file(repo_path, file_path1)?; - commit(repo_path, "c1")?; + commit(repo_path, "c1", None)?; File::create(root.join(file_path1))? .write_all(b"modified")?; diff --git a/asyncgit/src/sync/utils.rs b/asyncgit/src/sync/utils.rs index a5ec1b3e9b..fc82508524 100644 --- a/asyncgit/src/sync/utils.rs +++ b/asyncgit/src/sync/utils.rs @@ -388,7 +388,7 @@ mod tests { stage_add_file(repo_path, file_path).unwrap(); - commit(repo_path, "commit msg").unwrap(); + commit(repo_path, "commit msg", None).unwrap(); // delete the file now assert_eq!(remove_file(full_path).is_ok(), true); diff --git a/src/app.rs b/src/app.rs index 2bdb2754ef..69e918a992 100644 --- a/src/app.rs +++ b/src/app.rs @@ -31,6 +31,7 @@ use crate::{ AsyncAppNotification, AsyncNotification, }; use anyhow::{bail, Result}; +use asyncgit::ssh_key::private::PrivateKey; use asyncgit::{ sync::{ self, @@ -124,6 +125,7 @@ impl App { input: Input, theme: Theme, key_config: KeyConfig, + ssh_secret_key: Option, ) -> Result { log::trace!("open repo at: {:?}", &repo); @@ -150,6 +152,7 @@ impl App { theme.clone(), key_config.clone(), options.clone(), + ssh_secret_key, ), blame_file_popup: BlameFileComponent::new( &repo, diff --git a/src/args.rs b/src/args.rs index 0a45fb2864..56347d0309 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,5 +1,6 @@ use crate::bug_report; use anyhow::{anyhow, Result}; +use asyncgit::ssh_key::PrivateKey; use asyncgit::sync::RepoPath; use clap::{ crate_authors, crate_description, crate_name, crate_version, Arg, @@ -8,7 +9,7 @@ use clap::{ use simplelog::{Config, LevelFilter, WriteLogger}; use std::{ env, - fs::{self, File}, + fs::{self, read, File}, path::PathBuf, }; @@ -16,6 +17,7 @@ pub struct CliArgs { pub theme: PathBuf, pub repo_path: RepoPath, pub notify_watcher: bool, + pub ssh_key: Option, } pub fn process_cmdline() -> Result { @@ -54,6 +56,35 @@ pub fn process_cmdline() -> Result { get_app_config_path()?.join("theme.ron") }; + let default_ssh_path = "~/.ssh/id_rsa".to_string(); + let arg_ssh_key_path = arg_matches + .get_one::("ssh_key_path") + .unwrap_or(&default_ssh_path); + + let ssh_key_abs_path = if let Some(ssh_key_path) = + arg_ssh_key_path.strip_prefix("~") + { + dirs::home_dir().map(|home| { + home.join( + ssh_key_path + .strip_prefix("/") + .unwrap_or(ssh_key_path), + ) + }) + } else { + Some(PathBuf::from(arg_ssh_key_path)) + }; + + let mut ssh_key = ssh_key_abs_path + .and_then(|p| read(p).ok()) + .and_then(|bytes| PrivateKey::from_openssh(bytes).ok()); + if let Some(password) = + arg_matches.get_one::("ssh_key_password") + { + ssh_key = ssh_key + .and_then(|key| key.decrypt(password.as_bytes()).ok()) + } + let notify_watcher: bool = *arg_matches.get_one("watcher").unwrap_or(&false); @@ -61,6 +92,7 @@ pub fn process_cmdline() -> Result { theme, repo_path, notify_watcher, + ssh_key, }) } @@ -123,6 +155,21 @@ fn app() -> ClapApp { .env("GIT_WORK_TREE") .num_args(1), ) + .arg( + Arg::new("ssh_key_path") + .help("Set ssh secret key for sign commit") + .short('s') + .long("ssh-key-path") + .env("SSH_KEY_PATH") + .num_args(1), + ) + .arg( + Arg::new("ssh_key_password") + .help("password for ssh secret key") + .long("ssh-key-password") + .env("SSH_KEY_PASSWORD") + .num_args(1), + ) } fn setup_logging() -> Result<()> { diff --git a/src/components/commit.rs b/src/components/commit.rs index bd762878fd..f6070e385f 100644 --- a/src/components/commit.rs +++ b/src/components/commit.rs @@ -11,6 +11,7 @@ use crate::{ ui::style::SharedTheme, }; use anyhow::{bail, Ok, Result}; +use asyncgit::ssh_key::private::PrivateKey; use asyncgit::{ cached, message_prettify, sync::{ @@ -59,6 +60,7 @@ pub struct CommitComponent { commit_msg_history_idx: usize, options: SharedOptions, verify: bool, + ssh_secret_key: Option, } const FIRST_LINE_LIMIT: usize = 50; @@ -71,6 +73,7 @@ impl CommitComponent { theme: SharedTheme, key_config: SharedKeyConfig, options: SharedOptions, + ssh_secret_key: Option, ) -> Self { Self { queue, @@ -90,6 +93,7 @@ impl CommitComponent { commit_msg_history_idx: 0, options, verify: true, + ssh_secret_key, } } @@ -288,16 +292,22 @@ impl CommitComponent { fn do_commit(&self, msg: &str) -> Result<()> { match &self.mode { - Mode::Normal => sync::commit(&self.repo.borrow(), msg)?, + Mode::Normal => sync::commit( + &self.repo.borrow(), + msg, + self.ssh_secret_key.as_ref(), + )?, Mode::Amend(amend) => { sync::amend(&self.repo.borrow(), *amend, msg)? } Mode::Merge(ids) => { sync::merge_commit(&self.repo.borrow(), msg, ids)? } - Mode::Revert => { - sync::commit_revert(&self.repo.borrow(), msg)? - } + Mode::Revert => sync::commit_revert( + &self.repo.borrow(), + msg, + self.ssh_secret_key.as_ref(), + )?, Mode::Reword(id) => { let commit = sync::reword(&self.repo.borrow(), *id, msg)?; diff --git a/src/main.rs b/src/main.rs index c0f41a2770..08aea2b99e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,6 +50,7 @@ mod watcher; use crate::{app::App, args::process_cmdline}; use anyhow::{bail, Result}; use app::QuitState; +use asyncgit::ssh_key::private::PrivateKey; use asyncgit::{ sync::{utils::repo_work_dir, RepoPath}, AsyncGitNotification, @@ -162,6 +163,7 @@ fn main() -> Result<()> { &input, updater, &mut terminal, + cliargs.ssh_key.clone(), )?; match quit_state { @@ -183,6 +185,7 @@ fn run_app( input: &Input, updater: Updater, terminal: &mut Terminal>, + ssh_secret_key: Option, ) -> Result { let (tx_git, rx_git) = unbounded(); let (tx_app, rx_app) = unbounded(); @@ -208,6 +211,7 @@ fn run_app( input.clone(), theme, key_config, + ssh_secret_key, )?; let mut spinner = Spinner::default();