├── .envrc ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── default.nix ├── flake.lock ├── flake.nix ├── home-manager.nix └── src ├── cli.rs ├── config.rs ├── db.rs ├── gui.rs ├── main.rs └── socket.rs /.envrc: -------------------------------------------------------------------------------- 1 | use flake 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /.direnv 3 | *.db3 4 | flake.nix 5 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.24.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 19 | 20 | [[package]] 21 | name = "aead" 22 | version = "0.5.2" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" 25 | dependencies = [ 26 | "crypto-common", 27 | "generic-array", 28 | ] 29 | 30 | [[package]] 31 | name = "aes" 32 | version = "0.8.4" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" 35 | dependencies = [ 36 | "cfg-if 1.0.0", 37 | "cipher", 38 | "cpufeatures", 39 | ] 40 | 41 | [[package]] 42 | name = "aes-gcm" 43 | version = "0.10.3" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" 46 | dependencies = [ 47 | "aead", 48 | "aes", 49 | "cipher", 50 | "ctr", 51 | "ghash", 52 | "subtle", 53 | ] 54 | 55 | [[package]] 56 | name = "ahash" 57 | version = "0.8.11" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" 60 | dependencies = [ 61 | "cfg-if 1.0.0", 62 | "once_cell", 63 | "version_check", 64 | "zerocopy", 65 | ] 66 | 67 | [[package]] 68 | name = "aho-corasick" 69 | version = "1.1.3" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 72 | dependencies = [ 73 | "memchr", 74 | ] 75 | 76 | [[package]] 77 | name = "allocator-api2" 78 | version = "0.2.21" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" 81 | 82 | [[package]] 83 | name = "android-tzdata" 84 | version = "0.1.1" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" 87 | 88 | [[package]] 89 | name = "android_system_properties" 90 | version = "0.1.5" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 93 | dependencies = [ 94 | "libc", 95 | ] 96 | 97 | [[package]] 98 | name = "anstream" 99 | version = "0.6.18" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" 102 | dependencies = [ 103 | "anstyle", 104 | "anstyle-parse", 105 | "anstyle-query", 106 | "anstyle-wincon", 107 | "colorchoice", 108 | "is_terminal_polyfill", 109 | "utf8parse", 110 | ] 111 | 112 | [[package]] 113 | name = "anstyle" 114 | version = "1.0.10" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" 117 | 118 | [[package]] 119 | name = "anstyle-parse" 120 | version = "0.2.6" 121 | source = "registry+https://github.com/rust-lang/crates.io-index" 122 | checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" 123 | dependencies = [ 124 | "utf8parse", 125 | ] 126 | 127 | [[package]] 128 | name = "anstyle-query" 129 | version = "1.1.2" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" 132 | dependencies = [ 133 | "windows-sys 0.59.0", 134 | ] 135 | 136 | [[package]] 137 | name = "anstyle-wincon" 138 | version = "3.0.7" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" 141 | dependencies = [ 142 | "anstyle", 143 | "once_cell", 144 | "windows-sys 0.59.0", 145 | ] 146 | 147 | [[package]] 148 | name = "anyhow" 149 | version = "1.0.96" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4" 152 | 153 | [[package]] 154 | name = "async-broadcast" 155 | version = "0.5.1" 156 | source = "registry+https://github.com/rust-lang/crates.io-index" 157 | checksum = "7c48ccdbf6ca6b121e0f586cbc0e73ae440e56c67c30fa0873b4e110d9c26d2b" 158 | dependencies = [ 159 | "event-listener 2.5.3", 160 | "futures-core", 161 | ] 162 | 163 | [[package]] 164 | name = "async-channel" 165 | version = "2.3.1" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" 168 | dependencies = [ 169 | "concurrent-queue", 170 | "event-listener-strategy", 171 | "futures-core", 172 | "pin-project-lite", 173 | ] 174 | 175 | [[package]] 176 | name = "async-executor" 177 | version = "1.13.1" 178 | source = "registry+https://github.com/rust-lang/crates.io-index" 179 | checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" 180 | dependencies = [ 181 | "async-task", 182 | "concurrent-queue", 183 | "fastrand 2.3.0", 184 | "futures-lite 2.6.0", 185 | "slab", 186 | ] 187 | 188 | [[package]] 189 | name = "async-fs" 190 | version = "1.6.0" 191 | source = "registry+https://github.com/rust-lang/crates.io-index" 192 | checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" 193 | dependencies = [ 194 | "async-lock 2.8.0", 195 | "autocfg", 196 | "blocking", 197 | "futures-lite 1.13.0", 198 | ] 199 | 200 | [[package]] 201 | name = "async-io" 202 | version = "1.13.0" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" 205 | dependencies = [ 206 | "async-lock 2.8.0", 207 | "autocfg", 208 | "cfg-if 1.0.0", 209 | "concurrent-queue", 210 | "futures-lite 1.13.0", 211 | "log", 212 | "parking", 213 | "polling 2.8.0", 214 | "rustix 0.37.28", 215 | "slab", 216 | "socket2 0.4.10", 217 | "waker-fn", 218 | ] 219 | 220 | [[package]] 221 | name = "async-io" 222 | version = "2.4.0" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" 225 | dependencies = [ 226 | "async-lock 3.4.0", 227 | "cfg-if 1.0.0", 228 | "concurrent-queue", 229 | "futures-io", 230 | "futures-lite 2.6.0", 231 | "parking", 232 | "polling 3.7.4", 233 | "rustix 0.38.44", 234 | "slab", 235 | "tracing", 236 | "windows-sys 0.59.0", 237 | ] 238 | 239 | [[package]] 240 | name = "async-lock" 241 | version = "2.8.0" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" 244 | dependencies = [ 245 | "event-listener 2.5.3", 246 | ] 247 | 248 | [[package]] 249 | name = "async-lock" 250 | version = "3.4.0" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" 253 | dependencies = [ 254 | "event-listener 5.4.0", 255 | "event-listener-strategy", 256 | "pin-project-lite", 257 | ] 258 | 259 | [[package]] 260 | name = "async-process" 261 | version = "1.8.1" 262 | source = "registry+https://github.com/rust-lang/crates.io-index" 263 | checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" 264 | dependencies = [ 265 | "async-io 1.13.0", 266 | "async-lock 2.8.0", 267 | "async-signal", 268 | "blocking", 269 | "cfg-if 1.0.0", 270 | "event-listener 3.1.0", 271 | "futures-lite 1.13.0", 272 | "rustix 0.38.44", 273 | "windows-sys 0.48.0", 274 | ] 275 | 276 | [[package]] 277 | name = "async-recursion" 278 | version = "1.1.1" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" 281 | dependencies = [ 282 | "proc-macro2", 283 | "quote", 284 | "syn 2.0.98", 285 | ] 286 | 287 | [[package]] 288 | name = "async-signal" 289 | version = "0.2.10" 290 | source = "registry+https://github.com/rust-lang/crates.io-index" 291 | checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" 292 | dependencies = [ 293 | "async-io 2.4.0", 294 | "async-lock 3.4.0", 295 | "atomic-waker", 296 | "cfg-if 1.0.0", 297 | "futures-core", 298 | "futures-io", 299 | "rustix 0.38.44", 300 | "signal-hook-registry", 301 | "slab", 302 | "windows-sys 0.59.0", 303 | ] 304 | 305 | [[package]] 306 | name = "async-task" 307 | version = "4.7.1" 308 | source = "registry+https://github.com/rust-lang/crates.io-index" 309 | checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" 310 | 311 | [[package]] 312 | name = "async-trait" 313 | version = "0.1.86" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | checksum = "644dd749086bf3771a2fbc5f256fdb982d53f011c7d5d560304eafeecebce79d" 316 | dependencies = [ 317 | "proc-macro2", 318 | "quote", 319 | "syn 2.0.98", 320 | ] 321 | 322 | [[package]] 323 | name = "atomic-waker" 324 | version = "1.1.2" 325 | source = "registry+https://github.com/rust-lang/crates.io-index" 326 | checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 327 | 328 | [[package]] 329 | name = "autocfg" 330 | version = "1.4.0" 331 | source = "registry+https://github.com/rust-lang/crates.io-index" 332 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 333 | 334 | [[package]] 335 | name = "backtrace" 336 | version = "0.3.74" 337 | source = "registry+https://github.com/rust-lang/crates.io-index" 338 | checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" 339 | dependencies = [ 340 | "addr2line", 341 | "cfg-if 1.0.0", 342 | "libc", 343 | "miniz_oxide", 344 | "object", 345 | "rustc-demangle", 346 | "windows-targets 0.52.6", 347 | ] 348 | 349 | [[package]] 350 | name = "base16ct" 351 | version = "0.2.0" 352 | source = "registry+https://github.com/rust-lang/crates.io-index" 353 | checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" 354 | 355 | [[package]] 356 | name = "base64ct" 357 | version = "1.6.0" 358 | source = "registry+https://github.com/rust-lang/crates.io-index" 359 | checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" 360 | 361 | [[package]] 362 | name = "bcrypt-pbkdf" 363 | version = "0.10.0" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | checksum = "6aeac2e1fe888769f34f05ac343bbef98b14d1ffb292ab69d4608b3abc86f2a2" 366 | dependencies = [ 367 | "blowfish", 368 | "pbkdf2 0.12.2", 369 | "sha2", 370 | ] 371 | 372 | [[package]] 373 | name = "bit-vec" 374 | version = "0.6.3" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" 377 | 378 | [[package]] 379 | name = "bitflags" 380 | version = "1.3.2" 381 | source = "registry+https://github.com/rust-lang/crates.io-index" 382 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 383 | 384 | [[package]] 385 | name = "bitflags" 386 | version = "2.8.0" 387 | source = "registry+https://github.com/rust-lang/crates.io-index" 388 | checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" 389 | 390 | [[package]] 391 | name = "block-buffer" 392 | version = "0.10.4" 393 | source = "registry+https://github.com/rust-lang/crates.io-index" 394 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 395 | dependencies = [ 396 | "generic-array", 397 | ] 398 | 399 | [[package]] 400 | name = "block-padding" 401 | version = "0.3.3" 402 | source = "registry+https://github.com/rust-lang/crates.io-index" 403 | checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" 404 | dependencies = [ 405 | "generic-array", 406 | ] 407 | 408 | [[package]] 409 | name = "blocking" 410 | version = "1.6.1" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" 413 | dependencies = [ 414 | "async-channel", 415 | "async-task", 416 | "futures-io", 417 | "futures-lite 2.6.0", 418 | "piper", 419 | ] 420 | 421 | [[package]] 422 | name = "blowfish" 423 | version = "0.9.1" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" 426 | dependencies = [ 427 | "byteorder", 428 | "cipher", 429 | ] 430 | 431 | [[package]] 432 | name = "bumpalo" 433 | version = "3.17.0" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" 436 | 437 | [[package]] 438 | name = "byteorder" 439 | version = "1.5.0" 440 | source = "registry+https://github.com/rust-lang/crates.io-index" 441 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 442 | 443 | [[package]] 444 | name = "bytes" 445 | version = "1.10.0" 446 | source = "registry+https://github.com/rust-lang/crates.io-index" 447 | checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" 448 | 449 | [[package]] 450 | name = "cbc" 451 | version = "0.1.2" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" 454 | dependencies = [ 455 | "cipher", 456 | ] 457 | 458 | [[package]] 459 | name = "cc" 460 | version = "1.2.15" 461 | source = "registry+https://github.com/rust-lang/crates.io-index" 462 | checksum = "c736e259eea577f443d5c86c304f9f4ae0295c43f3ba05c21f1d66b5f06001af" 463 | dependencies = [ 464 | "shlex", 465 | ] 466 | 467 | [[package]] 468 | name = "cfg-if" 469 | version = "0.1.10" 470 | source = "registry+https://github.com/rust-lang/crates.io-index" 471 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 472 | 473 | [[package]] 474 | name = "cfg-if" 475 | version = "1.0.0" 476 | source = "registry+https://github.com/rust-lang/crates.io-index" 477 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 478 | 479 | [[package]] 480 | name = "chacha20" 481 | version = "0.9.1" 482 | source = "registry+https://github.com/rust-lang/crates.io-index" 483 | checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" 484 | dependencies = [ 485 | "cfg-if 1.0.0", 486 | "cipher", 487 | "cpufeatures", 488 | ] 489 | 490 | [[package]] 491 | name = "chrono" 492 | version = "0.4.39" 493 | source = "registry+https://github.com/rust-lang/crates.io-index" 494 | checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" 495 | dependencies = [ 496 | "android-tzdata", 497 | "iana-time-zone", 498 | "js-sys", 499 | "num-traits", 500 | "wasm-bindgen", 501 | "windows-targets 0.52.6", 502 | ] 503 | 504 | [[package]] 505 | name = "cipher" 506 | version = "0.4.4" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" 509 | dependencies = [ 510 | "crypto-common", 511 | "inout", 512 | ] 513 | 514 | [[package]] 515 | name = "clap" 516 | version = "4.5.30" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "92b7b18d71fad5313a1e320fa9897994228ce274b60faa4d694fe0ea89cd9e6d" 519 | dependencies = [ 520 | "clap_builder", 521 | "clap_derive", 522 | ] 523 | 524 | [[package]] 525 | name = "clap_builder" 526 | version = "4.5.30" 527 | source = "registry+https://github.com/rust-lang/crates.io-index" 528 | checksum = "a35db2071778a7344791a4fb4f95308b5673d219dee3ae348b86642574ecc90c" 529 | dependencies = [ 530 | "anstream", 531 | "anstyle", 532 | "clap_lex", 533 | "strsim", 534 | ] 535 | 536 | [[package]] 537 | name = "clap_derive" 538 | version = "4.5.28" 539 | source = "registry+https://github.com/rust-lang/crates.io-index" 540 | checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" 541 | dependencies = [ 542 | "heck", 543 | "proc-macro2", 544 | "quote", 545 | "syn 2.0.98", 546 | ] 547 | 548 | [[package]] 549 | name = "clap_lex" 550 | version = "0.7.4" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" 553 | 554 | [[package]] 555 | name = "colorchoice" 556 | version = "1.0.3" 557 | source = "registry+https://github.com/rust-lang/crates.io-index" 558 | checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" 559 | 560 | [[package]] 561 | name = "concurrent-queue" 562 | version = "2.5.0" 563 | source = "registry+https://github.com/rust-lang/crates.io-index" 564 | checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" 565 | dependencies = [ 566 | "crossbeam-utils", 567 | ] 568 | 569 | [[package]] 570 | name = "const-oid" 571 | version = "0.9.6" 572 | source = "registry+https://github.com/rust-lang/crates.io-index" 573 | checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" 574 | 575 | [[package]] 576 | name = "core-foundation" 577 | version = "0.9.4" 578 | source = "registry+https://github.com/rust-lang/crates.io-index" 579 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 580 | dependencies = [ 581 | "core-foundation-sys", 582 | "libc", 583 | ] 584 | 585 | [[package]] 586 | name = "core-foundation-sys" 587 | version = "0.8.7" 588 | source = "registry+https://github.com/rust-lang/crates.io-index" 589 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 590 | 591 | [[package]] 592 | name = "cpufeatures" 593 | version = "0.2.17" 594 | source = "registry+https://github.com/rust-lang/crates.io-index" 595 | checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" 596 | dependencies = [ 597 | "libc", 598 | ] 599 | 600 | [[package]] 601 | name = "crc32fast" 602 | version = "1.4.2" 603 | source = "registry+https://github.com/rust-lang/crates.io-index" 604 | checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" 605 | dependencies = [ 606 | "cfg-if 1.0.0", 607 | ] 608 | 609 | [[package]] 610 | name = "crossbeam-utils" 611 | version = "0.8.21" 612 | source = "registry+https://github.com/rust-lang/crates.io-index" 613 | checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" 614 | 615 | [[package]] 616 | name = "crypto-bigint" 617 | version = "0.5.5" 618 | source = "registry+https://github.com/rust-lang/crates.io-index" 619 | checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" 620 | dependencies = [ 621 | "generic-array", 622 | "rand_core 0.6.4", 623 | "subtle", 624 | "zeroize", 625 | ] 626 | 627 | [[package]] 628 | name = "crypto-common" 629 | version = "0.1.6" 630 | source = "registry+https://github.com/rust-lang/crates.io-index" 631 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 632 | dependencies = [ 633 | "generic-array", 634 | "rand_core 0.6.4", 635 | "typenum", 636 | ] 637 | 638 | [[package]] 639 | name = "ctr" 640 | version = "0.9.2" 641 | source = "registry+https://github.com/rust-lang/crates.io-index" 642 | checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" 643 | dependencies = [ 644 | "cipher", 645 | ] 646 | 647 | [[package]] 648 | name = "curve25519-dalek" 649 | version = "4.1.3" 650 | source = "registry+https://github.com/rust-lang/crates.io-index" 651 | checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" 652 | dependencies = [ 653 | "cfg-if 1.0.0", 654 | "cpufeatures", 655 | "curve25519-dalek-derive", 656 | "digest", 657 | "fiat-crypto", 658 | "rustc_version", 659 | "subtle", 660 | "zeroize", 661 | ] 662 | 663 | [[package]] 664 | name = "curve25519-dalek-derive" 665 | version = "0.1.1" 666 | source = "registry+https://github.com/rust-lang/crates.io-index" 667 | checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" 668 | dependencies = [ 669 | "proc-macro2", 670 | "quote", 671 | "syn 2.0.98", 672 | ] 673 | 674 | [[package]] 675 | name = "data-encoding" 676 | version = "2.8.0" 677 | source = "registry+https://github.com/rust-lang/crates.io-index" 678 | checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" 679 | 680 | [[package]] 681 | name = "der" 682 | version = "0.7.9" 683 | source = "registry+https://github.com/rust-lang/crates.io-index" 684 | checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" 685 | dependencies = [ 686 | "const-oid", 687 | "pem-rfc7468", 688 | "zeroize", 689 | ] 690 | 691 | [[package]] 692 | name = "derivative" 693 | version = "2.2.0" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" 696 | dependencies = [ 697 | "proc-macro2", 698 | "quote", 699 | "syn 1.0.109", 700 | ] 701 | 702 | [[package]] 703 | name = "dialog" 704 | version = "0.3.0" 705 | source = "registry+https://github.com/rust-lang/crates.io-index" 706 | checksum = "736bab36d647d14c985725a57a4110a1182c6852104536cd42f1c97e96d29bf0" 707 | dependencies = [ 708 | "dirs 2.0.2", 709 | "rpassword", 710 | ] 711 | 712 | [[package]] 713 | name = "digest" 714 | version = "0.10.7" 715 | source = "registry+https://github.com/rust-lang/crates.io-index" 716 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 717 | dependencies = [ 718 | "block-buffer", 719 | "const-oid", 720 | "crypto-common", 721 | "subtle", 722 | ] 723 | 724 | [[package]] 725 | name = "dirs" 726 | version = "2.0.2" 727 | source = "registry+https://github.com/rust-lang/crates.io-index" 728 | checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" 729 | dependencies = [ 730 | "cfg-if 0.1.10", 731 | "dirs-sys 0.3.7", 732 | ] 733 | 734 | [[package]] 735 | name = "dirs" 736 | version = "5.0.1" 737 | source = "registry+https://github.com/rust-lang/crates.io-index" 738 | checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" 739 | dependencies = [ 740 | "dirs-sys 0.4.1", 741 | ] 742 | 743 | [[package]] 744 | name = "dirs-sys" 745 | version = "0.3.7" 746 | source = "registry+https://github.com/rust-lang/crates.io-index" 747 | checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" 748 | dependencies = [ 749 | "libc", 750 | "redox_users", 751 | "winapi 0.3.9", 752 | ] 753 | 754 | [[package]] 755 | name = "dirs-sys" 756 | version = "0.4.1" 757 | source = "registry+https://github.com/rust-lang/crates.io-index" 758 | checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" 759 | dependencies = [ 760 | "libc", 761 | "option-ext", 762 | "redox_users", 763 | "windows-sys 0.48.0", 764 | ] 765 | 766 | [[package]] 767 | name = "ecdsa" 768 | version = "0.16.9" 769 | source = "registry+https://github.com/rust-lang/crates.io-index" 770 | checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" 771 | dependencies = [ 772 | "der", 773 | "digest", 774 | "elliptic-curve", 775 | "rfc6979", 776 | "signature", 777 | "spki", 778 | ] 779 | 780 | [[package]] 781 | name = "ed25519" 782 | version = "2.2.3" 783 | source = "registry+https://github.com/rust-lang/crates.io-index" 784 | checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" 785 | dependencies = [ 786 | "pkcs8", 787 | "signature", 788 | ] 789 | 790 | [[package]] 791 | name = "ed25519-dalek" 792 | version = "2.1.1" 793 | source = "registry+https://github.com/rust-lang/crates.io-index" 794 | checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" 795 | dependencies = [ 796 | "curve25519-dalek", 797 | "ed25519", 798 | "rand_core 0.6.4", 799 | "serde", 800 | "sha2", 801 | "subtle", 802 | "zeroize", 803 | ] 804 | 805 | [[package]] 806 | name = "elliptic-curve" 807 | version = "0.13.8" 808 | source = "registry+https://github.com/rust-lang/crates.io-index" 809 | checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" 810 | dependencies = [ 811 | "base16ct", 812 | "crypto-bigint", 813 | "digest", 814 | "ff", 815 | "generic-array", 816 | "group", 817 | "pem-rfc7468", 818 | "pkcs8", 819 | "rand_core 0.6.4", 820 | "sec1", 821 | "subtle", 822 | "zeroize", 823 | ] 824 | 825 | [[package]] 826 | name = "enumflags2" 827 | version = "0.7.11" 828 | source = "registry+https://github.com/rust-lang/crates.io-index" 829 | checksum = "ba2f4b465f5318854c6f8dd686ede6c0a9dc67d4b1ac241cf0eb51521a309147" 830 | dependencies = [ 831 | "enumflags2_derive", 832 | "serde", 833 | ] 834 | 835 | [[package]] 836 | name = "enumflags2_derive" 837 | version = "0.7.11" 838 | source = "registry+https://github.com/rust-lang/crates.io-index" 839 | checksum = "fc4caf64a58d7a6d65ab00639b046ff54399a39f5f2554728895ace4b297cd79" 840 | dependencies = [ 841 | "proc-macro2", 842 | "quote", 843 | "syn 2.0.98", 844 | ] 845 | 846 | [[package]] 847 | name = "equivalent" 848 | version = "1.0.2" 849 | source = "registry+https://github.com/rust-lang/crates.io-index" 850 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 851 | 852 | [[package]] 853 | name = "errno" 854 | version = "0.3.10" 855 | source = "registry+https://github.com/rust-lang/crates.io-index" 856 | checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" 857 | dependencies = [ 858 | "libc", 859 | "windows-sys 0.59.0", 860 | ] 861 | 862 | [[package]] 863 | name = "event-listener" 864 | version = "2.5.3" 865 | source = "registry+https://github.com/rust-lang/crates.io-index" 866 | checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" 867 | 868 | [[package]] 869 | name = "event-listener" 870 | version = "3.1.0" 871 | source = "registry+https://github.com/rust-lang/crates.io-index" 872 | checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" 873 | dependencies = [ 874 | "concurrent-queue", 875 | "parking", 876 | "pin-project-lite", 877 | ] 878 | 879 | [[package]] 880 | name = "event-listener" 881 | version = "5.4.0" 882 | source = "registry+https://github.com/rust-lang/crates.io-index" 883 | checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" 884 | dependencies = [ 885 | "concurrent-queue", 886 | "parking", 887 | "pin-project-lite", 888 | ] 889 | 890 | [[package]] 891 | name = "event-listener-strategy" 892 | version = "0.5.3" 893 | source = "registry+https://github.com/rust-lang/crates.io-index" 894 | checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" 895 | dependencies = [ 896 | "event-listener 5.4.0", 897 | "pin-project-lite", 898 | ] 899 | 900 | [[package]] 901 | name = "extrasafe" 902 | version = "0.3.0" 903 | source = "registry+https://github.com/rust-lang/crates.io-index" 904 | checksum = "e50420159c8230d3cd4a9e59d39aa0d6ce99583e2df1d3562a52351462bd469f" 905 | dependencies = [ 906 | "libc", 907 | "seccompiler", 908 | "syscalls", 909 | ] 910 | 911 | [[package]] 912 | name = "fallible-iterator" 913 | version = "0.2.0" 914 | source = "registry+https://github.com/rust-lang/crates.io-index" 915 | checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" 916 | 917 | [[package]] 918 | name = "fallible-streaming-iterator" 919 | version = "0.1.9" 920 | source = "registry+https://github.com/rust-lang/crates.io-index" 921 | checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" 922 | 923 | [[package]] 924 | name = "fastrand" 925 | version = "1.9.0" 926 | source = "registry+https://github.com/rust-lang/crates.io-index" 927 | checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" 928 | dependencies = [ 929 | "instant", 930 | ] 931 | 932 | [[package]] 933 | name = "fastrand" 934 | version = "2.3.0" 935 | source = "registry+https://github.com/rust-lang/crates.io-index" 936 | checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" 937 | 938 | [[package]] 939 | name = "ff" 940 | version = "0.13.0" 941 | source = "registry+https://github.com/rust-lang/crates.io-index" 942 | checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" 943 | dependencies = [ 944 | "rand_core 0.6.4", 945 | "subtle", 946 | ] 947 | 948 | [[package]] 949 | name = "fiat-crypto" 950 | version = "0.2.9" 951 | source = "registry+https://github.com/rust-lang/crates.io-index" 952 | checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" 953 | 954 | [[package]] 955 | name = "flate2" 956 | version = "1.0.35" 957 | source = "registry+https://github.com/rust-lang/crates.io-index" 958 | checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" 959 | dependencies = [ 960 | "crc32fast", 961 | "miniz_oxide", 962 | ] 963 | 964 | [[package]] 965 | name = "foreign-types" 966 | version = "0.3.2" 967 | source = "registry+https://github.com/rust-lang/crates.io-index" 968 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 969 | dependencies = [ 970 | "foreign-types-shared", 971 | ] 972 | 973 | [[package]] 974 | name = "foreign-types-shared" 975 | version = "0.1.1" 976 | source = "registry+https://github.com/rust-lang/crates.io-index" 977 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 978 | 979 | [[package]] 980 | name = "futures" 981 | version = "0.3.31" 982 | source = "registry+https://github.com/rust-lang/crates.io-index" 983 | checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" 984 | dependencies = [ 985 | "futures-channel", 986 | "futures-core", 987 | "futures-executor", 988 | "futures-io", 989 | "futures-sink", 990 | "futures-task", 991 | "futures-util", 992 | ] 993 | 994 | [[package]] 995 | name = "futures-channel" 996 | version = "0.3.31" 997 | source = "registry+https://github.com/rust-lang/crates.io-index" 998 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 999 | dependencies = [ 1000 | "futures-core", 1001 | "futures-sink", 1002 | ] 1003 | 1004 | [[package]] 1005 | name = "futures-core" 1006 | version = "0.3.31" 1007 | source = "registry+https://github.com/rust-lang/crates.io-index" 1008 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 1009 | 1010 | [[package]] 1011 | name = "futures-executor" 1012 | version = "0.3.31" 1013 | source = "registry+https://github.com/rust-lang/crates.io-index" 1014 | checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" 1015 | dependencies = [ 1016 | "futures-core", 1017 | "futures-task", 1018 | "futures-util", 1019 | ] 1020 | 1021 | [[package]] 1022 | name = "futures-io" 1023 | version = "0.3.31" 1024 | source = "registry+https://github.com/rust-lang/crates.io-index" 1025 | checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 1026 | 1027 | [[package]] 1028 | name = "futures-lite" 1029 | version = "1.13.0" 1030 | source = "registry+https://github.com/rust-lang/crates.io-index" 1031 | checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" 1032 | dependencies = [ 1033 | "fastrand 1.9.0", 1034 | "futures-core", 1035 | "futures-io", 1036 | "memchr", 1037 | "parking", 1038 | "pin-project-lite", 1039 | "waker-fn", 1040 | ] 1041 | 1042 | [[package]] 1043 | name = "futures-lite" 1044 | version = "2.6.0" 1045 | source = "registry+https://github.com/rust-lang/crates.io-index" 1046 | checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" 1047 | dependencies = [ 1048 | "fastrand 2.3.0", 1049 | "futures-core", 1050 | "futures-io", 1051 | "parking", 1052 | "pin-project-lite", 1053 | ] 1054 | 1055 | [[package]] 1056 | name = "futures-macro" 1057 | version = "0.3.31" 1058 | source = "registry+https://github.com/rust-lang/crates.io-index" 1059 | checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" 1060 | dependencies = [ 1061 | "proc-macro2", 1062 | "quote", 1063 | "syn 2.0.98", 1064 | ] 1065 | 1066 | [[package]] 1067 | name = "futures-sink" 1068 | version = "0.3.31" 1069 | source = "registry+https://github.com/rust-lang/crates.io-index" 1070 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 1071 | 1072 | [[package]] 1073 | name = "futures-task" 1074 | version = "0.3.31" 1075 | source = "registry+https://github.com/rust-lang/crates.io-index" 1076 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 1077 | 1078 | [[package]] 1079 | name = "futures-util" 1080 | version = "0.3.31" 1081 | source = "registry+https://github.com/rust-lang/crates.io-index" 1082 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 1083 | dependencies = [ 1084 | "futures-channel", 1085 | "futures-core", 1086 | "futures-io", 1087 | "futures-macro", 1088 | "futures-sink", 1089 | "futures-task", 1090 | "memchr", 1091 | "pin-project-lite", 1092 | "pin-utils", 1093 | "slab", 1094 | ] 1095 | 1096 | [[package]] 1097 | name = "generic-array" 1098 | version = "0.14.7" 1099 | source = "registry+https://github.com/rust-lang/crates.io-index" 1100 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 1101 | dependencies = [ 1102 | "typenum", 1103 | "version_check", 1104 | "zeroize", 1105 | ] 1106 | 1107 | [[package]] 1108 | name = "getrandom" 1109 | version = "0.1.16" 1110 | source = "registry+https://github.com/rust-lang/crates.io-index" 1111 | checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" 1112 | dependencies = [ 1113 | "cfg-if 1.0.0", 1114 | "libc", 1115 | "wasi 0.9.0+wasi-snapshot-preview1", 1116 | ] 1117 | 1118 | [[package]] 1119 | name = "getrandom" 1120 | version = "0.2.15" 1121 | source = "registry+https://github.com/rust-lang/crates.io-index" 1122 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 1123 | dependencies = [ 1124 | "cfg-if 1.0.0", 1125 | "libc", 1126 | "wasi 0.11.0+wasi-snapshot-preview1", 1127 | ] 1128 | 1129 | [[package]] 1130 | name = "getrandom" 1131 | version = "0.3.1" 1132 | source = "registry+https://github.com/rust-lang/crates.io-index" 1133 | checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" 1134 | dependencies = [ 1135 | "cfg-if 1.0.0", 1136 | "libc", 1137 | "wasi 0.13.3+wasi-0.2.2", 1138 | "windows-targets 0.52.6", 1139 | ] 1140 | 1141 | [[package]] 1142 | name = "ghash" 1143 | version = "0.5.1" 1144 | source = "registry+https://github.com/rust-lang/crates.io-index" 1145 | checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" 1146 | dependencies = [ 1147 | "opaque-debug", 1148 | "polyval", 1149 | ] 1150 | 1151 | [[package]] 1152 | name = "gimli" 1153 | version = "0.31.1" 1154 | source = "registry+https://github.com/rust-lang/crates.io-index" 1155 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 1156 | 1157 | [[package]] 1158 | name = "group" 1159 | version = "0.13.0" 1160 | source = "registry+https://github.com/rust-lang/crates.io-index" 1161 | checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" 1162 | dependencies = [ 1163 | "ff", 1164 | "rand_core 0.6.4", 1165 | "subtle", 1166 | ] 1167 | 1168 | [[package]] 1169 | name = "hashbrown" 1170 | version = "0.14.5" 1171 | source = "registry+https://github.com/rust-lang/crates.io-index" 1172 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 1173 | dependencies = [ 1174 | "ahash", 1175 | "allocator-api2", 1176 | ] 1177 | 1178 | [[package]] 1179 | name = "hashbrown" 1180 | version = "0.15.2" 1181 | source = "registry+https://github.com/rust-lang/crates.io-index" 1182 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 1183 | 1184 | [[package]] 1185 | name = "hashlink" 1186 | version = "0.8.4" 1187 | source = "registry+https://github.com/rust-lang/crates.io-index" 1188 | checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" 1189 | dependencies = [ 1190 | "hashbrown 0.14.5", 1191 | ] 1192 | 1193 | [[package]] 1194 | name = "heck" 1195 | version = "0.5.0" 1196 | source = "registry+https://github.com/rust-lang/crates.io-index" 1197 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 1198 | 1199 | [[package]] 1200 | name = "hermit-abi" 1201 | version = "0.3.9" 1202 | source = "registry+https://github.com/rust-lang/crates.io-index" 1203 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 1204 | 1205 | [[package]] 1206 | name = "hermit-abi" 1207 | version = "0.4.0" 1208 | source = "registry+https://github.com/rust-lang/crates.io-index" 1209 | checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" 1210 | 1211 | [[package]] 1212 | name = "hex" 1213 | version = "0.4.3" 1214 | source = "registry+https://github.com/rust-lang/crates.io-index" 1215 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 1216 | 1217 | [[package]] 1218 | name = "hex-literal" 1219 | version = "0.4.1" 1220 | source = "registry+https://github.com/rust-lang/crates.io-index" 1221 | checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" 1222 | 1223 | [[package]] 1224 | name = "hkdf" 1225 | version = "0.12.4" 1226 | source = "registry+https://github.com/rust-lang/crates.io-index" 1227 | checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" 1228 | dependencies = [ 1229 | "hmac", 1230 | ] 1231 | 1232 | [[package]] 1233 | name = "hmac" 1234 | version = "0.12.1" 1235 | source = "registry+https://github.com/rust-lang/crates.io-index" 1236 | checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" 1237 | dependencies = [ 1238 | "digest", 1239 | ] 1240 | 1241 | [[package]] 1242 | name = "iana-time-zone" 1243 | version = "0.1.61" 1244 | source = "registry+https://github.com/rust-lang/crates.io-index" 1245 | checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" 1246 | dependencies = [ 1247 | "android_system_properties", 1248 | "core-foundation-sys", 1249 | "iana-time-zone-haiku", 1250 | "js-sys", 1251 | "wasm-bindgen", 1252 | "windows-core", 1253 | ] 1254 | 1255 | [[package]] 1256 | name = "iana-time-zone-haiku" 1257 | version = "0.1.2" 1258 | source = "registry+https://github.com/rust-lang/crates.io-index" 1259 | checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" 1260 | dependencies = [ 1261 | "cc", 1262 | ] 1263 | 1264 | [[package]] 1265 | name = "indexmap" 1266 | version = "2.7.1" 1267 | source = "registry+https://github.com/rust-lang/crates.io-index" 1268 | checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" 1269 | dependencies = [ 1270 | "equivalent", 1271 | "hashbrown 0.15.2", 1272 | ] 1273 | 1274 | [[package]] 1275 | name = "inout" 1276 | version = "0.1.4" 1277 | source = "registry+https://github.com/rust-lang/crates.io-index" 1278 | checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" 1279 | dependencies = [ 1280 | "block-padding", 1281 | "generic-array", 1282 | ] 1283 | 1284 | [[package]] 1285 | name = "instant" 1286 | version = "0.1.13" 1287 | source = "registry+https://github.com/rust-lang/crates.io-index" 1288 | checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" 1289 | dependencies = [ 1290 | "cfg-if 1.0.0", 1291 | ] 1292 | 1293 | [[package]] 1294 | name = "io-lifetimes" 1295 | version = "1.0.11" 1296 | source = "registry+https://github.com/rust-lang/crates.io-index" 1297 | checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" 1298 | dependencies = [ 1299 | "hermit-abi 0.3.9", 1300 | "libc", 1301 | "windows-sys 0.48.0", 1302 | ] 1303 | 1304 | [[package]] 1305 | name = "is_terminal_polyfill" 1306 | version = "1.70.1" 1307 | source = "registry+https://github.com/rust-lang/crates.io-index" 1308 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 1309 | 1310 | [[package]] 1311 | name = "js-sys" 1312 | version = "0.3.77" 1313 | source = "registry+https://github.com/rust-lang/crates.io-index" 1314 | checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" 1315 | dependencies = [ 1316 | "once_cell", 1317 | "wasm-bindgen", 1318 | ] 1319 | 1320 | [[package]] 1321 | name = "kernel32-sys" 1322 | version = "0.2.2" 1323 | source = "registry+https://github.com/rust-lang/crates.io-index" 1324 | checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 1325 | dependencies = [ 1326 | "winapi 0.2.8", 1327 | "winapi-build", 1328 | ] 1329 | 1330 | [[package]] 1331 | name = "keyring" 1332 | version = "2.3.3" 1333 | source = "registry+https://github.com/rust-lang/crates.io-index" 1334 | checksum = "363387f0019d714aa60cc30ab4fe501a747f4c08fc58f069dd14be971bd495a0" 1335 | dependencies = [ 1336 | "byteorder", 1337 | "lazy_static", 1338 | "linux-keyutils", 1339 | "secret-service", 1340 | "security-framework", 1341 | "windows-sys 0.52.0", 1342 | ] 1343 | 1344 | [[package]] 1345 | name = "lazy_static" 1346 | version = "1.5.0" 1347 | source = "registry+https://github.com/rust-lang/crates.io-index" 1348 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 1349 | 1350 | [[package]] 1351 | name = "libc" 1352 | version = "0.2.170" 1353 | source = "registry+https://github.com/rust-lang/crates.io-index" 1354 | checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" 1355 | 1356 | [[package]] 1357 | name = "libredox" 1358 | version = "0.1.3" 1359 | source = "registry+https://github.com/rust-lang/crates.io-index" 1360 | checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" 1361 | dependencies = [ 1362 | "bitflags 2.8.0", 1363 | "libc", 1364 | ] 1365 | 1366 | [[package]] 1367 | name = "libsqlite3-sys" 1368 | version = "0.26.0" 1369 | source = "registry+https://github.com/rust-lang/crates.io-index" 1370 | checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" 1371 | dependencies = [ 1372 | "pkg-config", 1373 | "vcpkg", 1374 | ] 1375 | 1376 | [[package]] 1377 | name = "linux-keyutils" 1378 | version = "0.2.4" 1379 | source = "registry+https://github.com/rust-lang/crates.io-index" 1380 | checksum = "761e49ec5fd8a5a463f9b84e877c373d888935b71c6be78f3767fe2ae6bed18e" 1381 | dependencies = [ 1382 | "bitflags 2.8.0", 1383 | "libc", 1384 | ] 1385 | 1386 | [[package]] 1387 | name = "linux-raw-sys" 1388 | version = "0.3.8" 1389 | source = "registry+https://github.com/rust-lang/crates.io-index" 1390 | checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" 1391 | 1392 | [[package]] 1393 | name = "linux-raw-sys" 1394 | version = "0.4.15" 1395 | source = "registry+https://github.com/rust-lang/crates.io-index" 1396 | checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" 1397 | 1398 | [[package]] 1399 | name = "lock_api" 1400 | version = "0.4.12" 1401 | source = "registry+https://github.com/rust-lang/crates.io-index" 1402 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 1403 | dependencies = [ 1404 | "autocfg", 1405 | "scopeguard", 1406 | ] 1407 | 1408 | [[package]] 1409 | name = "log" 1410 | version = "0.4.26" 1411 | source = "registry+https://github.com/rust-lang/crates.io-index" 1412 | checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" 1413 | 1414 | [[package]] 1415 | name = "md5" 1416 | version = "0.7.0" 1417 | source = "registry+https://github.com/rust-lang/crates.io-index" 1418 | checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" 1419 | 1420 | [[package]] 1421 | name = "memchr" 1422 | version = "2.7.4" 1423 | source = "registry+https://github.com/rust-lang/crates.io-index" 1424 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 1425 | 1426 | [[package]] 1427 | name = "memoffset" 1428 | version = "0.7.1" 1429 | source = "registry+https://github.com/rust-lang/crates.io-index" 1430 | checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" 1431 | dependencies = [ 1432 | "autocfg", 1433 | ] 1434 | 1435 | [[package]] 1436 | name = "memoffset" 1437 | version = "0.9.1" 1438 | source = "registry+https://github.com/rust-lang/crates.io-index" 1439 | checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" 1440 | dependencies = [ 1441 | "autocfg", 1442 | ] 1443 | 1444 | [[package]] 1445 | name = "miniz_oxide" 1446 | version = "0.8.5" 1447 | source = "registry+https://github.com/rust-lang/crates.io-index" 1448 | checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" 1449 | dependencies = [ 1450 | "adler2", 1451 | ] 1452 | 1453 | [[package]] 1454 | name = "mio" 1455 | version = "1.0.3" 1456 | source = "registry+https://github.com/rust-lang/crates.io-index" 1457 | checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" 1458 | dependencies = [ 1459 | "libc", 1460 | "wasi 0.11.0+wasi-snapshot-preview1", 1461 | "windows-sys 0.52.0", 1462 | ] 1463 | 1464 | [[package]] 1465 | name = "nix" 1466 | version = "0.26.4" 1467 | source = "registry+https://github.com/rust-lang/crates.io-index" 1468 | checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" 1469 | dependencies = [ 1470 | "bitflags 1.3.2", 1471 | "cfg-if 1.0.0", 1472 | "libc", 1473 | "memoffset 0.7.1", 1474 | ] 1475 | 1476 | [[package]] 1477 | name = "num" 1478 | version = "0.4.3" 1479 | source = "registry+https://github.com/rust-lang/crates.io-index" 1480 | checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" 1481 | dependencies = [ 1482 | "num-bigint", 1483 | "num-complex", 1484 | "num-integer", 1485 | "num-iter", 1486 | "num-rational", 1487 | "num-traits", 1488 | ] 1489 | 1490 | [[package]] 1491 | name = "num-bigint" 1492 | version = "0.4.6" 1493 | source = "registry+https://github.com/rust-lang/crates.io-index" 1494 | checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" 1495 | dependencies = [ 1496 | "num-integer", 1497 | "num-traits", 1498 | "rand 0.8.5", 1499 | ] 1500 | 1501 | [[package]] 1502 | name = "num-complex" 1503 | version = "0.4.6" 1504 | source = "registry+https://github.com/rust-lang/crates.io-index" 1505 | checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" 1506 | dependencies = [ 1507 | "num-traits", 1508 | ] 1509 | 1510 | [[package]] 1511 | name = "num-integer" 1512 | version = "0.1.46" 1513 | source = "registry+https://github.com/rust-lang/crates.io-index" 1514 | checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 1515 | dependencies = [ 1516 | "num-traits", 1517 | ] 1518 | 1519 | [[package]] 1520 | name = "num-iter" 1521 | version = "0.1.45" 1522 | source = "registry+https://github.com/rust-lang/crates.io-index" 1523 | checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" 1524 | dependencies = [ 1525 | "autocfg", 1526 | "num-integer", 1527 | "num-traits", 1528 | ] 1529 | 1530 | [[package]] 1531 | name = "num-rational" 1532 | version = "0.4.2" 1533 | source = "registry+https://github.com/rust-lang/crates.io-index" 1534 | checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" 1535 | dependencies = [ 1536 | "num-bigint", 1537 | "num-integer", 1538 | "num-traits", 1539 | ] 1540 | 1541 | [[package]] 1542 | name = "num-traits" 1543 | version = "0.2.19" 1544 | source = "registry+https://github.com/rust-lang/crates.io-index" 1545 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 1546 | dependencies = [ 1547 | "autocfg", 1548 | ] 1549 | 1550 | [[package]] 1551 | name = "object" 1552 | version = "0.36.7" 1553 | source = "registry+https://github.com/rust-lang/crates.io-index" 1554 | checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 1555 | dependencies = [ 1556 | "memchr", 1557 | ] 1558 | 1559 | [[package]] 1560 | name = "once_cell" 1561 | version = "1.20.3" 1562 | source = "registry+https://github.com/rust-lang/crates.io-index" 1563 | checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" 1564 | 1565 | [[package]] 1566 | name = "opaque-debug" 1567 | version = "0.3.1" 1568 | source = "registry+https://github.com/rust-lang/crates.io-index" 1569 | checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" 1570 | 1571 | [[package]] 1572 | name = "openssl" 1573 | version = "0.10.71" 1574 | source = "registry+https://github.com/rust-lang/crates.io-index" 1575 | checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" 1576 | dependencies = [ 1577 | "bitflags 2.8.0", 1578 | "cfg-if 1.0.0", 1579 | "foreign-types", 1580 | "libc", 1581 | "once_cell", 1582 | "openssl-macros", 1583 | "openssl-sys", 1584 | ] 1585 | 1586 | [[package]] 1587 | name = "openssl-macros" 1588 | version = "0.1.1" 1589 | source = "registry+https://github.com/rust-lang/crates.io-index" 1590 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 1591 | dependencies = [ 1592 | "proc-macro2", 1593 | "quote", 1594 | "syn 2.0.98", 1595 | ] 1596 | 1597 | [[package]] 1598 | name = "openssl-sys" 1599 | version = "0.9.106" 1600 | source = "registry+https://github.com/rust-lang/crates.io-index" 1601 | checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" 1602 | dependencies = [ 1603 | "cc", 1604 | "libc", 1605 | "pkg-config", 1606 | "vcpkg", 1607 | ] 1608 | 1609 | [[package]] 1610 | name = "option-ext" 1611 | version = "0.2.0" 1612 | source = "registry+https://github.com/rust-lang/crates.io-index" 1613 | checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" 1614 | 1615 | [[package]] 1616 | name = "ordered-stream" 1617 | version = "0.2.0" 1618 | source = "registry+https://github.com/rust-lang/crates.io-index" 1619 | checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" 1620 | dependencies = [ 1621 | "futures-core", 1622 | "pin-project-lite", 1623 | ] 1624 | 1625 | [[package]] 1626 | name = "p256" 1627 | version = "0.13.2" 1628 | source = "registry+https://github.com/rust-lang/crates.io-index" 1629 | checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" 1630 | dependencies = [ 1631 | "ecdsa", 1632 | "elliptic-curve", 1633 | "primeorder", 1634 | "sha2", 1635 | ] 1636 | 1637 | [[package]] 1638 | name = "parking" 1639 | version = "2.2.1" 1640 | source = "registry+https://github.com/rust-lang/crates.io-index" 1641 | checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" 1642 | 1643 | [[package]] 1644 | name = "parking_lot" 1645 | version = "0.12.3" 1646 | source = "registry+https://github.com/rust-lang/crates.io-index" 1647 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 1648 | dependencies = [ 1649 | "lock_api", 1650 | "parking_lot_core", 1651 | ] 1652 | 1653 | [[package]] 1654 | name = "parking_lot_core" 1655 | version = "0.9.10" 1656 | source = "registry+https://github.com/rust-lang/crates.io-index" 1657 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 1658 | dependencies = [ 1659 | "cfg-if 1.0.0", 1660 | "libc", 1661 | "redox_syscall", 1662 | "smallvec", 1663 | "windows-targets 0.52.6", 1664 | ] 1665 | 1666 | [[package]] 1667 | name = "password-hash" 1668 | version = "0.4.2" 1669 | source = "registry+https://github.com/rust-lang/crates.io-index" 1670 | checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" 1671 | dependencies = [ 1672 | "base64ct", 1673 | "rand_core 0.6.4", 1674 | "subtle", 1675 | ] 1676 | 1677 | [[package]] 1678 | name = "pbkdf2" 1679 | version = "0.11.0" 1680 | source = "registry+https://github.com/rust-lang/crates.io-index" 1681 | checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" 1682 | dependencies = [ 1683 | "digest", 1684 | "hmac", 1685 | "password-hash", 1686 | "sha2", 1687 | ] 1688 | 1689 | [[package]] 1690 | name = "pbkdf2" 1691 | version = "0.12.2" 1692 | source = "registry+https://github.com/rust-lang/crates.io-index" 1693 | checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" 1694 | dependencies = [ 1695 | "digest", 1696 | ] 1697 | 1698 | [[package]] 1699 | name = "pem-rfc7468" 1700 | version = "0.7.0" 1701 | source = "registry+https://github.com/rust-lang/crates.io-index" 1702 | checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" 1703 | dependencies = [ 1704 | "base64ct", 1705 | ] 1706 | 1707 | [[package]] 1708 | name = "pin-project-lite" 1709 | version = "0.2.16" 1710 | source = "registry+https://github.com/rust-lang/crates.io-index" 1711 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 1712 | 1713 | [[package]] 1714 | name = "pin-utils" 1715 | version = "0.1.0" 1716 | source = "registry+https://github.com/rust-lang/crates.io-index" 1717 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1718 | 1719 | [[package]] 1720 | name = "piper" 1721 | version = "0.2.4" 1722 | source = "registry+https://github.com/rust-lang/crates.io-index" 1723 | checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" 1724 | dependencies = [ 1725 | "atomic-waker", 1726 | "fastrand 2.3.0", 1727 | "futures-io", 1728 | ] 1729 | 1730 | [[package]] 1731 | name = "pkcs8" 1732 | version = "0.10.2" 1733 | source = "registry+https://github.com/rust-lang/crates.io-index" 1734 | checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" 1735 | dependencies = [ 1736 | "der", 1737 | "spki", 1738 | ] 1739 | 1740 | [[package]] 1741 | name = "pkg-config" 1742 | version = "0.3.31" 1743 | source = "registry+https://github.com/rust-lang/crates.io-index" 1744 | checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" 1745 | 1746 | [[package]] 1747 | name = "polling" 1748 | version = "2.8.0" 1749 | source = "registry+https://github.com/rust-lang/crates.io-index" 1750 | checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" 1751 | dependencies = [ 1752 | "autocfg", 1753 | "bitflags 1.3.2", 1754 | "cfg-if 1.0.0", 1755 | "concurrent-queue", 1756 | "libc", 1757 | "log", 1758 | "pin-project-lite", 1759 | "windows-sys 0.48.0", 1760 | ] 1761 | 1762 | [[package]] 1763 | name = "polling" 1764 | version = "3.7.4" 1765 | source = "registry+https://github.com/rust-lang/crates.io-index" 1766 | checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" 1767 | dependencies = [ 1768 | "cfg-if 1.0.0", 1769 | "concurrent-queue", 1770 | "hermit-abi 0.4.0", 1771 | "pin-project-lite", 1772 | "rustix 0.38.44", 1773 | "tracing", 1774 | "windows-sys 0.59.0", 1775 | ] 1776 | 1777 | [[package]] 1778 | name = "poly1305" 1779 | version = "0.8.0" 1780 | source = "registry+https://github.com/rust-lang/crates.io-index" 1781 | checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" 1782 | dependencies = [ 1783 | "cpufeatures", 1784 | "opaque-debug", 1785 | "universal-hash", 1786 | ] 1787 | 1788 | [[package]] 1789 | name = "polyval" 1790 | version = "0.6.2" 1791 | source = "registry+https://github.com/rust-lang/crates.io-index" 1792 | checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" 1793 | dependencies = [ 1794 | "cfg-if 1.0.0", 1795 | "cpufeatures", 1796 | "opaque-debug", 1797 | "universal-hash", 1798 | ] 1799 | 1800 | [[package]] 1801 | name = "ppv-lite86" 1802 | version = "0.2.20" 1803 | source = "registry+https://github.com/rust-lang/crates.io-index" 1804 | checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" 1805 | dependencies = [ 1806 | "zerocopy", 1807 | ] 1808 | 1809 | [[package]] 1810 | name = "primeorder" 1811 | version = "0.13.6" 1812 | source = "registry+https://github.com/rust-lang/crates.io-index" 1813 | checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" 1814 | dependencies = [ 1815 | "elliptic-curve", 1816 | ] 1817 | 1818 | [[package]] 1819 | name = "proc-macro-crate" 1820 | version = "1.3.1" 1821 | source = "registry+https://github.com/rust-lang/crates.io-index" 1822 | checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" 1823 | dependencies = [ 1824 | "once_cell", 1825 | "toml_edit", 1826 | ] 1827 | 1828 | [[package]] 1829 | name = "proc-macro2" 1830 | version = "1.0.93" 1831 | source = "registry+https://github.com/rust-lang/crates.io-index" 1832 | checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" 1833 | dependencies = [ 1834 | "unicode-ident", 1835 | ] 1836 | 1837 | [[package]] 1838 | name = "quote" 1839 | version = "1.0.38" 1840 | source = "registry+https://github.com/rust-lang/crates.io-index" 1841 | checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" 1842 | dependencies = [ 1843 | "proc-macro2", 1844 | ] 1845 | 1846 | [[package]] 1847 | name = "rand" 1848 | version = "0.7.3" 1849 | source = "registry+https://github.com/rust-lang/crates.io-index" 1850 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 1851 | dependencies = [ 1852 | "getrandom 0.1.16", 1853 | "libc", 1854 | "rand_chacha 0.2.2", 1855 | "rand_core 0.5.1", 1856 | "rand_hc", 1857 | ] 1858 | 1859 | [[package]] 1860 | name = "rand" 1861 | version = "0.8.5" 1862 | source = "registry+https://github.com/rust-lang/crates.io-index" 1863 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1864 | dependencies = [ 1865 | "libc", 1866 | "rand_chacha 0.3.1", 1867 | "rand_core 0.6.4", 1868 | ] 1869 | 1870 | [[package]] 1871 | name = "rand_chacha" 1872 | version = "0.2.2" 1873 | source = "registry+https://github.com/rust-lang/crates.io-index" 1874 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 1875 | dependencies = [ 1876 | "ppv-lite86", 1877 | "rand_core 0.5.1", 1878 | ] 1879 | 1880 | [[package]] 1881 | name = "rand_chacha" 1882 | version = "0.3.1" 1883 | source = "registry+https://github.com/rust-lang/crates.io-index" 1884 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1885 | dependencies = [ 1886 | "ppv-lite86", 1887 | "rand_core 0.6.4", 1888 | ] 1889 | 1890 | [[package]] 1891 | name = "rand_core" 1892 | version = "0.5.1" 1893 | source = "registry+https://github.com/rust-lang/crates.io-index" 1894 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 1895 | dependencies = [ 1896 | "getrandom 0.1.16", 1897 | ] 1898 | 1899 | [[package]] 1900 | name = "rand_core" 1901 | version = "0.6.4" 1902 | source = "registry+https://github.com/rust-lang/crates.io-index" 1903 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1904 | dependencies = [ 1905 | "getrandom 0.2.15", 1906 | ] 1907 | 1908 | [[package]] 1909 | name = "rand_hc" 1910 | version = "0.2.0" 1911 | source = "registry+https://github.com/rust-lang/crates.io-index" 1912 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 1913 | dependencies = [ 1914 | "rand_core 0.5.1", 1915 | ] 1916 | 1917 | [[package]] 1918 | name = "redox_syscall" 1919 | version = "0.5.9" 1920 | source = "registry+https://github.com/rust-lang/crates.io-index" 1921 | checksum = "82b568323e98e49e2a0899dcee453dd679fae22d69adf9b11dd508d1549b7e2f" 1922 | dependencies = [ 1923 | "bitflags 2.8.0", 1924 | ] 1925 | 1926 | [[package]] 1927 | name = "redox_users" 1928 | version = "0.4.6" 1929 | source = "registry+https://github.com/rust-lang/crates.io-index" 1930 | checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" 1931 | dependencies = [ 1932 | "getrandom 0.2.15", 1933 | "libredox", 1934 | "thiserror", 1935 | ] 1936 | 1937 | [[package]] 1938 | name = "regex" 1939 | version = "1.11.1" 1940 | source = "registry+https://github.com/rust-lang/crates.io-index" 1941 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 1942 | dependencies = [ 1943 | "aho-corasick", 1944 | "memchr", 1945 | "regex-automata", 1946 | "regex-syntax", 1947 | ] 1948 | 1949 | [[package]] 1950 | name = "regex-automata" 1951 | version = "0.4.9" 1952 | source = "registry+https://github.com/rust-lang/crates.io-index" 1953 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 1954 | dependencies = [ 1955 | "aho-corasick", 1956 | "memchr", 1957 | "regex-syntax", 1958 | ] 1959 | 1960 | [[package]] 1961 | name = "regex-syntax" 1962 | version = "0.8.5" 1963 | source = "registry+https://github.com/rust-lang/crates.io-index" 1964 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 1965 | 1966 | [[package]] 1967 | name = "rfc6979" 1968 | version = "0.4.0" 1969 | source = "registry+https://github.com/rust-lang/crates.io-index" 1970 | checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" 1971 | dependencies = [ 1972 | "hmac", 1973 | "subtle", 1974 | ] 1975 | 1976 | [[package]] 1977 | name = "rpassword" 1978 | version = "2.1.0" 1979 | source = "registry+https://github.com/rust-lang/crates.io-index" 1980 | checksum = "d37473170aedbe66ffa3ad3726939ba677d83c646ad4fd99e5b4bc38712f45ec" 1981 | dependencies = [ 1982 | "kernel32-sys", 1983 | "libc", 1984 | "winapi 0.2.8", 1985 | ] 1986 | 1987 | [[package]] 1988 | name = "rusqlite" 1989 | version = "0.29.0" 1990 | source = "registry+https://github.com/rust-lang/crates.io-index" 1991 | checksum = "549b9d036d571d42e6e85d1c1425e2ac83491075078ca9a15be021c56b1641f2" 1992 | dependencies = [ 1993 | "bitflags 2.8.0", 1994 | "fallible-iterator", 1995 | "fallible-streaming-iterator", 1996 | "hashlink", 1997 | "libsqlite3-sys", 1998 | "smallvec", 1999 | ] 2000 | 2001 | [[package]] 2002 | name = "russh" 2003 | version = "0.40.2" 2004 | source = "registry+https://github.com/rust-lang/crates.io-index" 2005 | checksum = "93dab9e1c313d0d04a42e39c0995943fc38c037e2e3fa9c33685777a1aecdfb2" 2006 | dependencies = [ 2007 | "aes", 2008 | "aes-gcm", 2009 | "async-trait", 2010 | "bitflags 2.8.0", 2011 | "byteorder", 2012 | "chacha20", 2013 | "ctr", 2014 | "curve25519-dalek", 2015 | "digest", 2016 | "flate2", 2017 | "futures", 2018 | "generic-array", 2019 | "hex-literal", 2020 | "hmac", 2021 | "log", 2022 | "num-bigint", 2023 | "once_cell", 2024 | "openssl", 2025 | "poly1305", 2026 | "rand 0.8.5", 2027 | "russh-cryptovec", 2028 | "russh-keys", 2029 | "sha1", 2030 | "sha2", 2031 | "subtle", 2032 | "thiserror", 2033 | "tokio", 2034 | "tokio-util", 2035 | ] 2036 | 2037 | [[package]] 2038 | name = "russh-cryptovec" 2039 | version = "0.7.3" 2040 | source = "registry+https://github.com/rust-lang/crates.io-index" 2041 | checksum = "fadd2c0ab350e21c66556f94ee06f766d8bdae3213857ba7610bfd8e10e51880" 2042 | dependencies = [ 2043 | "libc", 2044 | "winapi 0.3.9", 2045 | ] 2046 | 2047 | [[package]] 2048 | name = "russh-keys" 2049 | version = "0.40.1" 2050 | source = "registry+https://github.com/rust-lang/crates.io-index" 2051 | checksum = "9d0de3cb3cbfa773b7f170b6830565fac207a0d630cc666a29f80097cc374dd8" 2052 | dependencies = [ 2053 | "aes", 2054 | "async-trait", 2055 | "bcrypt-pbkdf", 2056 | "bit-vec", 2057 | "block-padding", 2058 | "byteorder", 2059 | "cbc", 2060 | "ctr", 2061 | "data-encoding", 2062 | "dirs 5.0.1", 2063 | "ed25519-dalek", 2064 | "futures", 2065 | "hmac", 2066 | "inout", 2067 | "log", 2068 | "md5", 2069 | "num-bigint", 2070 | "num-integer", 2071 | "openssl", 2072 | "p256", 2073 | "pbkdf2 0.11.0", 2074 | "rand 0.7.3", 2075 | "rand_core 0.6.4", 2076 | "russh-cryptovec", 2077 | "serde", 2078 | "sha1", 2079 | "sha2", 2080 | "thiserror", 2081 | "tokio", 2082 | "tokio-stream", 2083 | "yasna", 2084 | ] 2085 | 2086 | [[package]] 2087 | name = "rustc-demangle" 2088 | version = "0.1.24" 2089 | source = "registry+https://github.com/rust-lang/crates.io-index" 2090 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 2091 | 2092 | [[package]] 2093 | name = "rustc_version" 2094 | version = "0.4.1" 2095 | source = "registry+https://github.com/rust-lang/crates.io-index" 2096 | checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" 2097 | dependencies = [ 2098 | "semver", 2099 | ] 2100 | 2101 | [[package]] 2102 | name = "rustix" 2103 | version = "0.37.28" 2104 | source = "registry+https://github.com/rust-lang/crates.io-index" 2105 | checksum = "519165d378b97752ca44bbe15047d5d3409e875f39327546b42ac81d7e18c1b6" 2106 | dependencies = [ 2107 | "bitflags 1.3.2", 2108 | "errno", 2109 | "io-lifetimes", 2110 | "libc", 2111 | "linux-raw-sys 0.3.8", 2112 | "windows-sys 0.48.0", 2113 | ] 2114 | 2115 | [[package]] 2116 | name = "rustix" 2117 | version = "0.38.44" 2118 | source = "registry+https://github.com/rust-lang/crates.io-index" 2119 | checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" 2120 | dependencies = [ 2121 | "bitflags 2.8.0", 2122 | "errno", 2123 | "libc", 2124 | "linux-raw-sys 0.4.15", 2125 | "windows-sys 0.59.0", 2126 | ] 2127 | 2128 | [[package]] 2129 | name = "rustversion" 2130 | version = "1.0.19" 2131 | source = "registry+https://github.com/rust-lang/crates.io-index" 2132 | checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" 2133 | 2134 | [[package]] 2135 | name = "scopeguard" 2136 | version = "1.2.0" 2137 | source = "registry+https://github.com/rust-lang/crates.io-index" 2138 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 2139 | 2140 | [[package]] 2141 | name = "sec1" 2142 | version = "0.7.3" 2143 | source = "registry+https://github.com/rust-lang/crates.io-index" 2144 | checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" 2145 | dependencies = [ 2146 | "base16ct", 2147 | "der", 2148 | "generic-array", 2149 | "pkcs8", 2150 | "subtle", 2151 | "zeroize", 2152 | ] 2153 | 2154 | [[package]] 2155 | name = "seccompiler" 2156 | version = "0.4.0" 2157 | source = "registry+https://github.com/rust-lang/crates.io-index" 2158 | checksum = "345a3e4dddf721a478089d4697b83c6c0a8f5bf16086f6c13397e4534eb6e2e5" 2159 | dependencies = [ 2160 | "libc", 2161 | ] 2162 | 2163 | [[package]] 2164 | name = "secret-service" 2165 | version = "3.1.0" 2166 | source = "registry+https://github.com/rust-lang/crates.io-index" 2167 | checksum = "b5204d39df37f06d1944935232fd2dfe05008def7ca599bf28c0800366c8a8f9" 2168 | dependencies = [ 2169 | "aes", 2170 | "cbc", 2171 | "futures-util", 2172 | "generic-array", 2173 | "hkdf", 2174 | "num", 2175 | "once_cell", 2176 | "rand 0.8.5", 2177 | "serde", 2178 | "sha2", 2179 | "zbus", 2180 | ] 2181 | 2182 | [[package]] 2183 | name = "security-framework" 2184 | version = "2.11.1" 2185 | source = "registry+https://github.com/rust-lang/crates.io-index" 2186 | checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" 2187 | dependencies = [ 2188 | "bitflags 2.8.0", 2189 | "core-foundation", 2190 | "core-foundation-sys", 2191 | "libc", 2192 | "security-framework-sys", 2193 | ] 2194 | 2195 | [[package]] 2196 | name = "security-framework-sys" 2197 | version = "2.14.0" 2198 | source = "registry+https://github.com/rust-lang/crates.io-index" 2199 | checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" 2200 | dependencies = [ 2201 | "core-foundation-sys", 2202 | "libc", 2203 | ] 2204 | 2205 | [[package]] 2206 | name = "semver" 2207 | version = "1.0.25" 2208 | source = "registry+https://github.com/rust-lang/crates.io-index" 2209 | checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03" 2210 | 2211 | [[package]] 2212 | name = "serde" 2213 | version = "1.0.218" 2214 | source = "registry+https://github.com/rust-lang/crates.io-index" 2215 | checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" 2216 | dependencies = [ 2217 | "serde_derive", 2218 | ] 2219 | 2220 | [[package]] 2221 | name = "serde_derive" 2222 | version = "1.0.218" 2223 | source = "registry+https://github.com/rust-lang/crates.io-index" 2224 | checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" 2225 | dependencies = [ 2226 | "proc-macro2", 2227 | "quote", 2228 | "syn 2.0.98", 2229 | ] 2230 | 2231 | [[package]] 2232 | name = "serde_repr" 2233 | version = "0.1.19" 2234 | source = "registry+https://github.com/rust-lang/crates.io-index" 2235 | checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" 2236 | dependencies = [ 2237 | "proc-macro2", 2238 | "quote", 2239 | "syn 2.0.98", 2240 | ] 2241 | 2242 | [[package]] 2243 | name = "serde_spanned" 2244 | version = "0.6.8" 2245 | source = "registry+https://github.com/rust-lang/crates.io-index" 2246 | checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" 2247 | dependencies = [ 2248 | "serde", 2249 | ] 2250 | 2251 | [[package]] 2252 | name = "sha1" 2253 | version = "0.10.6" 2254 | source = "registry+https://github.com/rust-lang/crates.io-index" 2255 | checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 2256 | dependencies = [ 2257 | "cfg-if 1.0.0", 2258 | "cpufeatures", 2259 | "digest", 2260 | ] 2261 | 2262 | [[package]] 2263 | name = "sha2" 2264 | version = "0.10.8" 2265 | source = "registry+https://github.com/rust-lang/crates.io-index" 2266 | checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 2267 | dependencies = [ 2268 | "cfg-if 1.0.0", 2269 | "cpufeatures", 2270 | "digest", 2271 | ] 2272 | 2273 | [[package]] 2274 | name = "shlex" 2275 | version = "1.3.0" 2276 | source = "registry+https://github.com/rust-lang/crates.io-index" 2277 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 2278 | 2279 | [[package]] 2280 | name = "signal-hook-registry" 2281 | version = "1.4.2" 2282 | source = "registry+https://github.com/rust-lang/crates.io-index" 2283 | checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" 2284 | dependencies = [ 2285 | "libc", 2286 | ] 2287 | 2288 | [[package]] 2289 | name = "signature" 2290 | version = "2.2.0" 2291 | source = "registry+https://github.com/rust-lang/crates.io-index" 2292 | checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" 2293 | dependencies = [ 2294 | "digest", 2295 | "rand_core 0.6.4", 2296 | ] 2297 | 2298 | [[package]] 2299 | name = "slab" 2300 | version = "0.4.9" 2301 | source = "registry+https://github.com/rust-lang/crates.io-index" 2302 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 2303 | dependencies = [ 2304 | "autocfg", 2305 | ] 2306 | 2307 | [[package]] 2308 | name = "smallvec" 2309 | version = "1.14.0" 2310 | source = "registry+https://github.com/rust-lang/crates.io-index" 2311 | checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" 2312 | 2313 | [[package]] 2314 | name = "socket2" 2315 | version = "0.4.10" 2316 | source = "registry+https://github.com/rust-lang/crates.io-index" 2317 | checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" 2318 | dependencies = [ 2319 | "libc", 2320 | "winapi 0.3.9", 2321 | ] 2322 | 2323 | [[package]] 2324 | name = "socket2" 2325 | version = "0.5.8" 2326 | source = "registry+https://github.com/rust-lang/crates.io-index" 2327 | checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" 2328 | dependencies = [ 2329 | "libc", 2330 | "windows-sys 0.52.0", 2331 | ] 2332 | 2333 | [[package]] 2334 | name = "spki" 2335 | version = "0.7.3" 2336 | source = "registry+https://github.com/rust-lang/crates.io-index" 2337 | checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" 2338 | dependencies = [ 2339 | "base64ct", 2340 | "der", 2341 | ] 2342 | 2343 | [[package]] 2344 | name = "ssh2-config" 2345 | version = "0.2.3" 2346 | source = "registry+https://github.com/rust-lang/crates.io-index" 2347 | checksum = "98150bad1e8fe53df07f38b53364f4d34e84a6cc2ee9f933e43629571060af65" 2348 | dependencies = [ 2349 | "bitflags 2.8.0", 2350 | "dirs 5.0.1", 2351 | "thiserror", 2352 | "wildmatch", 2353 | ] 2354 | 2355 | [[package]] 2356 | name = "sshield" 2357 | version = "0.1.0" 2358 | dependencies = [ 2359 | "anyhow", 2360 | "async-trait", 2361 | "chrono", 2362 | "clap", 2363 | "dialog", 2364 | "dirs 5.0.1", 2365 | "extrasafe", 2366 | "futures", 2367 | "keyring", 2368 | "rusqlite", 2369 | "russh", 2370 | "russh-keys", 2371 | "ssh2-config", 2372 | "tokio", 2373 | "tokio-stream", 2374 | "toml", 2375 | ] 2376 | 2377 | [[package]] 2378 | name = "static_assertions" 2379 | version = "1.1.0" 2380 | source = "registry+https://github.com/rust-lang/crates.io-index" 2381 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 2382 | 2383 | [[package]] 2384 | name = "strsim" 2385 | version = "0.11.1" 2386 | source = "registry+https://github.com/rust-lang/crates.io-index" 2387 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 2388 | 2389 | [[package]] 2390 | name = "subtle" 2391 | version = "2.6.1" 2392 | source = "registry+https://github.com/rust-lang/crates.io-index" 2393 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 2394 | 2395 | [[package]] 2396 | name = "syn" 2397 | version = "1.0.109" 2398 | source = "registry+https://github.com/rust-lang/crates.io-index" 2399 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 2400 | dependencies = [ 2401 | "proc-macro2", 2402 | "quote", 2403 | "unicode-ident", 2404 | ] 2405 | 2406 | [[package]] 2407 | name = "syn" 2408 | version = "2.0.98" 2409 | source = "registry+https://github.com/rust-lang/crates.io-index" 2410 | checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" 2411 | dependencies = [ 2412 | "proc-macro2", 2413 | "quote", 2414 | "unicode-ident", 2415 | ] 2416 | 2417 | [[package]] 2418 | name = "syscalls" 2419 | version = "0.6.18" 2420 | source = "registry+https://github.com/rust-lang/crates.io-index" 2421 | checksum = "43d0e35dc7d73976a53c7e6d7d177ef804a0c0ee774ec77bcc520c2216fd7cbe" 2422 | 2423 | [[package]] 2424 | name = "tempfile" 2425 | version = "3.17.1" 2426 | source = "registry+https://github.com/rust-lang/crates.io-index" 2427 | checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230" 2428 | dependencies = [ 2429 | "cfg-if 1.0.0", 2430 | "fastrand 2.3.0", 2431 | "getrandom 0.3.1", 2432 | "once_cell", 2433 | "rustix 0.38.44", 2434 | "windows-sys 0.59.0", 2435 | ] 2436 | 2437 | [[package]] 2438 | name = "thiserror" 2439 | version = "1.0.69" 2440 | source = "registry+https://github.com/rust-lang/crates.io-index" 2441 | checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" 2442 | dependencies = [ 2443 | "thiserror-impl", 2444 | ] 2445 | 2446 | [[package]] 2447 | name = "thiserror-impl" 2448 | version = "1.0.69" 2449 | source = "registry+https://github.com/rust-lang/crates.io-index" 2450 | checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" 2451 | dependencies = [ 2452 | "proc-macro2", 2453 | "quote", 2454 | "syn 2.0.98", 2455 | ] 2456 | 2457 | [[package]] 2458 | name = "tokio" 2459 | version = "1.43.0" 2460 | source = "registry+https://github.com/rust-lang/crates.io-index" 2461 | checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" 2462 | dependencies = [ 2463 | "backtrace", 2464 | "bytes", 2465 | "libc", 2466 | "mio", 2467 | "parking_lot", 2468 | "pin-project-lite", 2469 | "signal-hook-registry", 2470 | "socket2 0.5.8", 2471 | "tokio-macros", 2472 | "windows-sys 0.52.0", 2473 | ] 2474 | 2475 | [[package]] 2476 | name = "tokio-macros" 2477 | version = "2.5.0" 2478 | source = "registry+https://github.com/rust-lang/crates.io-index" 2479 | checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" 2480 | dependencies = [ 2481 | "proc-macro2", 2482 | "quote", 2483 | "syn 2.0.98", 2484 | ] 2485 | 2486 | [[package]] 2487 | name = "tokio-stream" 2488 | version = "0.1.17" 2489 | source = "registry+https://github.com/rust-lang/crates.io-index" 2490 | checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" 2491 | dependencies = [ 2492 | "futures-core", 2493 | "pin-project-lite", 2494 | "tokio", 2495 | ] 2496 | 2497 | [[package]] 2498 | name = "tokio-util" 2499 | version = "0.7.13" 2500 | source = "registry+https://github.com/rust-lang/crates.io-index" 2501 | checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" 2502 | dependencies = [ 2503 | "bytes", 2504 | "futures-core", 2505 | "futures-sink", 2506 | "pin-project-lite", 2507 | "tokio", 2508 | ] 2509 | 2510 | [[package]] 2511 | name = "toml" 2512 | version = "0.7.8" 2513 | source = "registry+https://github.com/rust-lang/crates.io-index" 2514 | checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" 2515 | dependencies = [ 2516 | "serde", 2517 | "serde_spanned", 2518 | "toml_datetime", 2519 | "toml_edit", 2520 | ] 2521 | 2522 | [[package]] 2523 | name = "toml_datetime" 2524 | version = "0.6.8" 2525 | source = "registry+https://github.com/rust-lang/crates.io-index" 2526 | checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" 2527 | dependencies = [ 2528 | "serde", 2529 | ] 2530 | 2531 | [[package]] 2532 | name = "toml_edit" 2533 | version = "0.19.15" 2534 | source = "registry+https://github.com/rust-lang/crates.io-index" 2535 | checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" 2536 | dependencies = [ 2537 | "indexmap", 2538 | "serde", 2539 | "serde_spanned", 2540 | "toml_datetime", 2541 | "winnow", 2542 | ] 2543 | 2544 | [[package]] 2545 | name = "tracing" 2546 | version = "0.1.41" 2547 | source = "registry+https://github.com/rust-lang/crates.io-index" 2548 | checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 2549 | dependencies = [ 2550 | "pin-project-lite", 2551 | "tracing-attributes", 2552 | "tracing-core", 2553 | ] 2554 | 2555 | [[package]] 2556 | name = "tracing-attributes" 2557 | version = "0.1.28" 2558 | source = "registry+https://github.com/rust-lang/crates.io-index" 2559 | checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" 2560 | dependencies = [ 2561 | "proc-macro2", 2562 | "quote", 2563 | "syn 2.0.98", 2564 | ] 2565 | 2566 | [[package]] 2567 | name = "tracing-core" 2568 | version = "0.1.33" 2569 | source = "registry+https://github.com/rust-lang/crates.io-index" 2570 | checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" 2571 | dependencies = [ 2572 | "once_cell", 2573 | ] 2574 | 2575 | [[package]] 2576 | name = "typenum" 2577 | version = "1.18.0" 2578 | source = "registry+https://github.com/rust-lang/crates.io-index" 2579 | checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" 2580 | 2581 | [[package]] 2582 | name = "uds_windows" 2583 | version = "1.1.0" 2584 | source = "registry+https://github.com/rust-lang/crates.io-index" 2585 | checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" 2586 | dependencies = [ 2587 | "memoffset 0.9.1", 2588 | "tempfile", 2589 | "winapi 0.3.9", 2590 | ] 2591 | 2592 | [[package]] 2593 | name = "unicode-ident" 2594 | version = "1.0.17" 2595 | source = "registry+https://github.com/rust-lang/crates.io-index" 2596 | checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" 2597 | 2598 | [[package]] 2599 | name = "universal-hash" 2600 | version = "0.5.1" 2601 | source = "registry+https://github.com/rust-lang/crates.io-index" 2602 | checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" 2603 | dependencies = [ 2604 | "crypto-common", 2605 | "subtle", 2606 | ] 2607 | 2608 | [[package]] 2609 | name = "utf8parse" 2610 | version = "0.2.2" 2611 | source = "registry+https://github.com/rust-lang/crates.io-index" 2612 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 2613 | 2614 | [[package]] 2615 | name = "vcpkg" 2616 | version = "0.2.15" 2617 | source = "registry+https://github.com/rust-lang/crates.io-index" 2618 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 2619 | 2620 | [[package]] 2621 | name = "version_check" 2622 | version = "0.9.5" 2623 | source = "registry+https://github.com/rust-lang/crates.io-index" 2624 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 2625 | 2626 | [[package]] 2627 | name = "waker-fn" 2628 | version = "1.2.0" 2629 | source = "registry+https://github.com/rust-lang/crates.io-index" 2630 | checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" 2631 | 2632 | [[package]] 2633 | name = "wasi" 2634 | version = "0.9.0+wasi-snapshot-preview1" 2635 | source = "registry+https://github.com/rust-lang/crates.io-index" 2636 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 2637 | 2638 | [[package]] 2639 | name = "wasi" 2640 | version = "0.11.0+wasi-snapshot-preview1" 2641 | source = "registry+https://github.com/rust-lang/crates.io-index" 2642 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2643 | 2644 | [[package]] 2645 | name = "wasi" 2646 | version = "0.13.3+wasi-0.2.2" 2647 | source = "registry+https://github.com/rust-lang/crates.io-index" 2648 | checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" 2649 | dependencies = [ 2650 | "wit-bindgen-rt", 2651 | ] 2652 | 2653 | [[package]] 2654 | name = "wasm-bindgen" 2655 | version = "0.2.100" 2656 | source = "registry+https://github.com/rust-lang/crates.io-index" 2657 | checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" 2658 | dependencies = [ 2659 | "cfg-if 1.0.0", 2660 | "once_cell", 2661 | "rustversion", 2662 | "wasm-bindgen-macro", 2663 | ] 2664 | 2665 | [[package]] 2666 | name = "wasm-bindgen-backend" 2667 | version = "0.2.100" 2668 | source = "registry+https://github.com/rust-lang/crates.io-index" 2669 | checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" 2670 | dependencies = [ 2671 | "bumpalo", 2672 | "log", 2673 | "proc-macro2", 2674 | "quote", 2675 | "syn 2.0.98", 2676 | "wasm-bindgen-shared", 2677 | ] 2678 | 2679 | [[package]] 2680 | name = "wasm-bindgen-macro" 2681 | version = "0.2.100" 2682 | source = "registry+https://github.com/rust-lang/crates.io-index" 2683 | checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" 2684 | dependencies = [ 2685 | "quote", 2686 | "wasm-bindgen-macro-support", 2687 | ] 2688 | 2689 | [[package]] 2690 | name = "wasm-bindgen-macro-support" 2691 | version = "0.2.100" 2692 | source = "registry+https://github.com/rust-lang/crates.io-index" 2693 | checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" 2694 | dependencies = [ 2695 | "proc-macro2", 2696 | "quote", 2697 | "syn 2.0.98", 2698 | "wasm-bindgen-backend", 2699 | "wasm-bindgen-shared", 2700 | ] 2701 | 2702 | [[package]] 2703 | name = "wasm-bindgen-shared" 2704 | version = "0.2.100" 2705 | source = "registry+https://github.com/rust-lang/crates.io-index" 2706 | checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" 2707 | dependencies = [ 2708 | "unicode-ident", 2709 | ] 2710 | 2711 | [[package]] 2712 | name = "wildmatch" 2713 | version = "2.4.0" 2714 | source = "registry+https://github.com/rust-lang/crates.io-index" 2715 | checksum = "68ce1ab1f8c62655ebe1350f589c61e505cf94d385bc6a12899442d9081e71fd" 2716 | 2717 | [[package]] 2718 | name = "winapi" 2719 | version = "0.2.8" 2720 | source = "registry+https://github.com/rust-lang/crates.io-index" 2721 | checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 2722 | 2723 | [[package]] 2724 | name = "winapi" 2725 | version = "0.3.9" 2726 | source = "registry+https://github.com/rust-lang/crates.io-index" 2727 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2728 | dependencies = [ 2729 | "winapi-i686-pc-windows-gnu", 2730 | "winapi-x86_64-pc-windows-gnu", 2731 | ] 2732 | 2733 | [[package]] 2734 | name = "winapi-build" 2735 | version = "0.1.1" 2736 | source = "registry+https://github.com/rust-lang/crates.io-index" 2737 | checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 2738 | 2739 | [[package]] 2740 | name = "winapi-i686-pc-windows-gnu" 2741 | version = "0.4.0" 2742 | source = "registry+https://github.com/rust-lang/crates.io-index" 2743 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2744 | 2745 | [[package]] 2746 | name = "winapi-x86_64-pc-windows-gnu" 2747 | version = "0.4.0" 2748 | source = "registry+https://github.com/rust-lang/crates.io-index" 2749 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2750 | 2751 | [[package]] 2752 | name = "windows-core" 2753 | version = "0.52.0" 2754 | source = "registry+https://github.com/rust-lang/crates.io-index" 2755 | checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" 2756 | dependencies = [ 2757 | "windows-targets 0.52.6", 2758 | ] 2759 | 2760 | [[package]] 2761 | name = "windows-sys" 2762 | version = "0.48.0" 2763 | source = "registry+https://github.com/rust-lang/crates.io-index" 2764 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 2765 | dependencies = [ 2766 | "windows-targets 0.48.5", 2767 | ] 2768 | 2769 | [[package]] 2770 | name = "windows-sys" 2771 | version = "0.52.0" 2772 | source = "registry+https://github.com/rust-lang/crates.io-index" 2773 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2774 | dependencies = [ 2775 | "windows-targets 0.52.6", 2776 | ] 2777 | 2778 | [[package]] 2779 | name = "windows-sys" 2780 | version = "0.59.0" 2781 | source = "registry+https://github.com/rust-lang/crates.io-index" 2782 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 2783 | dependencies = [ 2784 | "windows-targets 0.52.6", 2785 | ] 2786 | 2787 | [[package]] 2788 | name = "windows-targets" 2789 | version = "0.48.5" 2790 | source = "registry+https://github.com/rust-lang/crates.io-index" 2791 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 2792 | dependencies = [ 2793 | "windows_aarch64_gnullvm 0.48.5", 2794 | "windows_aarch64_msvc 0.48.5", 2795 | "windows_i686_gnu 0.48.5", 2796 | "windows_i686_msvc 0.48.5", 2797 | "windows_x86_64_gnu 0.48.5", 2798 | "windows_x86_64_gnullvm 0.48.5", 2799 | "windows_x86_64_msvc 0.48.5", 2800 | ] 2801 | 2802 | [[package]] 2803 | name = "windows-targets" 2804 | version = "0.52.6" 2805 | source = "registry+https://github.com/rust-lang/crates.io-index" 2806 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 2807 | dependencies = [ 2808 | "windows_aarch64_gnullvm 0.52.6", 2809 | "windows_aarch64_msvc 0.52.6", 2810 | "windows_i686_gnu 0.52.6", 2811 | "windows_i686_gnullvm", 2812 | "windows_i686_msvc 0.52.6", 2813 | "windows_x86_64_gnu 0.52.6", 2814 | "windows_x86_64_gnullvm 0.52.6", 2815 | "windows_x86_64_msvc 0.52.6", 2816 | ] 2817 | 2818 | [[package]] 2819 | name = "windows_aarch64_gnullvm" 2820 | version = "0.48.5" 2821 | source = "registry+https://github.com/rust-lang/crates.io-index" 2822 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 2823 | 2824 | [[package]] 2825 | name = "windows_aarch64_gnullvm" 2826 | version = "0.52.6" 2827 | source = "registry+https://github.com/rust-lang/crates.io-index" 2828 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 2829 | 2830 | [[package]] 2831 | name = "windows_aarch64_msvc" 2832 | version = "0.48.5" 2833 | source = "registry+https://github.com/rust-lang/crates.io-index" 2834 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 2835 | 2836 | [[package]] 2837 | name = "windows_aarch64_msvc" 2838 | version = "0.52.6" 2839 | source = "registry+https://github.com/rust-lang/crates.io-index" 2840 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 2841 | 2842 | [[package]] 2843 | name = "windows_i686_gnu" 2844 | version = "0.48.5" 2845 | source = "registry+https://github.com/rust-lang/crates.io-index" 2846 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 2847 | 2848 | [[package]] 2849 | name = "windows_i686_gnu" 2850 | version = "0.52.6" 2851 | source = "registry+https://github.com/rust-lang/crates.io-index" 2852 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 2853 | 2854 | [[package]] 2855 | name = "windows_i686_gnullvm" 2856 | version = "0.52.6" 2857 | source = "registry+https://github.com/rust-lang/crates.io-index" 2858 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 2859 | 2860 | [[package]] 2861 | name = "windows_i686_msvc" 2862 | version = "0.48.5" 2863 | source = "registry+https://github.com/rust-lang/crates.io-index" 2864 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 2865 | 2866 | [[package]] 2867 | name = "windows_i686_msvc" 2868 | version = "0.52.6" 2869 | source = "registry+https://github.com/rust-lang/crates.io-index" 2870 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 2871 | 2872 | [[package]] 2873 | name = "windows_x86_64_gnu" 2874 | version = "0.48.5" 2875 | source = "registry+https://github.com/rust-lang/crates.io-index" 2876 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 2877 | 2878 | [[package]] 2879 | name = "windows_x86_64_gnu" 2880 | version = "0.52.6" 2881 | source = "registry+https://github.com/rust-lang/crates.io-index" 2882 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 2883 | 2884 | [[package]] 2885 | name = "windows_x86_64_gnullvm" 2886 | version = "0.48.5" 2887 | source = "registry+https://github.com/rust-lang/crates.io-index" 2888 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 2889 | 2890 | [[package]] 2891 | name = "windows_x86_64_gnullvm" 2892 | version = "0.52.6" 2893 | source = "registry+https://github.com/rust-lang/crates.io-index" 2894 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 2895 | 2896 | [[package]] 2897 | name = "windows_x86_64_msvc" 2898 | version = "0.48.5" 2899 | source = "registry+https://github.com/rust-lang/crates.io-index" 2900 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 2901 | 2902 | [[package]] 2903 | name = "windows_x86_64_msvc" 2904 | version = "0.52.6" 2905 | source = "registry+https://github.com/rust-lang/crates.io-index" 2906 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 2907 | 2908 | [[package]] 2909 | name = "winnow" 2910 | version = "0.5.40" 2911 | source = "registry+https://github.com/rust-lang/crates.io-index" 2912 | checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" 2913 | dependencies = [ 2914 | "memchr", 2915 | ] 2916 | 2917 | [[package]] 2918 | name = "wit-bindgen-rt" 2919 | version = "0.33.0" 2920 | source = "registry+https://github.com/rust-lang/crates.io-index" 2921 | checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" 2922 | dependencies = [ 2923 | "bitflags 2.8.0", 2924 | ] 2925 | 2926 | [[package]] 2927 | name = "xdg-home" 2928 | version = "1.3.0" 2929 | source = "registry+https://github.com/rust-lang/crates.io-index" 2930 | checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" 2931 | dependencies = [ 2932 | "libc", 2933 | "windows-sys 0.59.0", 2934 | ] 2935 | 2936 | [[package]] 2937 | name = "yasna" 2938 | version = "0.5.2" 2939 | source = "registry+https://github.com/rust-lang/crates.io-index" 2940 | checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" 2941 | dependencies = [ 2942 | "bit-vec", 2943 | "num-bigint", 2944 | ] 2945 | 2946 | [[package]] 2947 | name = "zbus" 2948 | version = "3.15.2" 2949 | source = "registry+https://github.com/rust-lang/crates.io-index" 2950 | checksum = "675d170b632a6ad49804c8cf2105d7c31eddd3312555cffd4b740e08e97c25e6" 2951 | dependencies = [ 2952 | "async-broadcast", 2953 | "async-executor", 2954 | "async-fs", 2955 | "async-io 1.13.0", 2956 | "async-lock 2.8.0", 2957 | "async-process", 2958 | "async-recursion", 2959 | "async-task", 2960 | "async-trait", 2961 | "blocking", 2962 | "byteorder", 2963 | "derivative", 2964 | "enumflags2", 2965 | "event-listener 2.5.3", 2966 | "futures-core", 2967 | "futures-sink", 2968 | "futures-util", 2969 | "hex", 2970 | "nix", 2971 | "once_cell", 2972 | "ordered-stream", 2973 | "rand 0.8.5", 2974 | "serde", 2975 | "serde_repr", 2976 | "sha1", 2977 | "static_assertions", 2978 | "tracing", 2979 | "uds_windows", 2980 | "winapi 0.3.9", 2981 | "xdg-home", 2982 | "zbus_macros", 2983 | "zbus_names", 2984 | "zvariant", 2985 | ] 2986 | 2987 | [[package]] 2988 | name = "zbus_macros" 2989 | version = "3.15.2" 2990 | source = "registry+https://github.com/rust-lang/crates.io-index" 2991 | checksum = "7131497b0f887e8061b430c530240063d33bf9455fa34438f388a245da69e0a5" 2992 | dependencies = [ 2993 | "proc-macro-crate", 2994 | "proc-macro2", 2995 | "quote", 2996 | "regex", 2997 | "syn 1.0.109", 2998 | "zvariant_utils", 2999 | ] 3000 | 3001 | [[package]] 3002 | name = "zbus_names" 3003 | version = "2.6.1" 3004 | source = "registry+https://github.com/rust-lang/crates.io-index" 3005 | checksum = "437d738d3750bed6ca9b8d423ccc7a8eb284f6b1d6d4e225a0e4e6258d864c8d" 3006 | dependencies = [ 3007 | "serde", 3008 | "static_assertions", 3009 | "zvariant", 3010 | ] 3011 | 3012 | [[package]] 3013 | name = "zerocopy" 3014 | version = "0.7.35" 3015 | source = "registry+https://github.com/rust-lang/crates.io-index" 3016 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 3017 | dependencies = [ 3018 | "byteorder", 3019 | "zerocopy-derive", 3020 | ] 3021 | 3022 | [[package]] 3023 | name = "zerocopy-derive" 3024 | version = "0.7.35" 3025 | source = "registry+https://github.com/rust-lang/crates.io-index" 3026 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 3027 | dependencies = [ 3028 | "proc-macro2", 3029 | "quote", 3030 | "syn 2.0.98", 3031 | ] 3032 | 3033 | [[package]] 3034 | name = "zeroize" 3035 | version = "1.8.1" 3036 | source = "registry+https://github.com/rust-lang/crates.io-index" 3037 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 3038 | 3039 | [[package]] 3040 | name = "zvariant" 3041 | version = "3.15.2" 3042 | source = "registry+https://github.com/rust-lang/crates.io-index" 3043 | checksum = "4eef2be88ba09b358d3b58aca6e41cd853631d44787f319a1383ca83424fb2db" 3044 | dependencies = [ 3045 | "byteorder", 3046 | "enumflags2", 3047 | "libc", 3048 | "serde", 3049 | "static_assertions", 3050 | "zvariant_derive", 3051 | ] 3052 | 3053 | [[package]] 3054 | name = "zvariant_derive" 3055 | version = "3.15.2" 3056 | source = "registry+https://github.com/rust-lang/crates.io-index" 3057 | checksum = "37c24dc0bed72f5f90d1f8bb5b07228cbf63b3c6e9f82d82559d4bae666e7ed9" 3058 | dependencies = [ 3059 | "proc-macro-crate", 3060 | "proc-macro2", 3061 | "quote", 3062 | "syn 1.0.109", 3063 | "zvariant_utils", 3064 | ] 3065 | 3066 | [[package]] 3067 | name = "zvariant_utils" 3068 | version = "1.0.1" 3069 | source = "registry+https://github.com/rust-lang/crates.io-index" 3070 | checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200" 3071 | dependencies = [ 3072 | "proc-macro2", 3073 | "quote", 3074 | "syn 1.0.109", 3075 | ] 3076 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sshield" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | anyhow = "1.0.72" 10 | async-trait = "0.1.72" 11 | chrono = "0.4.31" 12 | clap = { version = "4.3.17", features = [ "derive" ] } 13 | dialog = "0.3.0" 14 | dirs = "5.0.1" 15 | extrasafe = "0.3.0" 16 | futures = "0.3.28" 17 | keyring = { version = "2.3.2", features = ["linux-secret-service"] } 18 | rusqlite = { version = "0.29.0", features = ["sqlcipher"] } 19 | russh = { version = "0.40.2", features = ["openssl"] } 20 | russh-keys = { version = "0.40.1", features = ["openssl"] } 21 | # russh = { git = "https://github.com/warp-tech/russh" , features = ["openssl"] } 22 | # russh-keys = { git = "https://github.com/warp-tech/russh" , features = ["openssl"] } 23 | ssh2-config = "0.2.0" 24 | tokio = { version = "1.29.1", features = ["full"] } 25 | tokio-stream = "0.1.14" 26 | toml = "0.7.6" 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | chip8-emulator 294 | Copyright (C) 2022 Saksham Mittal 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sshield 2 | 3 | An experimental, opinionated drop-in `ssh-agent` replacement written in Rust using [`russh`](https://github.com/warp-tech/russh) 4 | with the aim of being safer and more secure due to sandboxing sensitive data. 5 | 6 | Right now, we are able to use it as an SSH agent, albeit with some degree of manual setup, 7 | which will be automated 8 | 9 | It can: 10 | 11 | - Import private OpenSSH keys from keyfiles into the database or generate new ones 12 | 13 | - Act as SSH agent 14 | 15 | - Create an authentication check whenever `ssh` client request key for a certain operation 16 | 17 | - Secure all key data through encryption of the database (using [SQLCipher](https://github.com/sqlcipher/sqlcipher)) 18 | 19 | - Use the OS keyring to store your database password (disabled by default) so it unlocks on login 20 | 21 | To-dos: 22 | 23 | - Allow easy exporting of key data to the OpenSSH format 24 | 25 | - Lock the key data when user logs out 26 | 27 | - Use [Landlock](https://docs.kernel.org/security/landlock.html) or [seccomp](https://en.wikipedia.org/wiki/Seccomp) based sandboxing to drop all privileges down to 28 | the bare minimum in order to protect the running process from various exploits 29 | 30 | Nice-to-haves: 31 | 32 | - Store key data on remote locations with different authentication schemes 33 | 34 | - Store key data in different formats 35 | 36 | - Configure database and socket location 37 | 38 | ## Usage 39 | 40 | The best way is to use Nix and [home-manager](https://github.com/nix-community/home-manager). This way, a hardened user systemd service will be set up that runs on login. 41 | You can configure sshield using Nix for greater flexibility. 42 | 43 | The provided Home Manager module will also add the program to your user's PATH, so it can be invoked from the command line. 44 | 45 | For a flake-based NixOS config, add this repo to your inputs: 46 | 47 | ``` 48 | inputs.sshield.url = "github:gotlougit/sshield"; 49 | inputs.sshield.inputs.nixpkgs.follows = "nixpkgs"; 50 | ``` 51 | 52 | and write the following in your Home Manager config: 53 | 54 | ``` 55 | { inputs, ... }: 56 | { 57 | imports = [ inputs.sshield.hmModule ]; 58 | programs.sshield = { 59 | enable = true; 60 | settings = { 61 | # Write your config here 62 | database = "/home/user/.sshield.db"; 63 | prompt = 60; 64 | keyring = true; 65 | }; 66 | }; 67 | } 68 | ``` 69 | 70 | This does all the hard work for you! You now have a hardened SSH agent using encrypted SSH keys 71 | that unlocks the database on login using the keyring that comes with your desktop environment 72 | (if any). 73 | -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | { lib, makeBinaryWrapper, rustPlatform, fetchFromGitHub, pkgs, cargo, pkg-config 2 | , openssl, libseccomp, sqlcipher, ... }: 3 | 4 | rustPlatform.buildRustPackage rec { 5 | pname = "sshield"; 6 | version = "0.1.0"; 7 | 8 | src = ./.; 9 | 10 | cargoLock = { lockFile = ./Cargo.lock; }; 11 | cargoSha256 = ""; 12 | 13 | nativeBuildInputs = 14 | [ makeBinaryWrapper cargo rustPlatform.cargoSetupHook pkg-config ]; 15 | buildInputs = [ openssl libseccomp sqlcipher ]; 16 | wrapperPath = lib.makeBinPath ([ pkgs.libsForQt5.kdialog pkgs.zenity ]); 17 | 18 | checkPhase = false; 19 | postFixup = '' 20 | wrapProgram $out/bin/sshield --prefix PATH : "${wrapperPath}" 21 | ''; 22 | 23 | meta = with lib; { 24 | description = "A secure, drop-in, opinionated SSH agent replacement"; 25 | homepage = "https://git.sr.ht/~gotlou/sshield"; 26 | license = licenses.gpl2Plus; 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "nixpkgs": { 4 | "locked": { 5 | "lastModified": 1731139594, 6 | "narHash": "sha256-IigrKK3vYRpUu+HEjPL/phrfh7Ox881er1UEsZvw9Q4=", 7 | "path": "/nix/store/0sxsfzswhjck7f4sbsvznz285s4i7y64-source", 8 | "rev": "76612b17c0ce71689921ca12d9ffdc9c23ce40b2", 9 | "type": "path" 10 | }, 11 | "original": { 12 | "id": "nixpkgs", 13 | "type": "indirect" 14 | } 15 | }, 16 | "root": { 17 | "inputs": { 18 | "nixpkgs": "nixpkgs" 19 | } 20 | } 21 | }, 22 | "root": "root", 23 | "version": 7 24 | } 25 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | outputs = { self, nixpkgs }: 3 | let 4 | system = "x86_64-linux"; 5 | pkgs = import nixpkgs { inherit system; }; 6 | mkShell = pkgs.mkShell.override { stdenv = pkgs.stdenvAdapters.useMoldLinker pkgs.stdenv; }; 7 | in 8 | { 9 | devShells.${system}.default = mkShell { 10 | name = "rustdev"; 11 | shellHook = '' 12 | export CARGO_HOME="$(realpath ./.localcargo)" 13 | export _ZO_DATA_DIR="$(realpath ./.localzoxide)" 14 | ''; 15 | buildInputs = [ 16 | pkgs.pkg-config 17 | pkgs.cargo 18 | pkgs.clippy 19 | pkgs.rustc 20 | pkgs.rustfmt 21 | pkgs.rust-analyzer 22 | pkgs.libseccomp 23 | pkgs.sqlcipher 24 | pkgs.zenity 25 | pkgs.libsForQt5.kdialog 26 | pkgs.gdb 27 | ]; 28 | }; 29 | packages.${system} = { 30 | default = pkgs.callPackage ./default.nix { }; 31 | }; 32 | hmModule = import ./home-manager.nix; 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /home-manager.nix: -------------------------------------------------------------------------------- 1 | { config, lib, makeBinaryWrapper, rustPlatform, fetchFromGitHub, pkgs, cargo, pkg-config, openssl, libseccomp, sqlcipher, ... }: 2 | 3 | with lib; 4 | 5 | let 6 | cfg = config.programs.sshield; 7 | tomlFormat = pkgs.formats.toml { }; 8 | in { 9 | 10 | options.programs.sshield = { 11 | enable = mkEnableOption "sshield, secure SSH agent"; 12 | 13 | extraPackages = mkOption { 14 | type = with types; listOf package; 15 | default = [ ]; 16 | example = literalExpression "[ ]"; 17 | description = "Extra packages available to sshield."; 18 | }; 19 | 20 | settings = mkOption { 21 | type = tomlFormat.type; 22 | default = { }; 23 | example = literalExpression '' 24 | { 25 | database = "/home/user/.ssh.db3"; 26 | prompt = 60; 27 | keyring = true; 28 | } 29 | ''; 30 | description = '' 31 | Configuration written to 32 | {file}`$XDG_CONFIG_HOME/sshield/sshield.toml`. 33 | ''; 34 | }; 35 | 36 | }; 37 | 38 | config = mkIf cfg.enable { 39 | home.packages = [ (pkgs.callPackage ./default.nix { }) ]; 40 | home.sessionVariablesExtra = '' 41 | if [[ -z "$SSH_AUTH_SOCK" ]]; then 42 | export SSH_AUTH_SOCK=$XDG_RUNTIME_DIR/ssh-agent 43 | fi 44 | ''; 45 | 46 | systemd.user.services.sshield = { 47 | Unit = { 48 | Description = "Secure SSH agent written in Rust"; 49 | After = [ "graphical-session.target" ]; 50 | }; 51 | Install = { 52 | WantedBy = [ "default.target" ]; 53 | }; 54 | Service = { 55 | ExecStart = "${pkgs.writeShellScript "sshield-serve" '' 56 | #!/usr/bin/env bash 57 | sshield serve 58 | ''}"; 59 | ExecStop = "${pkgs.writeShellScript "sshield-stop" '' 60 | #!/usr/bin/env bash 61 | rm "$XDG_RUNTIME_DIR"/ssh-agent 62 | ''}"; 63 | Restart = "on-failure"; 64 | LockPersonality = true; 65 | PrivateNetwork = true; 66 | MemoryDenyWriteExecute = true; 67 | NoNewPrivileges = true; 68 | ProtectSystem = "strict"; 69 | PrivateMounts = true; 70 | PrivateTmp = true; 71 | ProtectProc = "invisible"; 72 | ProtectClock = true; 73 | ProtectControlGroups = true; 74 | ProtectHostname = true; 75 | ProtectKernelLogs = true; 76 | ProtectKernelModules = true; 77 | ProtectKernelTunables = true; 78 | RestrictNamespaces = true; 79 | RestrictRealtime = true; 80 | RestrictSUIDSGID = true; 81 | RestrictAddressFamilies = [ "AF_UNIX" ]; 82 | SystemCallArchitectures = "native"; 83 | PrivateDevices = true; 84 | SystemCallFilter = [ "@known" "~@clock" "~@cpu-emulation" "~@raw-io" "~@reboot" "~@mount" "~@obsolete" "~@swap" "~@debug" "~@keyring" "~@pkey" "~@chown" ]; 85 | }; 86 | }; 87 | 88 | xdg.configFile = let 89 | settings = { 90 | "sshield/sshield.toml" = mkIf (cfg.settings != { }) { 91 | source = tomlFormat.generate "sshield-config" cfg.settings; 92 | }; 93 | }; 94 | in settings; 95 | }; 96 | } 97 | -------------------------------------------------------------------------------- /src/cli.rs: -------------------------------------------------------------------------------- 1 | use clap::{Parser, Subcommand}; 2 | 3 | #[derive(Subcommand, PartialEq)] 4 | pub enum Command { 5 | /// Generate a key for a particular service 6 | GenKey { 7 | /// key nickname 8 | #[arg(required = true)] 9 | name: String, 10 | /// Username 11 | #[arg(required = true)] 12 | user: String, 13 | /// Hostname 14 | #[arg(required = true)] 15 | host: String, 16 | /// Port (optional) 17 | #[arg(short, long, default_value_t = 22)] 18 | port: u16, 19 | }, 20 | /// Show a key for a particular service, 21 | /// if no name is given, return all keys 22 | ShowKey { 23 | /// key nickname 24 | #[arg(required = false)] 25 | name: Option, 26 | }, 27 | /// Delete a key for a particular service 28 | DeleteKey { 29 | /// key nickname 30 | #[arg(required = true)] 31 | name: String, 32 | }, 33 | /// Create a new key for a pre-existing service 34 | UpdateKey { 35 | /// key nickname 36 | #[arg(required = true)] 37 | name: String, 38 | /// Username 39 | #[arg(long, required = false)] 40 | user: Option, 41 | /// Hostname 42 | #[arg(long, required = false)] 43 | host: Option, 44 | /// Port (optional) 45 | #[arg(long, required = false)] 46 | port: Option, 47 | /// Generate new key (if needed) 48 | #[arg(long, required = false)] 49 | genkey: Option, 50 | }, 51 | /// Start listener process and handle remote requests for keys 52 | Serve {}, 53 | /// Import an OpenSSH key 54 | ImportKey { 55 | /// Key name as defined in SSH config; this will be key name here as well 56 | #[arg(required = true)] 57 | name: String, 58 | /// Path to the SSH private key 59 | #[arg(required = true)] 60 | path: String, 61 | /// Passcode to unlock the key if need be 62 | #[arg(required = false)] 63 | pass: Option, 64 | }, 65 | /// Change the database password 66 | ChangePassword {}, 67 | } 68 | 69 | /// Rust reimplementation of SSH client with sandboxing 70 | #[derive(Parser)] 71 | #[command(author, version, about, long_about = None)] 72 | pub(crate) struct Args { 73 | #[command(subcommand)] 74 | pub(crate) command: Option, 75 | } 76 | -------------------------------------------------------------------------------- /src/config.rs: -------------------------------------------------------------------------------- 1 | use keyring::Entry; 2 | use std::env; 3 | use std::fs; 4 | use std::io::Write; 5 | use std::path::Path; 6 | use toml::Table; 7 | 8 | #[derive(PartialEq, Clone)] 9 | pub enum Prompt { 10 | NoPrompt, 11 | EveryNSeconds(i64), 12 | } 13 | 14 | pub struct Config { 15 | pub db_path: String, 16 | pub prompt: Prompt, 17 | pub trust_keyring: bool, 18 | } 19 | 20 | pub fn get_pass(trust_keyring: bool) -> anyhow::Result { 21 | if !trust_keyring { 22 | delete_pass_from_keyring()?; 23 | } 24 | let user = std::env::var_os("USER").unwrap_or_default(); 25 | let entry = Entry::new("sshield", user.to_str().unwrap_or_default())?; 26 | Ok(match entry.get_password() { 27 | Ok(pass) => pass, 28 | Err(_) => { 29 | let pass = crate::gui::get_db_pass(); 30 | if trust_keyring { 31 | entry.set_password(&pass)?; 32 | } 33 | pass 34 | } 35 | }) 36 | } 37 | 38 | pub fn delete_pass_from_keyring() -> anyhow::Result<()> { 39 | let user = std::env::var_os("USER").unwrap_or_default(); 40 | let entry = Entry::new("sshield", user.to_str().unwrap_or_default())?; 41 | entry.delete_password()?; 42 | Ok(()) 43 | } 44 | 45 | fn get_config_path() -> String { 46 | match env::var_os("XDG_CONFIG_HOME") { 47 | Some(path) => { 48 | let parentconfdir = path.to_str().unwrap_or_default().to_string(); 49 | parentconfdir + "/sshield" 50 | } 51 | None => { 52 | let home_dir = env::var_os("HOME").unwrap(); 53 | let parentconfdir = home_dir.into_string().unwrap(); 54 | parentconfdir + ".config/sshield" 55 | } 56 | } 57 | } 58 | 59 | fn create_config_folder(config_path: &str) -> anyhow::Result<()> { 60 | if !Path::new(&config_path).exists() { 61 | eprintln!("Creating the config folder and default config"); 62 | fs::create_dir(config_path)?; 63 | let mut config = Table::new(); 64 | config.insert( 65 | "database".to_string(), 66 | (config_path.to_string() + "/keys.db3").into(), 67 | ); 68 | config.insert("keyring".to_string(), false.into()); 69 | config.insert("prompt".to_string(), 60.into()); 70 | let rawconf = config.to_string(); 71 | let conffilename = config_path.to_string() + "/sshield.toml"; 72 | let mut file = fs::File::create(conffilename)?; 73 | file.write_all(rawconf.as_bytes())?; 74 | } 75 | Ok(()) 76 | } 77 | 78 | pub fn get_all_vars() -> anyhow::Result { 79 | let config_path = get_config_path(); 80 | create_config_folder(&config_path)?; 81 | let file_path = config_path + "/sshield.toml"; 82 | let rawconf = fs::read_to_string(file_path)?; 83 | let conf: Table = rawconf.parse()?; 84 | let db_path = conf 85 | .get("database") 86 | .unwrap() 87 | .as_str() 88 | .unwrap() 89 | // TODO: Figure out a way to remove these quotation marks elegantly 90 | .replace('\"', ""); 91 | let prompt_timeout = conf.get("prompt").unwrap().as_integer().unwrap_or(0); 92 | let auth_settings = { 93 | if prompt_timeout <= 0 { 94 | Prompt::NoPrompt 95 | } else { 96 | Prompt::EveryNSeconds(prompt_timeout) 97 | } 98 | }; 99 | // Don't trust keyring by default 100 | let trust_keyring = conf.get("keyring").unwrap().as_bool().unwrap_or(false); 101 | Ok(Config { 102 | db_path, 103 | prompt: auth_settings, 104 | trust_keyring, 105 | }) 106 | } 107 | -------------------------------------------------------------------------------- /src/db.rs: -------------------------------------------------------------------------------- 1 | // The database module is meant to be dumb and not understand much of the 2 | // key data at all. 3 | // 4 | // It will handle only encrypted blobs and not actually sensitive info 5 | // This compartmentalization will help reduce the chances of exposing anything 6 | // accidentally 7 | use rusqlite::{params, Connection, Result}; 8 | use russh_keys::{key::KeyPair, pkcs8, PublicKeyBase64}; 9 | use std::fmt::Display; 10 | 11 | /// Row representation 12 | struct RawKey { 13 | nickname: String, 14 | user: String, 15 | host: String, 16 | port: u16, 17 | encoded_key: Vec, 18 | } 19 | 20 | pub struct ProcessedKey { 21 | pub nickname: String, 22 | pub user: String, 23 | pub host: String, 24 | pub port: u16, 25 | pub keypair: KeyPair, 26 | pub pubkey: String, 27 | pub cipher: String, 28 | } 29 | 30 | // TODO: maybe not do this processing here? 31 | // We may encrypt this data in the future 32 | impl RawKey { 33 | pub fn process(&self) -> ProcessedKey { 34 | let keypair = pkcs8::decode_pkcs8(&self.encoded_key, None).unwrap(); 35 | let pubkey = keypair.clone_public_key().unwrap().public_key_base64(); 36 | let cipher = keypair.name().to_string(); 37 | ProcessedKey { 38 | nickname: self.nickname.clone(), 39 | user: self.user.clone(), 40 | host: self.host.clone(), 41 | port: self.port, 42 | keypair, 43 | pubkey, 44 | cipher, 45 | } 46 | } 47 | } 48 | 49 | impl Display for ProcessedKey { 50 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 51 | writeln!( 52 | f, 53 | "SSH key '{}' for {}@{}:{} using cipher '{}'", 54 | self.nickname, self.user, self.host, self.port, self.cipher 55 | )?; 56 | writeln!(f, "{} {} {}", self.cipher, self.pubkey, self.nickname)?; 57 | Ok(()) 58 | } 59 | } 60 | 61 | /// Opens the database and changes password from 'oldpass' to 'newpass' 62 | pub(crate) fn change_db_pass(db_path: &str, oldpass: &str, newpass: &str) -> Result { 63 | match Connection::open(db_path) { 64 | Ok(conn) => { 65 | conn.pragma_update(None, "key", oldpass)?; 66 | conn.pragma_update(None, "rekey", newpass)?; 67 | Ok(conn) 68 | } 69 | Err(e) => Err(e), 70 | } 71 | } 72 | 73 | /// Opens the database and creates the table if necessary. 74 | /// Also encrypts the database as well. 75 | pub(crate) fn open_db(pass: &str, db_path: &str) -> Result { 76 | match Connection::open(db_path) { 77 | Ok(conn) => { 78 | conn.pragma_update(None, "key", pass).unwrap(); 79 | conn.execute( 80 | "CREATE TABLE IF NOT EXISTS keys ( 81 | nickname VARCHAR PRIMARY KEY, 82 | user VARCHAR, 83 | host VARCHAR, 84 | port INT, 85 | encoded_key BLOB 86 | )", 87 | [], 88 | )?; 89 | Ok(conn) 90 | } 91 | Err(e) => Err(e), 92 | } 93 | } 94 | 95 | pub(crate) fn insert_key( 96 | db: &Connection, 97 | nick: &str, 98 | user: &str, 99 | host: &str, 100 | port: u16, 101 | encoded_key: Vec, 102 | ) -> bool { 103 | let mut prepstatement = db 104 | .prepare( 105 | "INSERT INTO keys ( 106 | nickname, user, host, port, encoded_key 107 | ) VALUES (?1, ?2, ?3, ?4, (?5))", 108 | ) 109 | .unwrap(); 110 | prepstatement 111 | .execute(params![nick, user, host, &port.to_string(), encoded_key]) 112 | .is_ok() 113 | } 114 | 115 | /// Get the required key from the database 116 | pub(crate) fn get_key(db: &Connection, nick: &str) -> Result { 117 | let mut prepstatement = db.prepare( 118 | "SELECT 119 | nickname, user, host, port, encoded_key 120 | FROM keys WHERE nickname = ?1", 121 | )?; 122 | prepstatement.query_row([nick], |row| { 123 | let row = RawKey { 124 | nickname: row.get(0)?, 125 | user: row.get(1)?, 126 | host: row.get(2)?, 127 | port: row.get(3)?, 128 | encoded_key: row.get(4)?, 129 | }; 130 | Ok(row.process()) 131 | }) 132 | } 133 | 134 | pub(crate) fn update_key( 135 | db: &Connection, 136 | nick: &str, 137 | user: &Option, 138 | host: &Option, 139 | port: &Option, 140 | maybegenkey: &Option, 141 | ) -> Result { 142 | // TODO: allow regeneration of key 143 | let mut statement = db 144 | .prepare( 145 | "UPDATE keys SET 146 | user = COALESCE(?1, user), 147 | host = COALESCE(?2, host), 148 | port = COALESCE(?3, port) 149 | WHERE nickname = ?4 150 | ", 151 | ) 152 | .unwrap(); 153 | statement.execute(params![user, host, port, nick]) 154 | } 155 | 156 | /// Delete the required key from the database 157 | pub(crate) fn del_key(db: &Connection, nick: &str) -> Result { 158 | let mut prepstatement = db.prepare( 159 | "DELETE FROM keys 160 | WHERE nickname = ?1", 161 | )?; 162 | prepstatement.execute([nick]) 163 | } 164 | 165 | /// Get all the keys from the database 166 | pub(crate) fn get_all_keys(db: &Connection) -> Result, rusqlite::Error> { 167 | let mut prepstatement = db.prepare( 168 | "SELECT 169 | nickname, user, host, port, encoded_key 170 | FROM keys", 171 | )?; 172 | let rows: Result, rusqlite::Error> = prepstatement 173 | .query_map([], |row| { 174 | let row = RawKey { 175 | nickname: row.get(0)?, 176 | user: row.get(1)?, 177 | host: row.get(2)?, 178 | port: row.get(3)?, 179 | encoded_key: row.get(4)?, 180 | }; 181 | Ok(row.process()) 182 | })? 183 | .collect(); 184 | rows 185 | } 186 | -------------------------------------------------------------------------------- /src/gui.rs: -------------------------------------------------------------------------------- 1 | use dialog::{Choice, DialogBox}; 2 | 3 | pub fn confirm_request(msg: &str) -> bool { 4 | let choice = dialog::Question::new(msg) 5 | .title("sshield - Confirm request") 6 | .show() 7 | .unwrap_or(Choice::No); 8 | matches!(choice, Choice::Yes) 9 | } 10 | 11 | pub fn get_db_pass() -> String { 12 | dialog::Password::new("Enter database password: ") 13 | .title("sshield - Unlock database") 14 | .show() 15 | .unwrap() 16 | .unwrap_or(String::new()) 17 | } 18 | 19 | pub fn get_new_db_pass() -> String { 20 | dialog::Password::new("Enter new database password: ") 21 | .title("sshield - Change password") 22 | .show() 23 | .unwrap() 24 | .unwrap_or(String::new()) 25 | } 26 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use crate::config::Config; 2 | use crate::socket::Client; 3 | use clap::Parser; 4 | use cli::{Args, Command}; 5 | use std::process::exit; 6 | 7 | mod cli; 8 | mod config; 9 | mod db; 10 | mod gui; 11 | mod socket; 12 | 13 | /// Allow only local file access, and no socket access 14 | fn restrict_net() { 15 | extrasafe::SafetyContext::new() 16 | .enable(extrasafe::builtins::Networking::nothing()) 17 | .unwrap() 18 | .enable( 19 | extrasafe::builtins::SystemIO::nothing() 20 | .allow_close() 21 | .allow_open() 22 | .yes_really() 23 | .allow_read() 24 | .allow_write() 25 | .allow_unlink() 26 | .allow_ioctl() 27 | .allow_metadata(), 28 | ) 29 | .unwrap() 30 | .apply_to_all_threads() 31 | .unwrap(); 32 | } 33 | 34 | /// Allow only socket access and restricted file access 35 | fn restrict_file() { 36 | extrasafe::SafetyContext::new() 37 | .enable( 38 | extrasafe::builtins::Networking::nothing() 39 | // This allows `connect()` syscalls 40 | // TODO: Wait for https://github.com/boustrophedon/extrasafe/pull/25 41 | // to be merged in order to use `allow_connect()` 42 | .allow_start_tcp_clients() 43 | .allow_running_unix_clients() 44 | .allow_running_unix_servers() 45 | .allow_start_unix_servers() 46 | .yes_really(), 47 | ) 48 | .unwrap() 49 | // TODO: actually restrict file access 50 | .enable(extrasafe::builtins::SystemIO::everything()) 51 | .unwrap() 52 | // Allows tokio's Ctrl+C handler to work 53 | .enable(extrasafe::builtins::danger_zone::Threads::nothing().allow_create()) 54 | .unwrap() 55 | .apply_to_all_threads() 56 | .unwrap(); 57 | } 58 | 59 | #[tokio::main] 60 | async fn main() { 61 | let Config { 62 | db_path, 63 | prompt, 64 | trust_keyring, 65 | } = crate::config::get_all_vars().unwrap(); 66 | let args = Args::parse(); 67 | if let Some(cmd) = args.command { 68 | let pass = crate::config::get_pass(trust_keyring).unwrap(); 69 | if !pass.is_empty() { 70 | match Client::init(pass.as_str(), &db_path) { 71 | Ok(mgr) => { 72 | match cmd { 73 | Command::ChangePassword {} => { 74 | std::mem::drop(mgr); 75 | let newpass = crate::gui::get_new_db_pass(); 76 | match crate::db::change_db_pass(&db_path, &pass, &newpass) { 77 | Ok(_) => println!("Password of database changed successfully!"), 78 | Err(_) => eprintln!("Password was unable to be changed!"), 79 | }; 80 | } 81 | Command::GenKey { 82 | name, 83 | user, 84 | host, 85 | port, 86 | } => { 87 | match mgr.gen_key(&name, &user, &host, port).await { 88 | true => println!("{}", mgr.show_key(&name).unwrap()), 89 | false => println!("Error, key wasn't able to be created"), 90 | }; 91 | } 92 | Command::ShowKey { name } => match name { 93 | Some(name) => { 94 | mgr.show_key(&name).unwrap(); 95 | } 96 | None => { 97 | let keys = mgr.show_all_keys(); 98 | for key in keys.iter() { 99 | println!("{key}"); 100 | } 101 | } 102 | }, 103 | Command::DeleteKey { name } => match mgr.delete_key(name.as_str()) { 104 | true => println!("Key deleted"), 105 | false => println!("Key could not be deleted, maybe it does not exist?"), 106 | }, 107 | Command::Serve {} => { 108 | tokio::spawn(async move { 109 | tokio::signal::ctrl_c().await.unwrap(); 110 | println!("Closing socket..."); 111 | socket::close_socket().await; 112 | exit(0); 113 | }); 114 | println!("Starting server process..."); 115 | let task1 = socket::start_server(prompt); 116 | let task2 = { 117 | // In order to prevent any funny business with the scheduler, 118 | // let's wait for a while and let the other task take over 119 | tokio::time::sleep(std::time::Duration::from_secs(1)).await; 120 | mgr.add_all_keys() 121 | }; 122 | tokio::join!(task1, task2); 123 | } 124 | Command::UpdateKey { 125 | name, 126 | user, 127 | host, 128 | port, 129 | genkey, 130 | } => { 131 | match mgr.update_key(&name, &user, &host, &port, &genkey) { 132 | true => println!("Updated key successfully"), 133 | false => eprintln!("Couldn't update key, does it exist?"), 134 | }; 135 | } 136 | Command::ImportKey { name, path, pass } => { 137 | match mgr.import_key_from_file(pass, &name, &path).await { 138 | true => println!("Key imported successfully"), 139 | false => eprintln!("Couldn't import key, check path or config?"), 140 | } 141 | } 142 | }; 143 | } 144 | Err(_) => { 145 | crate::config::delete_pass_from_keyring().unwrap(); 146 | eprintln!("Check database password or location, unable to open database"); 147 | } 148 | }; 149 | } else { 150 | eprintln!("Password is empty!"); 151 | } 152 | }; 153 | } 154 | -------------------------------------------------------------------------------- /src/socket.rs: -------------------------------------------------------------------------------- 1 | use crate::config::Prompt; 2 | use crate::db::{self, ProcessedKey}; 3 | use crate::gui; 4 | use anyhow::Result; 5 | use async_trait::async_trait; 6 | use chrono::prelude::*; 7 | use chrono::Duration; 8 | use rusqlite::Connection; 9 | use russh_keys::load_secret_key; 10 | use russh_keys::{agent::client, agent::server, agent::server::MessageType, key::KeyPair, pkcs8}; 11 | use ssh2_config::{ParseRule, SshConfig}; 12 | use std::sync::Arc; 13 | use tokio::fs::{self, File}; 14 | use tokio::io::AsyncReadExt; 15 | use tokio::macros::support::Future; 16 | use tokio::net::{UnixListener, UnixStream}; 17 | use tokio::sync::Mutex; 18 | 19 | const SOCKNAME: &str = "/run/user/1000/ssh-agent"; 20 | 21 | #[derive(Clone)] 22 | struct SecureAgent { 23 | auth_timeout: Prompt, 24 | last_auth_time: Arc>>, 25 | } 26 | 27 | #[async_trait] 28 | impl server::Agent for SecureAgent { 29 | fn confirm(self, _pk: Arc) -> Box + Unpin + Send> { 30 | Box::new(futures::future::ready((self, true))) 31 | } 32 | async fn confirm_request(&self, msg: MessageType) -> bool { 33 | match self.auth_timeout { 34 | Prompt::NoPrompt => true, 35 | Prompt::EveryNSeconds(diff) => { 36 | // Only prompt on requesting signing since that is most important 37 | let msgstr = match msg { 38 | MessageType::Sign => "Allow request to sign data?", 39 | _ => "", 40 | }; 41 | if msgstr.is_empty() { 42 | return true; 43 | } 44 | let current_time = Utc::now(); 45 | let mut last_time = self.last_auth_time.lock().await; 46 | let timediff = current_time - *last_time; 47 | if timediff < Duration::seconds(diff) { 48 | return true; 49 | } 50 | if gui::confirm_request(msgstr) { 51 | *last_time = current_time; 52 | return true; 53 | } 54 | false 55 | } 56 | } 57 | } 58 | } 59 | 60 | pub async fn start_server(auth_timeout: Prompt) { 61 | match UnixListener::bind(SOCKNAME) { 62 | Ok(listener) => { 63 | let wrapper = tokio_stream::wrappers::UnixListenerStream::new(listener); 64 | let last_auth_time = Arc::new(Mutex::new(Utc::now())); 65 | server::serve( 66 | wrapper, 67 | SecureAgent { 68 | auth_timeout, 69 | last_auth_time, 70 | }, 71 | ) 72 | .await 73 | .unwrap(); 74 | } 75 | Err(e) => { 76 | eprintln!("Error while starting agent server: {}", e); 77 | } 78 | } 79 | } 80 | 81 | pub async fn close_socket() { 82 | fs::remove_file(SOCKNAME).await.unwrap(); 83 | } 84 | 85 | pub struct Client { 86 | conn: Connection, 87 | } 88 | 89 | impl Client { 90 | pub fn init(pass: &str, db_path: &str) -> Result { 91 | let conn = db::open_db(pass, db_path)?; 92 | // Here we would ideally place some decryption mechanisms to handle 93 | // sensitive key data 94 | Ok(Self { conn }) 95 | } 96 | 97 | pub async fn import_key_from_file( 98 | &self, 99 | pass: Option, 100 | nick: &str, 101 | keypath: &str, 102 | ) -> bool { 103 | let mut confpath = dirs::home_dir().unwrap(); 104 | confpath.push(".ssh/config"); 105 | let mut configfile = File::open(confpath).await.unwrap(); 106 | let mut reader: Vec = Vec::new(); 107 | configfile.read_to_end(&mut reader).await.unwrap(); 108 | let config = SshConfig::default() 109 | .parse(&mut reader.as_slice(), ParseRule::STRICT) 110 | .unwrap(); 111 | let params = config.query(nick); 112 | let host = params.host_name.unwrap(); 113 | let user = params.user.unwrap(); 114 | let port = params.port.unwrap_or(22); 115 | let key = load_secret_key(keypath, pass.as_deref()).unwrap(); 116 | let encoded_key = pkcs8::encode_pkcs8(&key); 117 | crate::db::insert_key(&self.conn, nick, &user, &host, port, encoded_key) 118 | } 119 | 120 | pub async fn add_key_to_running_agent(&self, key: &ProcessedKey) { 121 | match UnixStream::connect(SOCKNAME).await { 122 | Ok(stream) => { 123 | let mut dummyclient = client::AgentClient::connect(stream); 124 | println!("adding key {}", key.nickname); 125 | let pair = key.keypair.clone(); 126 | dummyclient.add_identity(&pair, &[]).await.unwrap(); 127 | } 128 | Err(_) => eprintln!("Couldn't connect to agent, is it running?"), 129 | } 130 | } 131 | 132 | pub async fn add_all_keys(&self) { 133 | // Add keys to server automatically 134 | // This is done by creating a dummy client that adds all the keys we have 135 | let keys = self.show_all_keys(); 136 | for key in keys.iter() { 137 | self.add_key_to_running_agent(key).await; 138 | } 139 | } 140 | 141 | pub async fn gen_key(&self, nick: &str, user: &str, host: &str, port: u16) -> bool { 142 | let key = KeyPair::generate_ed25519().unwrap(); 143 | // store this encoded key in db 144 | let encoded_key = pkcs8::encode_pkcs8(&key); 145 | let res = crate::db::insert_key(&self.conn, nick, user, host, port, encoded_key); 146 | if !res { 147 | return false; 148 | } 149 | let processedkey = self.show_key(nick).unwrap(); 150 | // insert key into running agent, if any 151 | self.add_key_to_running_agent(&processedkey).await; 152 | true 153 | } 154 | 155 | pub fn show_key(&self, nick: &str) -> Result { 156 | match crate::db::get_key(&self.conn, nick) { 157 | Ok(res) => Ok(res), 158 | Err(e) => { 159 | println!("That key doesn't exist, try creating it?"); 160 | Err(e.into()) 161 | } 162 | } 163 | } 164 | 165 | pub fn update_key( 166 | &self, 167 | nick: &str, 168 | user: &Option, 169 | host: &Option, 170 | port: &Option, 171 | genkey: &Option, 172 | ) -> bool { 173 | match crate::db::update_key(&self.conn, nick, user, host, port, genkey) { 174 | Ok(rows) => rows != 0, 175 | Err(_) => false, 176 | } 177 | } 178 | 179 | pub fn delete_key(&self, nick: &str) -> bool { 180 | match crate::db::del_key(&self.conn, nick) { 181 | Ok(rows) => rows != 0, 182 | Err(_) => false, 183 | } 184 | } 185 | 186 | pub fn show_all_keys(&self) -> Vec { 187 | crate::db::get_all_keys(&self.conn).unwrap() 188 | } 189 | } 190 | --------------------------------------------------------------------------------