Fetch User Keys - simple tool for fetching SSH keys from various sources
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

ft: improve initial implementation

+850 -101
+649 -48
Cargo.lock
··· 18 18 checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 19 20 20 [[package]] 21 + name = "anstream" 22 + version = "0.6.11" 23 + source = "registry+https://github.com/rust-lang/crates.io-index" 24 + checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" 25 + dependencies = [ 26 + "anstyle", 27 + "anstyle-parse", 28 + "anstyle-query", 29 + "anstyle-wincon", 30 + "colorchoice", 31 + "utf8parse", 32 + ] 33 + 34 + [[package]] 35 + name = "anstyle" 36 + version = "1.0.6" 37 + source = "registry+https://github.com/rust-lang/crates.io-index" 38 + checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" 39 + 40 + [[package]] 41 + name = "anstyle-parse" 42 + version = "0.2.3" 43 + source = "registry+https://github.com/rust-lang/crates.io-index" 44 + checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" 45 + dependencies = [ 46 + "utf8parse", 47 + ] 48 + 49 + [[package]] 50 + name = "anstyle-query" 51 + version = "1.0.2" 52 + source = "registry+https://github.com/rust-lang/crates.io-index" 53 + checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" 54 + dependencies = [ 55 + "windows-sys 0.52.0", 56 + ] 57 + 58 + [[package]] 59 + name = "anstyle-wincon" 60 + version = "3.0.2" 61 + source = "registry+https://github.com/rust-lang/crates.io-index" 62 + checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" 63 + dependencies = [ 64 + "anstyle", 65 + "windows-sys 0.52.0", 66 + ] 67 + 68 + [[package]] 21 69 name = "async-trait" 22 70 version = "0.1.77" 23 71 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 50 98 ] 51 99 52 100 [[package]] 101 + name = "base16ct" 102 + version = "0.2.0" 103 + source = "registry+https://github.com/rust-lang/crates.io-index" 104 + checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" 105 + 106 + [[package]] 53 107 name = "base64" 54 108 version = "0.21.7" 55 109 source = "registry+https://github.com/rust-lang/crates.io-index" 56 110 checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 57 111 58 112 [[package]] 113 + name = "base64ct" 114 + version = "1.6.0" 115 + source = "registry+https://github.com/rust-lang/crates.io-index" 116 + checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" 117 + 118 + [[package]] 59 119 name = "bitflags" 60 120 version = "1.3.2" 61 121 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 68 128 checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" 69 129 70 130 [[package]] 131 + name = "block-buffer" 132 + version = "0.10.4" 133 + source = "registry+https://github.com/rust-lang/crates.io-index" 134 + checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 135 + dependencies = [ 136 + "generic-array", 137 + ] 138 + 139 + [[package]] 71 140 name = "bumpalo" 72 141 version = "3.14.0" 73 142 source = "registry+https://github.com/rust-lang/crates.io-index" 74 143 checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" 144 + 145 + [[package]] 146 + name = "byteorder" 147 + version = "1.5.0" 148 + source = "registry+https://github.com/rust-lang/crates.io-index" 149 + checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 75 150 76 151 [[package]] 77 152 name = "bytes" ··· 95 170 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 96 171 97 172 [[package]] 173 + name = "cipher" 174 + version = "0.4.4" 175 + source = "registry+https://github.com/rust-lang/crates.io-index" 176 + checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" 177 + dependencies = [ 178 + "crypto-common", 179 + "inout", 180 + ] 181 + 182 + [[package]] 183 + name = "clap" 184 + version = "4.4.18" 185 + source = "registry+https://github.com/rust-lang/crates.io-index" 186 + checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" 187 + dependencies = [ 188 + "clap_builder", 189 + "clap_derive", 190 + ] 191 + 192 + [[package]] 193 + name = "clap_builder" 194 + version = "4.4.18" 195 + source = "registry+https://github.com/rust-lang/crates.io-index" 196 + checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" 197 + dependencies = [ 198 + "anstream", 199 + "anstyle", 200 + "clap_lex", 201 + "strsim", 202 + ] 203 + 204 + [[package]] 205 + name = "clap_derive" 206 + version = "4.4.7" 207 + source = "registry+https://github.com/rust-lang/crates.io-index" 208 + checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" 209 + dependencies = [ 210 + "heck", 211 + "proc-macro2", 212 + "quote", 213 + "syn", 214 + ] 215 + 216 + [[package]] 217 + name = "clap_lex" 218 + version = "0.6.0" 219 + source = "registry+https://github.com/rust-lang/crates.io-index" 220 + checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" 221 + 222 + [[package]] 223 + name = "colorchoice" 224 + version = "1.0.0" 225 + source = "registry+https://github.com/rust-lang/crates.io-index" 226 + checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 227 + 228 + [[package]] 229 + name = "const-oid" 230 + version = "0.9.6" 231 + source = "registry+https://github.com/rust-lang/crates.io-index" 232 + checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" 233 + 234 + [[package]] 98 235 name = "core-foundation" 99 236 version = "0.9.4" 100 237 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 111 248 checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" 112 249 113 250 [[package]] 251 + name = "cpufeatures" 252 + version = "0.2.12" 253 + source = "registry+https://github.com/rust-lang/crates.io-index" 254 + checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" 255 + dependencies = [ 256 + "libc", 257 + ] 258 + 259 + [[package]] 260 + name = "crypto-bigint" 261 + version = "0.5.5" 262 + source = "registry+https://github.com/rust-lang/crates.io-index" 263 + checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" 264 + dependencies = [ 265 + "generic-array", 266 + "rand_core", 267 + "subtle", 268 + "zeroize", 269 + ] 270 + 271 + [[package]] 272 + name = "crypto-common" 273 + version = "0.1.6" 274 + source = "registry+https://github.com/rust-lang/crates.io-index" 275 + checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 276 + dependencies = [ 277 + "generic-array", 278 + "typenum", 279 + ] 280 + 281 + [[package]] 282 + name = "der" 283 + version = "0.7.8" 284 + source = "registry+https://github.com/rust-lang/crates.io-index" 285 + checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" 286 + dependencies = [ 287 + "const-oid", 288 + "zeroize", 289 + ] 290 + 291 + [[package]] 292 + name = "digest" 293 + version = "0.10.7" 294 + source = "registry+https://github.com/rust-lang/crates.io-index" 295 + checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 296 + dependencies = [ 297 + "block-buffer", 298 + "const-oid", 299 + "crypto-common", 300 + "subtle", 301 + ] 302 + 303 + [[package]] 304 + name = "ecdsa" 305 + version = "0.16.9" 306 + source = "registry+https://github.com/rust-lang/crates.io-index" 307 + checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" 308 + dependencies = [ 309 + "der", 310 + "digest", 311 + "elliptic-curve", 312 + "rfc6979", 313 + "signature", 314 + "spki", 315 + ] 316 + 317 + [[package]] 318 + name = "elliptic-curve" 319 + version = "0.13.8" 320 + source = "registry+https://github.com/rust-lang/crates.io-index" 321 + checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" 322 + dependencies = [ 323 + "base16ct", 324 + "crypto-bigint", 325 + "digest", 326 + "ff", 327 + "generic-array", 328 + "group", 329 + "pkcs8", 330 + "rand_core", 331 + "sec1", 332 + "subtle", 333 + "zeroize", 334 + ] 335 + 336 + [[package]] 114 337 name = "encoding_rs" 115 338 version = "0.8.33" 116 339 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 126 349 checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 127 350 128 351 [[package]] 129 - name = "erased-serde" 130 - version = "0.4.2" 352 + name = "errno" 353 + version = "0.3.8" 131 354 source = "registry+https://github.com/rust-lang/crates.io-index" 132 - checksum = "55d05712b2d8d88102bc9868020c9e5c7a1f5527c452b9b97450a1d006140ba7" 355 + checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" 133 356 dependencies = [ 134 - "serde", 357 + "libc", 358 + "windows-sys 0.52.0", 135 359 ] 136 360 137 361 [[package]] 138 - name = "errno" 139 - version = "0.3.8" 362 + name = "eyre" 363 + version = "0.6.12" 140 364 source = "registry+https://github.com/rust-lang/crates.io-index" 141 - checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" 365 + checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" 142 366 dependencies = [ 143 - "libc", 144 - "windows-sys 0.52.0", 367 + "indenter", 368 + "once_cell", 145 369 ] 146 370 147 371 [[package]] ··· 149 373 version = "2.0.1" 150 374 source = "registry+https://github.com/rust-lang/crates.io-index" 151 375 checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" 376 + 377 + [[package]] 378 + name = "ff" 379 + version = "0.13.0" 380 + source = "registry+https://github.com/rust-lang/crates.io-index" 381 + checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" 382 + dependencies = [ 383 + "rand_core", 384 + "subtle", 385 + ] 152 386 153 387 [[package]] 154 388 name = "fnv" ··· 185 419 version = "0.1.0" 186 420 dependencies = [ 187 421 "async-trait", 422 + "clap", 188 423 "futures", 189 424 "reqwest", 190 425 "serde", 191 426 "serde_json", 427 + "simple-eyre", 428 + "ssh-key", 192 429 "tokio", 193 - "tokio-stream", 194 430 "toml", 195 - "typetag", 196 431 ] 197 432 198 433 [[package]] ··· 285 520 ] 286 521 287 522 [[package]] 523 + name = "generic-array" 524 + version = "0.14.7" 525 + source = "registry+https://github.com/rust-lang/crates.io-index" 526 + checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 527 + dependencies = [ 528 + "typenum", 529 + "version_check", 530 + "zeroize", 531 + ] 532 + 533 + [[package]] 534 + name = "getrandom" 535 + version = "0.2.12" 536 + source = "registry+https://github.com/rust-lang/crates.io-index" 537 + checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" 538 + dependencies = [ 539 + "cfg-if", 540 + "libc", 541 + "wasi", 542 + ] 543 + 544 + [[package]] 288 545 name = "gimli" 289 546 version = "0.28.1" 290 547 source = "registry+https://github.com/rust-lang/crates.io-index" 291 548 checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" 292 549 293 550 [[package]] 551 + name = "group" 552 + version = "0.13.0" 553 + source = "registry+https://github.com/rust-lang/crates.io-index" 554 + checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" 555 + dependencies = [ 556 + "ff", 557 + "rand_core", 558 + "subtle", 559 + ] 560 + 561 + [[package]] 294 562 name = "h2" 295 563 version = "0.3.24" 296 564 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 316 584 checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" 317 585 318 586 [[package]] 587 + name = "heck" 588 + version = "0.4.1" 589 + source = "registry+https://github.com/rust-lang/crates.io-index" 590 + checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 591 + 592 + [[package]] 319 593 name = "hermit-abi" 320 - version = "0.3.4" 594 + version = "0.3.5" 321 595 source = "registry+https://github.com/rust-lang/crates.io-index" 322 - checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" 596 + checksum = "d0c62115964e08cb8039170eb33c1d0e2388a256930279edca206fff675f82c3" 597 + 598 + [[package]] 599 + name = "hmac" 600 + version = "0.12.1" 601 + source = "registry+https://github.com/rust-lang/crates.io-index" 602 + checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" 603 + dependencies = [ 604 + "digest", 605 + ] 323 606 324 607 [[package]] 325 608 name = "http" ··· 403 686 ] 404 687 405 688 [[package]] 689 + name = "indenter" 690 + version = "0.3.3" 691 + source = "registry+https://github.com/rust-lang/crates.io-index" 692 + checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" 693 + 694 + [[package]] 406 695 name = "indexmap" 407 696 version = "2.2.2" 408 697 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 413 702 ] 414 703 415 704 [[package]] 416 - name = "inventory" 417 - version = "0.3.15" 705 + name = "inout" 706 + version = "0.1.3" 418 707 source = "registry+https://github.com/rust-lang/crates.io-index" 419 - checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767" 708 + checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" 709 + dependencies = [ 710 + "generic-array", 711 + ] 420 712 421 713 [[package]] 422 714 name = "ipnet" ··· 444 736 version = "1.4.0" 445 737 source = "registry+https://github.com/rust-lang/crates.io-index" 446 738 checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 739 + dependencies = [ 740 + "spin", 741 + ] 447 742 448 743 [[package]] 449 744 name = "libc" ··· 452 747 checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" 453 748 454 749 [[package]] 750 + name = "libm" 751 + version = "0.2.8" 752 + source = "registry+https://github.com/rust-lang/crates.io-index" 753 + checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" 754 + 755 + [[package]] 455 756 name = "linux-raw-sys" 456 757 version = "0.4.13" 457 758 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 514 815 ] 515 816 516 817 [[package]] 818 + name = "num-bigint-dig" 819 + version = "0.8.4" 820 + source = "registry+https://github.com/rust-lang/crates.io-index" 821 + checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" 822 + dependencies = [ 823 + "byteorder", 824 + "lazy_static", 825 + "libm", 826 + "num-integer", 827 + "num-iter", 828 + "num-traits", 829 + "rand", 830 + "smallvec", 831 + "zeroize", 832 + ] 833 + 834 + [[package]] 835 + name = "num-integer" 836 + version = "0.1.46" 837 + source = "registry+https://github.com/rust-lang/crates.io-index" 838 + checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 839 + dependencies = [ 840 + "num-traits", 841 + ] 842 + 843 + [[package]] 844 + name = "num-iter" 845 + version = "0.1.44" 846 + source = "registry+https://github.com/rust-lang/crates.io-index" 847 + checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" 848 + dependencies = [ 849 + "autocfg", 850 + "num-integer", 851 + "num-traits", 852 + ] 853 + 854 + [[package]] 855 + name = "num-traits" 856 + version = "0.2.18" 857 + source = "registry+https://github.com/rust-lang/crates.io-index" 858 + checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" 859 + dependencies = [ 860 + "autocfg", 861 + "libm", 862 + ] 863 + 864 + [[package]] 517 865 name = "num_cpus" 518 866 version = "1.16.0" 519 867 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 583 931 ] 584 932 585 933 [[package]] 934 + name = "p256" 935 + version = "0.13.2" 936 + source = "registry+https://github.com/rust-lang/crates.io-index" 937 + checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" 938 + dependencies = [ 939 + "ecdsa", 940 + "elliptic-curve", 941 + "primeorder", 942 + "sha2", 943 + ] 944 + 945 + [[package]] 946 + name = "p384" 947 + version = "0.13.0" 948 + source = "registry+https://github.com/rust-lang/crates.io-index" 949 + checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" 950 + dependencies = [ 951 + "ecdsa", 952 + "elliptic-curve", 953 + "primeorder", 954 + "sha2", 955 + ] 956 + 957 + [[package]] 958 + name = "p521" 959 + version = "0.13.3" 960 + source = "registry+https://github.com/rust-lang/crates.io-index" 961 + checksum = "0fc9e2161f1f215afdfce23677034ae137bbd45016a880c2eb3ba8eb95f085b2" 962 + dependencies = [ 963 + "base16ct", 964 + "ecdsa", 965 + "elliptic-curve", 966 + "primeorder", 967 + "rand_core", 968 + "sha2", 969 + ] 970 + 971 + [[package]] 972 + name = "pem-rfc7468" 973 + version = "0.7.0" 974 + source = "registry+https://github.com/rust-lang/crates.io-index" 975 + checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" 976 + dependencies = [ 977 + "base64ct", 978 + ] 979 + 980 + [[package]] 586 981 name = "percent-encoding" 587 982 version = "2.3.1" 588 983 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 601 996 checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 602 997 603 998 [[package]] 999 + name = "pkcs1" 1000 + version = "0.7.5" 1001 + source = "registry+https://github.com/rust-lang/crates.io-index" 1002 + checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" 1003 + dependencies = [ 1004 + "der", 1005 + "pkcs8", 1006 + "spki", 1007 + ] 1008 + 1009 + [[package]] 1010 + name = "pkcs8" 1011 + version = "0.10.2" 1012 + source = "registry+https://github.com/rust-lang/crates.io-index" 1013 + checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" 1014 + dependencies = [ 1015 + "der", 1016 + "spki", 1017 + ] 1018 + 1019 + [[package]] 604 1020 name = "pkg-config" 605 1021 version = "0.3.29" 606 1022 source = "registry+https://github.com/rust-lang/crates.io-index" 607 1023 checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" 608 1024 609 1025 [[package]] 1026 + name = "ppv-lite86" 1027 + version = "0.2.17" 1028 + source = "registry+https://github.com/rust-lang/crates.io-index" 1029 + checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 1030 + 1031 + [[package]] 1032 + name = "primeorder" 1033 + version = "0.13.6" 1034 + source = "registry+https://github.com/rust-lang/crates.io-index" 1035 + checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" 1036 + dependencies = [ 1037 + "elliptic-curve", 1038 + ] 1039 + 1040 + [[package]] 610 1041 name = "proc-macro2" 611 1042 version = "1.0.78" 612 1043 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 625 1056 ] 626 1057 627 1058 [[package]] 1059 + name = "rand" 1060 + version = "0.8.5" 1061 + source = "registry+https://github.com/rust-lang/crates.io-index" 1062 + checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1063 + dependencies = [ 1064 + "rand_chacha", 1065 + "rand_core", 1066 + ] 1067 + 1068 + [[package]] 1069 + name = "rand_chacha" 1070 + version = "0.3.1" 1071 + source = "registry+https://github.com/rust-lang/crates.io-index" 1072 + checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1073 + dependencies = [ 1074 + "ppv-lite86", 1075 + "rand_core", 1076 + ] 1077 + 1078 + [[package]] 1079 + name = "rand_core" 1080 + version = "0.6.4" 1081 + source = "registry+https://github.com/rust-lang/crates.io-index" 1082 + checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1083 + dependencies = [ 1084 + "getrandom", 1085 + ] 1086 + 1087 + [[package]] 628 1088 name = "reqwest" 629 1089 version = "0.11.24" 630 1090 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 662 1122 "wasm-bindgen-futures", 663 1123 "web-sys", 664 1124 "winreg", 1125 + ] 1126 + 1127 + [[package]] 1128 + name = "rfc6979" 1129 + version = "0.4.0" 1130 + source = "registry+https://github.com/rust-lang/crates.io-index" 1131 + checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" 1132 + dependencies = [ 1133 + "hmac", 1134 + "subtle", 1135 + ] 1136 + 1137 + [[package]] 1138 + name = "rsa" 1139 + version = "0.9.6" 1140 + source = "registry+https://github.com/rust-lang/crates.io-index" 1141 + checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" 1142 + dependencies = [ 1143 + "const-oid", 1144 + "digest", 1145 + "num-bigint-dig", 1146 + "num-integer", 1147 + "num-traits", 1148 + "pkcs1", 1149 + "pkcs8", 1150 + "rand_core", 1151 + "sha2", 1152 + "signature", 1153 + "spki", 1154 + "subtle", 1155 + "zeroize", 665 1156 ] 666 1157 667 1158 [[package]] ··· 708 1199 ] 709 1200 710 1201 [[package]] 1202 + name = "sec1" 1203 + version = "0.7.3" 1204 + source = "registry+https://github.com/rust-lang/crates.io-index" 1205 + checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" 1206 + dependencies = [ 1207 + "base16ct", 1208 + "der", 1209 + "generic-array", 1210 + "pkcs8", 1211 + "subtle", 1212 + "zeroize", 1213 + ] 1214 + 1215 + [[package]] 711 1216 name = "security-framework" 712 1217 version = "2.9.2" 713 1218 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 783 1288 ] 784 1289 785 1290 [[package]] 1291 + name = "sha2" 1292 + version = "0.10.8" 1293 + source = "registry+https://github.com/rust-lang/crates.io-index" 1294 + checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 1295 + dependencies = [ 1296 + "cfg-if", 1297 + "cpufeatures", 1298 + "digest", 1299 + ] 1300 + 1301 + [[package]] 786 1302 name = "signal-hook-registry" 787 1303 version = "1.4.1" 788 1304 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 792 1308 ] 793 1309 794 1310 [[package]] 1311 + name = "signature" 1312 + version = "2.2.0" 1313 + source = "registry+https://github.com/rust-lang/crates.io-index" 1314 + checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" 1315 + dependencies = [ 1316 + "digest", 1317 + "rand_core", 1318 + ] 1319 + 1320 + [[package]] 1321 + name = "simple-eyre" 1322 + version = "0.3.1" 1323 + source = "registry+https://github.com/rust-lang/crates.io-index" 1324 + checksum = "1b561532e8ffe7ecf09108c4f662896a9ec3eac4999eba84015ec3dcb8cc630a" 1325 + dependencies = [ 1326 + "eyre", 1327 + "indenter", 1328 + ] 1329 + 1330 + [[package]] 795 1331 name = "slab" 796 1332 version = "0.4.9" 797 1333 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 801 1337 ] 802 1338 803 1339 [[package]] 1340 + name = "smallvec" 1341 + version = "1.13.1" 1342 + source = "registry+https://github.com/rust-lang/crates.io-index" 1343 + checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" 1344 + 1345 + [[package]] 804 1346 name = "socket2" 805 1347 version = "0.5.5" 806 1348 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 811 1353 ] 812 1354 813 1355 [[package]] 1356 + name = "spin" 1357 + version = "0.5.2" 1358 + source = "registry+https://github.com/rust-lang/crates.io-index" 1359 + checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" 1360 + 1361 + [[package]] 1362 + name = "spki" 1363 + version = "0.7.3" 1364 + source = "registry+https://github.com/rust-lang/crates.io-index" 1365 + checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" 1366 + dependencies = [ 1367 + "base64ct", 1368 + "der", 1369 + ] 1370 + 1371 + [[package]] 1372 + name = "ssh-cipher" 1373 + version = "0.2.0" 1374 + source = "registry+https://github.com/rust-lang/crates.io-index" 1375 + checksum = "caac132742f0d33c3af65bfcde7f6aa8f62f0e991d80db99149eb9d44708784f" 1376 + dependencies = [ 1377 + "cipher", 1378 + "ssh-encoding", 1379 + ] 1380 + 1381 + [[package]] 1382 + name = "ssh-encoding" 1383 + version = "0.2.0" 1384 + source = "registry+https://github.com/rust-lang/crates.io-index" 1385 + checksum = "eb9242b9ef4108a78e8cd1a2c98e193ef372437f8c22be363075233321dd4a15" 1386 + dependencies = [ 1387 + "base64ct", 1388 + "pem-rfc7468", 1389 + "sha2", 1390 + ] 1391 + 1392 + [[package]] 1393 + name = "ssh-key" 1394 + version = "0.6.4" 1395 + source = "registry+https://github.com/rust-lang/crates.io-index" 1396 + checksum = "01f8f4ea73476c0aa5d5e6a75ce1e8634e2c3f82005ef3bbed21547ac57f2bf7" 1397 + dependencies = [ 1398 + "p256", 1399 + "p384", 1400 + "p521", 1401 + "rand_core", 1402 + "rsa", 1403 + "sec1", 1404 + "serde", 1405 + "sha2", 1406 + "signature", 1407 + "ssh-cipher", 1408 + "ssh-encoding", 1409 + "subtle", 1410 + "zeroize", 1411 + ] 1412 + 1413 + [[package]] 1414 + name = "strsim" 1415 + version = "0.10.0" 1416 + source = "registry+https://github.com/rust-lang/crates.io-index" 1417 + checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 1418 + 1419 + [[package]] 1420 + name = "subtle" 1421 + version = "2.5.0" 1422 + source = "registry+https://github.com/rust-lang/crates.io-index" 1423 + checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" 1424 + 1425 + [[package]] 814 1426 name = "syn" 815 1427 version = "2.0.48" 816 1428 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 915 1527 ] 916 1528 917 1529 [[package]] 918 - name = "tokio-stream" 919 - version = "0.1.14" 920 - source = "registry+https://github.com/rust-lang/crates.io-index" 921 - checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" 922 - dependencies = [ 923 - "futures-core", 924 - "pin-project-lite", 925 - "tokio", 926 - ] 927 - 928 - [[package]] 929 1530 name = "tokio-util" 930 1531 version = "0.7.10" 931 1532 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1005 1606 checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 1006 1607 1007 1608 [[package]] 1008 - name = "typetag" 1009 - version = "0.2.15" 1010 - source = "registry+https://github.com/rust-lang/crates.io-index" 1011 - checksum = "c43148481c7b66502c48f35b8eef38b6ccdc7a9f04bd4cc294226d901ccc9bc7" 1012 - dependencies = [ 1013 - "erased-serde", 1014 - "inventory", 1015 - "once_cell", 1016 - "serde", 1017 - "typetag-impl", 1018 - ] 1019 - 1020 - [[package]] 1021 - name = "typetag-impl" 1022 - version = "0.2.15" 1609 + name = "typenum" 1610 + version = "1.17.0" 1023 1611 source = "registry+https://github.com/rust-lang/crates.io-index" 1024 - checksum = "291db8a81af4840c10d636e047cac67664e343be44e24dfdbd1492df9a5d3390" 1025 - dependencies = [ 1026 - "proc-macro2", 1027 - "quote", 1028 - "syn", 1029 - ] 1612 + checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 1030 1613 1031 1614 [[package]] 1032 1615 name = "unicode-bidi" ··· 1061 1644 ] 1062 1645 1063 1646 [[package]] 1647 + name = "utf8parse" 1648 + version = "0.2.1" 1649 + source = "registry+https://github.com/rust-lang/crates.io-index" 1650 + checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 1651 + 1652 + [[package]] 1064 1653 name = "vcpkg" 1065 1654 version = "0.2.15" 1066 1655 source = "registry+https://github.com/rust-lang/crates.io-index" 1067 1656 checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 1657 + 1658 + [[package]] 1659 + name = "version_check" 1660 + version = "0.9.4" 1661 + source = "registry+https://github.com/rust-lang/crates.io-index" 1662 + checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1068 1663 1069 1664 [[package]] 1070 1665 name = "want" ··· 1307 1902 "cfg-if", 1308 1903 "windows-sys 0.48.0", 1309 1904 ] 1905 + 1906 + [[package]] 1907 + name = "zeroize" 1908 + version = "1.7.0" 1909 + source = "registry+https://github.com/rust-lang/crates.io-index" 1910 + checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"
+3 -4
Cargo.toml
··· 3 3 version = "0.1.0" 4 4 edition = "2021" 5 5 6 - # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 - 8 6 [dependencies] 9 7 async-trait = "0.1.77" 8 + clap = { version = "4.4.18", features = ["derive"] } 10 9 futures = "0.3.30" 11 10 reqwest = "0.11.24" 12 11 serde = { version = "1.0.196", features = ["derive"] } 13 12 serde_json = "1.0.113" 13 + simple-eyre = "0.3.1" 14 + ssh-key = { version = "0.6.4", features = ["alloc", "serde"] } 14 15 tokio = { version = "1.36.0", default-features = false, features = ["rt-multi-thread", "fs", "io-std", "io-util", "macros", "process", "net"] } 15 - tokio-stream = "0.1.14" 16 16 toml = "0.8.10" 17 - typetag = "0.2.15"
+8 -10
README.md
··· 7 7 8 8 ## Sources 9 9 10 - - [ ] Raw - no fetching, just raw key from the configuration 11 - - [ ] Forges 12 - + [ ] GitHub 13 - + [ ] SourceHut 14 - + [ ] GitLab 15 - + [ ] Forgejo 16 - + [ ] Defining your own forges 17 - - [ ] Host keys via `ssh-keyscan` 10 + - [x] Raw - no fetching, just raw key from the configuration 11 + - [x] Forges 12 + + [x] GitHub 13 + + [x] SourceHut 14 + + [x] GitLab 15 + + [x] Forgejo 16 + - [x] Host keys via `ssh-keyscan` 18 17 19 18 ## Reason 20 19 ··· 33 32 ```toml 34 33 [[entry]] 35 34 name = "hauleth" 36 - emails = [ "~@hauleth.dev" ] 37 35 keys = [ 38 36 { sourcehut = "~hauleth" }, 39 37 { github = "hauleth" } ··· 42 40 [[entry]] 43 41 name = "heimdall" 44 42 keys = [ 45 - { host = "heimdall" } 43 + { host = [ "heimdall" ] } 46 44 ] 47 45 ``` 48 46
+17 -5
flake.nix
··· 12 12 extra-substituters = "https://devenv.cachix.org"; 13 13 }; 14 14 15 - outputs = inputs@{ flake-parts, ... }: 16 - flake-parts.lib.mkFlake { inherit inputs; } { 15 + outputs = inputs @ {flake-parts, ...}: 16 + flake-parts.lib.mkFlake {inherit inputs;} { 17 17 imports = [ 18 18 inputs.devenv.flakeModule 19 19 ]; 20 20 21 21 flake = { 22 - 23 22 }; 24 23 25 - systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" "x86_64-darwin" ]; 24 + systems = ["x86_64-linux" "aarch64-linux" "aarch64-darwin" "x86_64-darwin"]; 26 25 27 - perSystem = { inputs', pkgs, ... }: { 26 + perSystem = { 27 + self', 28 + inputs', 29 + pkgs, 30 + ... 31 + }: { 32 + formatter = pkgs.alejandra; 33 + 34 + packages = { 35 + default = self'.packages.fuk; 36 + 37 + fuk = pkgs.callPackage ./nix/fuk.nix {}; 38 + }; 39 + 28 40 devenv.shells.default = { 29 41 languages.rust.enable = true; 30 42
+12
keys.toml
··· 1 + [[entry]] 2 + name = "hauleth" 3 + keys = [ 4 + { sourcehut = "~hauleth" }, 5 + { github = "hauleth" } 6 + ] 7 + 8 + [[entry]] 9 + name = "heimdall" 10 + keys = [ 11 + { hosts = ["heimdall"] } 12 + ]
+29
nix/fuk.nix
··· 1 + { 2 + lib, 3 + rustPlatform, 4 + stdenv, 5 + darwin, 6 + libiconv, 7 + }: 8 + rustPlatform.buildRustPackage { 9 + pname = "fuk"; 10 + version = "0.1.0"; 11 + 12 + src = ./..; 13 + 14 + cargoHash = "sha256-uRCR8SMFurNbgL1ZSLW95tJcZRH3FMYNAc0uWGvH4yw="; 15 + 16 + buildInputs = lib.lists.optionals stdenv.isDarwin (with darwin.apple_sdk; [ 17 + frameworks.Foundation 18 + frameworks.CoreFoundation 19 + frameworks.SystemConfiguration 20 + frameworks.Security 21 + libiconv 22 + ]); 23 + 24 + meta = with lib; { 25 + description = "Simple tool for fetching SSH keys from various sources"; 26 + homepage = "https://git.sr.ht/~hauleth/fuk"; 27 + mainProgram = "fuk"; 28 + }; 29 + }
+9 -3
src/config.rs
··· 6 6 #[derive(Debug, serde::Deserialize)] 7 7 pub struct Entry { 8 8 pub name: String, 9 - pub keys: Vec<Box<dyn Fetch>>, 9 + pub keys: Vec<Box<Source>>, 10 10 } 11 11 12 12 impl Entry { 13 - pub async fn fetch(&self) -> (String, Vec<String>) { 14 - let stream = stream::iter(&self.keys) 13 + pub async fn fetch(&self) -> (String, Vec<ssh_key::PublicKey>) { 14 + let mut stream: Vec<_> = stream::iter(&self.keys) 15 15 .then(|k| async { k.fetch().await }) 16 16 .map(stream::iter) 17 17 .flatten() 18 18 .collect() 19 19 .await; 20 + 21 + // Deduplicate keys, no need for duplicated entries 22 + stream.sort(); 23 + stream.dedup_by(|a, b| { 24 + a.key_data() == b.key_data() 25 + }); 20 26 21 27 (self.name.clone(), stream) 22 28 }
+50 -17
src/main.rs
··· 1 - const EXAMPLE: &'static str = r#" 2 - [[entry]] 3 - name = "hauleth" 4 - keys = [ 5 - { Forge = { user = "~hauleth", host = "meta.sr.ht" } } 6 - ] 1 + use simple_eyre::eyre::Result; 2 + use clap::Parser; 3 + use std::path::Path; 4 + use tokio::fs::File; 5 + use tokio::io::{self, AsyncReadExt}; 6 + 7 + #[derive(Debug, Clone)] 8 + enum Input { 9 + File(Box<Path>), 10 + Stdio, 11 + } 12 + 13 + impl<'a> From<&'a str> for Input { 14 + fn from(input: &'a str) -> Self { 15 + match input { 16 + "-" => Input::Stdio, 17 + other => Input::File(Path::new(other).into()), 18 + } 19 + } 20 + } 21 + 22 + impl Input { 23 + async fn read_all(&self) -> io::Result<String> { 24 + let mut buffer = String::new(); 25 + let result = match *self { 26 + Input::Stdio => io::stdin().read_to_string(&mut buffer).await, 27 + Input::File(ref path) => { 28 + let mut f = File::open(path).await?; 29 + f.read_to_string(&mut buffer).await 30 + } 31 + }; 32 + 33 + result.map(|_| buffer) 34 + } 35 + } 7 36 8 - [[entry]] 9 - name = "heimdall" 10 - keys = [ 11 - { Host = [ "heimdall" ] } 12 - ] 13 - "#; 37 + #[derive(Debug, Parser)] 38 + struct Args { 39 + #[arg(long, default_value_t = fuk::output::Format::JSONPretty)] 40 + format: fuk::output::Format, 41 + /// File containing list of keys to be fetched 42 + #[arg(value_hint = clap::ValueHint::FilePath)] 43 + file: Input, 44 + } 14 45 15 46 #[tokio::main] 16 - async fn main() { 17 - let config: fuk::config::Config = 18 - toml::from_str(EXAMPLE).unwrap(); 47 + async fn main() -> Result<()> { 48 + let args = Args::parse(); 19 49 20 - println!("{:#?}", config); 50 + let config: fuk::config::Config = toml::from_str(&args.file.read_all().await?)?; 21 51 22 52 let output = fuk::fuk(config).await; 23 - println!("{}", serde_json::to_string_pretty(&output.keys).unwrap()); 53 + 54 + println!("{}", args.format.render(&output)); 55 + 56 + Ok(()) 24 57 }
+35 -1
src/output/mod.rs
··· 1 1 use std::collections::HashMap; 2 2 3 + #[derive(PartialEq, Eq, Debug, Copy, Clone)] 4 + pub enum Format { 5 + JSON, 6 + JSONPretty, 7 + } 8 + 9 + impl Format { 10 + pub fn render(self, output: &Output) -> String { 11 + match self { 12 + Format::JSON => serde_json::to_string(&output.keys).unwrap(), 13 + Format::JSONPretty => serde_json::to_string_pretty(&output.keys).unwrap(), 14 + } 15 + } 16 + } 17 + 18 + impl std::fmt::Display for Format { 19 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 20 + match *self { 21 + Format::JSON => f.write_str("json"), 22 + Format::JSONPretty => f.write_str("pretty"), 23 + } 24 + } 25 + } 26 + 27 + impl<'a> From<&'a str> for Format { 28 + fn from(s: &'a str) -> Format { 29 + match s { 30 + "json" => Format::JSON, 31 + "pretty" => Format::JSONPretty, 32 + _ => unreachable!() 33 + } 34 + } 35 + } 36 + 3 37 #[derive(Debug, serde::Serialize)] 4 38 pub struct Output { 5 - pub keys: HashMap<String, Vec<String>>, 39 + pub keys: HashMap<String, Vec<ssh_key::PublicKey>>, 6 40 }
+38 -13
src/sources/mod.rs
··· 1 + use ssh_key::PublicKey; 1 2 use tokio::process::Command; 2 - 3 3 use serde::Deserialize; 4 4 use async_trait::async_trait; 5 5 6 - #[typetag::deserialize] 7 6 #[async_trait] 8 7 pub trait Fetch: std::fmt::Debug { 9 - async fn fetch(&self) -> Vec<String>; 8 + async fn fetch(&self) -> Vec<PublicKey>; 9 + } 10 + 11 + #[derive(Debug, Deserialize)] 12 + #[serde(rename_all = "lowercase")] 13 + pub enum Source { 14 + Raw(Raw), 15 + Hosts(Hosts), 16 + Forge(Forge), 17 + Github(String), 18 + Sourcehut(String), 19 + Gitlab(String), 20 + Codeberg(String), 21 + } 22 + 23 + #[async_trait] 24 + impl Fetch for Source { 25 + async fn fetch(&self) -> Vec<PublicKey> { 26 + match *self { 27 + Source::Raw(ref raw) => raw.fetch().await, 28 + Source::Hosts(ref raw) => raw.fetch().await, 29 + Source::Forge(ref raw) => raw.fetch().await, 30 + Source::Github(ref user) => Forge { user: user.clone(), host: "github.com".into() }.fetch().await, 31 + Source::Sourcehut(ref user) => Forge { user: user.clone(), host: "meta.sr.ht".into() }.fetch().await, 32 + Source::Gitlab(ref user) => Forge { user: user.clone(), host: "gitlab.com".into() }.fetch().await, 33 + Source::Codeberg(ref user) => Forge { user: user.clone(), host: "codeberg.org".into() }.fetch().await, 34 + } 35 + } 10 36 } 11 37 12 38 #[derive(Debug, Deserialize)] 13 - pub struct Raw(Vec<String>); 39 + pub struct Raw(Vec<PublicKey>); 14 40 15 - #[typetag::deserialize] 16 41 #[async_trait::async_trait] 17 42 impl Fetch for Raw { 18 - async fn fetch(&self) -> Vec<String> { 43 + async fn fetch(&self) -> Vec<PublicKey> { 19 44 self.0.clone() 20 45 } 21 46 } 22 47 23 48 #[derive(Debug, Deserialize)] 24 - pub struct Host(pub Vec<String>); 49 + pub struct Hosts(pub Vec<String>); 25 50 26 - #[typetag::deserialize] 27 51 #[async_trait] 28 - impl Fetch for Host { 29 - async fn fetch(&self) -> Vec<String> { 52 + impl Fetch for Hosts { 53 + async fn fetch(&self) -> Vec<PublicKey> { 54 + // TODO: Check if we can do it in-process instead of shelling out to `ssh-keyscan` 30 55 let result = Command::new("ssh-keyscan") 31 56 .args(&self.0) 32 57 .output() ··· 46 71 .join(" ") 47 72 .to_owned() 48 73 }) 74 + .map(|k| PublicKey::from_openssh(&k).unwrap()) 49 75 .collect() 50 76 } 51 77 } ··· 56 82 pub host: String, 57 83 } 58 84 59 - #[typetag::deserialize] 60 85 #[async_trait] 61 86 impl Fetch for Forge { 62 - async fn fetch(&self) -> Vec<String> { 87 + async fn fetch(&self) -> Vec<PublicKey> { 63 88 let url = format!("https://{}/{}.keys", self.host, self.user); 64 89 65 90 reqwest::get(url) ··· 70 95 .unwrap() 71 96 .trim() 72 97 .split('\n') 73 - .map(|s| s.to_owned()) 98 + .map(|s| PublicKey::from_openssh(s).unwrap()) 74 99 .collect() 75 100 } 76 101 }