Differences From
Artifact [de39328fae]:
8 8 * this by attempting to execute a sequence
9 9 * of binaries, and then writing the password
10 10 * to STDIN of the binary that succeeds.
11 11 * ? generates passwords
12 12 * → kpw is unlikely to be portable to non-POSIX
13 13 * systems, but should run fine on Linux as well
14 14 * as BSDs with getrandom() support.
15 + * → kpw has the following dependencies:
16 + * - libsodium
15 17 * ! for getrandom() to work with the version of
16 18 * libc on my android phone, the getrandom() call
17 19 * had to be converted to use the syscall()
18 20 * interface. this is unlikely to cause problems,
19 21 * but should be kept in mind.
20 22 *
21 23 * TODO prevent pw reads from going off the edge of
................................................................................
461 463
462 464 enum bad
463 465 dbunlock(byte* priv_enc, byte* salt, byte* priv) {
464 466 const size_t priv_sz = sizeof(key_priv);
465 467 byte key [db_privkey_len];
466 468
467 469 /* is the private key loaded into memory? */
470 +#ifdef _SAVEKEY
468 471 int shm = shmget(*((key_t*) salt), sizeof(key_priv), 0);
469 472 if (shm == -1) {
473 +#endif
470 474 /* no key in memory - read password from stdin instead */
471 475 password dbpw; size_t pwlen;
472 476 bad e = pwread(true, dbpw, &pwlen,_str("database key: "));
473 477 if (e != ok) return e;
474 478
475 479 alert(a_debug, "deriving secret");
476 480 if(crypto_pwhash(key, sz(key), dbpw, pwlen, salt,
................................................................................
482 486 hexdump(key, sz(key));
483 487
484 488 alert(a_debug, "attempting to decrypt private key");
485 489 for (size_t i = 0; i < sz(key); ++i) {
486 490 priv[i] = priv_enc[i] ^ key[i];
487 491 }
488 492 hexdump(priv, sz(key));
493 +#ifdef _SAVEKEY
489 494 } else {
490 495 /* found a key in memory; loading it into *priv */
491 496 alert(a_debug, "using saved key");
492 497 key_priv* saved = shmat(shm, 0, 0);
493 498 if (saved == (void*)-1)
494 499 return bad_shm;
495 500 hexdump((byte*)saved, sizeof(key_priv));
496 501 memcpy(priv, saved, sizeof(key_priv));
497 502 shmdt(saved);
498 503 }
504 +#endif
499 505
500 506 return ok;
501 507 }
502 508
503 509 enum bad
504 510 dbverify(byte* salt, byte* salt_enc, byte* pub, byte* priv) {
505 511 byte salt_dec [crypto_pwhash_SALTBYTES];
................................................................................
610 616
611 617 if (op == getpw && param == 0) return emit_usage(NULL);
612 618
613 619 if (sodium_init() < 0)
614 620 return bad_lib_sodium_init;
615 621
616 622 switch(op) {
623 +# ifdef _SAVEKEY
617 624 case logout:
618 625 case keyin: {
619 626 if (param != 0) return bad_syntax;
620 627
621 628 int db = dbopen(O_RDONLY);
622 629 key_pub pub;
623 630 key_priv priv, priv_enc;
................................................................................
646 653 int shm = shmget(ipck, sizeof(key_priv), 0);
647 654 if (shm == -1) return bad_no_shm;
648 655 shmctl(shm, IPC_RMID, NULL);
649 656 }
650 657
651 658 return ok;
652 659 }
660 +# endif
653 661
654 662 case genpw:
655 663 case addpw: {
656 664 if (param == 0) return emit_usage(
657 665 op == addpw ? " -a[p] <account> [<pw>]\n" :
658 666 /* genpw */" -g[lmusp] <account> [<pw len>]\n");
659 667