Overview
| Comment: | fix bugs found by qwen3.6-35a3b |
|---|---|
| Downloads: | Tarball | ZIP archive | SQL archive |
| Timelines: | family | ancestors | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
ba636ffe3da24c91be3c75402f2e3f49 |
| User & Date: | lexi on 2026-05-22 11:58:06 |
| Other Links: | manifest | tags |
Context
|
2026-05-22
| ||
| 11:58 | fix bugs found by qwen3.6-35a3b Leaf check-in: ba636ffe3d user: lexi tags: trunk | |
|
2025-04-15
| ||
| 10:28 | fix idiot typo check-in: a1d7d9de5e user: lexi tags: trunk | |
Changes
Modified clib/compose.c from [9e5668944d] to [981e719b09].
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
#ifndef k_static
char* compose(pstr* lst,size_t ct, size_t* strsz) k_impl ({
size_t len = pstrsum(lst,ct)
if (strsz != NULL) *strsz = len;
if (len == 0) return NULL;
char* str = malloc(len + 1);
char* ptr = pstrcoll(lst, ct, ptr);
*ptr = 0;
return str;
});
#endif
char* impose(pstr* lst,size_t ct, size_t* strsz, char* buf) k_impl({
size_t len = pstrsum(lst,ct);
|
| |
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
#ifndef k_static
char* compose(pstr* lst,size_t ct, size_t* strsz) k_impl ({
size_t len = pstrsum(lst,ct)
if (strsz != NULL) *strsz = len;
if (len == 0) return NULL;
char* str = malloc(len + 1);
char* ptr = pstrcoll(lst, ct, str);
*ptr = 0;
return str;
});
#endif
char* impose(pstr* lst,size_t ct, size_t* strsz, char* buf) k_impl({
size_t len = pstrsum(lst,ct);
|
Modified clib/map.c from [f74e4bde0b] to [7853f77aca].
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
}
}
free(om);
return nm;
}
static bool mapEqPredicate(mapValue a, void* b) {
return a.ip = ((mapValue*)b) -> ip; /* real fucky */
}
mapResult mapRFindPred(map* m, void* val, mapPredicate p) {
for (size_t i = 0; i < m->sz; ++ i) {
mapBox* b = &m -> boxes[i];
if (b -> head == nullptr) continue;
for (mapLink* l = b -> head; l != nullptr; l = l -> next) {
|
| |
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
}
}
free(om);
return nm;
}
static bool mapEqPredicate(mapValue a, void* b) {
return a.ip == ((mapValue*)b) -> ip; /* real fucky */
}
mapResult mapRFindPred(map* m, void* val, mapPredicate p) {
for (size_t i = 0; i < m->sz; ++ i) {
mapBox* b = &m -> boxes[i];
if (b -> head == nullptr) continue;
for (mapLink* l = b -> head; l != nullptr; l = l -> next) {
|
Modified kpw/kpw.c from [9379e84c9e] to [f38f0771ed].
25 26 27 28 29 30 31 32 33 34 35 36 37 38 .. 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 ... 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 ... 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 ... 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 ... 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 ... 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 ... 484 485 486 487 488 489 490 491 492 493 494 495 496 497 ... 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 ... 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 ... 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 ... 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 ... 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 ... 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 ... 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 ... 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 ... 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 .... 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 .... 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 |
* interface. this is unlikely to cause problems, * but should be kept in mind. * * TODO prevent pw reads from going off the edge of * the screen and fucking up all the shit */ #include <unistd.h> #include <sys/random.h> #include <sys/syscall.h> #include <sys/shm.h> #include <stddef.h> #include <stdint.h> #include <stdlib.h> ................................................................................ # include <pwd.h> # include <stdlib.h> #else # define copy(str,len) #endif enum /* constants */ { null = 0, true = 1, false = 0, kpw_shm_key = 0x3CC215A, }; #include "err.inc" enum /* db format constants */ { db_pubkey_len = crypto_box_PUBLICKEYBYTES, db_privkey_len = crypto_box_SECRETKEYBYTES, kpw_db_pw_max = 64, default_pw_len = 32, }; typedef _Bool bool; typedef unsigned long long iaia_word_type; typedef bad iaia_error_type; enum /* iaia errors */ { iaia_e_ok = ok, iaia_e_base = fail, iaia_e_domain = fail, iaia_e_overflow = fail, ................................................................................ #ifdef _CLIPBOARD char* const* cbd_cmds[] = { /* NOTE: these commands must be specified in order of * most- to least-specific. more than one utility may * be present on a given system, so we need to make sure * the right one is called. */ (char* const[]){"termux-clipboard-set", null}, (char* const[]){"xsel", "-bi", null}, /* TODO: allow command to be specified by env var */ null }; enum bad copy(const char* str, size_t len) { alert(a_debug, "copying password to clipboard"); if (geteuid() == 0) { /* on a sane system, what we'd do is hike up the process * tree til we found a non-root user. alas, this is UNIX. */ const char* realuser = getenv("SUDO_USER"); if (realuser == null) realuser = "nobody"; alert(a_warn, "running as root! dropping privileges to prevent malicious use of copy functionality"); setenv("USER", realuser, true); struct passwd* nobody = getpwnam(realuser); if (nobody == null) { alert(a_fatal | bad_user, "could not get UID to drop privileges; bailing"); return bad_user; } else { setenv("HOME", nobody -> pw_dir, true); setenv("SHELL", "/dev/null", true); setuid(nobody -> pw_uid); if (geteuid() == 0) ................................................................................ char* const clipboard_env_arg = getenv("mkpw_clipboard_setter_arg"); // FIXME: allow multiple args int fds[2]; if (pipe(fds) != 0) return bad_pipe; if (!fork()) { close(fds[1]); dup2(fds[0], 0); if (clipboard_env != null) { execvp(clipboard_env, (char* const[]){ clipboard_env, clipboard_env_arg, null}); return bad_copy; } else for(char* const** cmd = cbd_cmds; *cmd != null; ++cmd) { execvp((*cmd)[0], *cmd); } return bad_copy; } else { close(fds[0]); write(fds[1], str, len); write(fds[1], "\n", 1); ................................................................................ hexdump(byte* bytes, size_t sz) { if(!_g_debug_msgs) return; alert(a_debug, "printing hex dump"); byte* st = bytes; write(2, _str("\t\x1b[94m")); for (size_t i = 0; i < sz; ++i) { char hex[5] = " "; kitoa(16, bytes[i], hex, hex + 2, NULL, true); write(2, hex, 4); if(!((i+1)%8)) { write(2, _str("\x1b[;1m│\x1b[m ")); bytedump(st, 8); write(2, "\n\t\x1b[94m", (i == sz - 1 ? 1 : 7)); st += 8; } else if (i == sz - 1) { ................................................................................ /* either EOF or an error - either way, * we're finished here */ break; } } while(1); end_read_loop: term_clear(tty, term_clear_line); *p = 0; if (out_len!=NULL) *out_len = p - dest; /* return the terminal to normal */ tcsetattr(tty, TCSANOW, &initial); if (tty != 1) close(tty); } else { alert(a_warn, "reading pw from standard input"); ................................................................................ return ok; } int dbopen(int flags) { const char* dbpath = getenv("kpw_db"); int db; if (dbpath == NULL) { const char* cfg = getenv("XDG_CONFIG_HOME"); if (cfg == NULL) { const char* home = getenv("HOME"); if (home == NULL) exit(bad_insane); size_t homelen = strlen(home); pstr path[] = { {homelen, home}, _p("/.config/kpw.db") }; char buf[homelen + path[1].len + 1]; bzero(buf, sz(buf)); impose(path, sz(path), NULL, buf); db = open(buf, flags, 0600); } else { size_t cfglen = strlen(cfg); pstr path[] = { {cfglen, cfg}, _p("/kpw.db") }; char buf[cfglen + path[1].len + 1]; bzero(buf, sz(buf)); impose(path, sz(path), NULL, buf); db = open(buf, flags, 0600); } } else { db = open(dbpath, flags, 0600); } ................................................................................ alert(a_debug, "deriving secret"); if(crypto_pwhash(key, sz(key), dbpw, pwlen, salt, crypto_pwhash_OPSLIMIT_INTERACTIVE, crypto_pwhash_MEMLIMIT_INTERACTIVE, crypto_pwhash_ALG_DEFAULT) != 0) { return bad_mem; } hexdump(key, sz(key)); alert(a_debug, "attempting to decrypt private key"); for (size_t i = 0; i < sz(key); ++i) { priv[i] = priv_enc[i] ^ key[i]; } hexdump(priv, sz(key)); ................................................................................ memcpy(dest, src, sz); return dest + sz; } enum bad emit_usage(const char* text) { say("\x1b[1musage:\x1b[m "); write(2, _g_binary_name, strlen(_g_binary_name)); if (text == NULL) { write(2, kpw_optstr, sz(kpw_optstr)); write(2, kpw_usage, sz(kpw_usage)); } else write(2, text, strlen(text)); return bad_usage; } int ................................................................................ bool print = false, clobber = false, no_more_opts = false; # ifdef _CLIPBOARD bool copy_pw = true; # endif for (const char** arg = argv + 1; *arg != null; ++arg) { if (!no_more_opts && (*arg)[0] == '-') { if ((*arg)[1] == '-') { /* long opt */ if((*arg)[2] == 0) { no_more_opts = true; continue; } unsigned char a; ................................................................................ } } else { if (param > sz(params)) return bad_syntax; params[param++] = *arg; } } if (op == getpw && param == 0) return emit_usage(NULL); if (sodium_init() < 0) return bad_lib_sodium_init; switch(op) { # ifdef _SAVEKEY case logout: ................................................................................ key_priv* saved = shmat(shm, 0, 0); if (saved == (void*)-1) return bad_shm; memcpy(saved, priv, sz(priv)); shmdt(saved); } else { int shm = shmget(ipck, sizeof(key_priv), 0); if (shm == -1) return bad_no_shm; shmctl(shm, IPC_RMID, NULL); } return ok; } # endif case genpw: ................................................................................ case addpw: { if (param == 0) return emit_usage( op == addpw ? " -a[p] <account> [<pw>]\n" : /* genpw */" -g[lmusp] <account> [<pw len>]\n"); if (param > 2 || param < 1) return bad_syntax; const char* acct = params[0], * prm = (param == 2 ? params[1] : NULL); alert(a_debug, "opening database"); int db = dbopen(O_RDWR); if (db == -1) return bad_db_load; alert(a_debug, "reading in public key"); byte key [db_pubkey_len]; ssize_t e = read(db, key, sz(key)); ................................................................................ lseek(db, 0, SEEK_END); bool tty_in = isatty(0), tty_out = isatty(1); password pw; size_t pwlen; const char* acct_pw; if (op == addpw) { if (prm == NULL) { pstr prompt_l[] = { _p("- new password for "), {0, acct}, _p(": "), }; char prompt[pstrsum(prompt_l, sz(prompt_l))]; if (tty_in) pstrcoll(prompt_l, sz(prompt_l), prompt); bad e = pwread(!print, pw, &pwlen, prompt, sz(prompt)); if (e != ok) return e; if (tty_in && !print) { password pw_conf; e = pwread(true, pw_conf, NULL, _str("- confirm: ")); if (e != ok) return e; if (strcmp(pw,pw_conf) != 0) return bad_pw_match; } acct_pw = pw; } else acct_pw = prm, pwlen = strlen(prm); } else if (op == genpw) { unsigned long long len; if (prm != NULL) { alert(a_debug, "converting length parameter to integer"); bad e = katoi(10, prm, &len); if (e != ok) return bad_num; } else alert(a_debug, "using default password length"), len = default_pw_len; alert(a_debug, "generating new password"); ................................................................................ /* op==chpw */ " -c <account> [<new pw>]\n"); if (param < 1 || param > (op == delpw ? 1 : 2)) return bad_syntax; const char* target = params[0]; const char* delta; if (param == 2) delta=params[1]; else delta=NULL; int db = dbopen(O_RDWR); if (db == -1) return bad_db_load; const size_t dbsz = lseek(db, 0, SEEK_END); lseek(db, 0, SEEK_SET); ................................................................................ const char* newpass; size_t pwlen; if (op == regen) { alert(a_debug, "generating new password"); /* generating a new password. use the default * length if the user hasn't supplied one herself, * or if she has, convert it to an integer. */ if (delta == NULL) pwlen = default_pw_len; else { unsigned long long value; bad k = katoi(10, delta, &value); if (k != ok) return bad_num; pwlen = value; } bad m = mkpw(mode, pwbuf, pwlen); if (m != ok) return m; newpass = pwbuf; } else if (op == chpw) { /* the user has requested a password change. take * it from the command line if available, otherwise * generate a prompt and read from stdin */ if (delta == NULL) { pstr prompt_l[] = { _p("- new password for "), {0, target}, _p(": "), }; char prompt[pstrsum(prompt_l, sz(prompt_l))]; if (_g_term_type[0] > plain_term) pstrcoll(prompt_l, sz(prompt_l), prompt); bad p = pwread(!print, pwbuf, &pwlen, prompt, sz(prompt)); if (p != ok) return p; /* prompt again to make sure the user entered * her new password correctly */ if(!print && _g_term_type[0] > plain_term) { password passconf; p = pwread(!print, passconf, NULL, _str("confirm: ")); if (p != ok) return p; if (strcmp(passconf, pwbuf) != 0) return bad_pw_match; } newpass = pwbuf; } else newpass = delta, pwlen = strlen(delta); } else return bad_assert; ................................................................................ return ok; } case getpw: /* kpw <acct> */ case lspw: { /* kpw -t[p] [<prefix>] */ const char* target; if (param == 1) target = params[0]; else if (param == 0) target = NULL; else return bad_syntax; alert(a_debug, "opening database for reading"); int db = dbopen(O_RDONLY); if (db == -1) return bad_db_load; key_pub pub; ................................................................................ alert(a_notice, "database keypair generated, encrypting"); password dbpw; size_t pwlen; bad e = pwread(!print, dbpw, &pwlen, _str("- new database key: ")); if (e != ok) return e; if (!print && isatty(0)) { password dbpw_conf; e = pwread(!print, dbpw_conf, NULL, _str("- confirm: ")); if (e != ok) return e; if(strcmp(dbpw,dbpw_conf) != 0) return bad_pw_match; } byte salt [crypto_pwhash_SALTBYTES], ................................................................................ int main (int argc, const char** argv) { const char* colorterm = getenv("COLORTERM"); const char* term = getenv("TERM"); bool color, ansi; if (colorterm != NULL) color = true; else if (term == NULL) ansi = false, color = false; else if (strstr(term, "color") == NULL) ansi = true, color = false; else color = true; for (uint8_t i = 0; i < 3; ++i) { if(isatty(i)) { _g_term_type[i] = (color ? color_term : ansi ? ansi_term : plain_term); |
> > | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | |
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 .. 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 ... 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 ... 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 ... 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 ... 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 ... 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 ... 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 ... 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 ... 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 ... 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 ... 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 ... 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 ... 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 ... 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 ... 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 ... 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 .... 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 .... 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 |
* interface. this is unlikely to cause problems, * but should be kept in mind. * * TODO prevent pw reads from going off the edge of * the screen and fucking up all the shit */ #define _DEFAULT_SOURCE #include <unistd.h> #include <sys/random.h> #include <sys/syscall.h> #include <sys/shm.h> #include <stddef.h> #include <stdint.h> #include <stdlib.h> ................................................................................ # include <pwd.h> # include <stdlib.h> #else # define copy(str,len) #endif enum /* constants */ { /* nullptr = 0, true = 1, false = 0, */ kpw_shm_key = 0x3CC215A, }; #include "err.inc" enum /* db format constants */ { db_pubkey_len = crypto_box_PUBLICKEYBYTES, db_privkey_len = crypto_box_SECRETKEYBYTES, kpw_db_pw_max = 64, default_pw_len = 32, }; /* typedef _Bool bool; */ typedef unsigned long long iaia_word_type; typedef bad iaia_error_type; enum /* iaia errors */ { iaia_e_ok = ok, iaia_e_base = fail, iaia_e_domain = fail, iaia_e_overflow = fail, ................................................................................ #ifdef _CLIPBOARD char* const* cbd_cmds[] = { /* NOTE: these commands must be specified in order of * most- to least-specific. more than one utility may * be present on a given system, so we need to make sure * the right one is called. */ (char* const[]){"termux-clipboard-set", nullptr}, (char* const[]){"xsel", "-bi", nullptr}, /* TODO: allow command to be specified by env var */ nullptr }; enum bad copy(const char* str, size_t len) { alert(a_debug, "copying password to clipboard"); if (geteuid() == 0) { /* on a sane system, what we'd do is hike up the process * tree til we found a non-root user. alas, this is UNIX. */ const char* realuser = getenv("SUDO_USER"); if (realuser == nullptr) realuser = "nobody"; alert(a_warn, "running as root! dropping privileges to prevent malicious use of copy functionality"); setenv("USER", realuser, true); struct passwd* nobody = getpwnam(realuser); if (nobody == nullptr) { alert(a_fatal | bad_user, "could not get UID to drop privileges; bailing"); return bad_user; } else { setenv("HOME", nobody -> pw_dir, true); setenv("SHELL", "/dev/null", true); setuid(nobody -> pw_uid); if (geteuid() == 0) ................................................................................ char* const clipboard_env_arg = getenv("mkpw_clipboard_setter_arg"); // FIXME: allow multiple args int fds[2]; if (pipe(fds) != 0) return bad_pipe; if (!fork()) { close(fds[1]); dup2(fds[0], 0); if (clipboard_env != nullptr) { execvp(clipboard_env, (char* const[]){ clipboard_env, clipboard_env_arg, nullptr}); return bad_copy; } else for(char* const** cmd = cbd_cmds; *cmd != nullptr; ++cmd) { execvp((*cmd)[0], *cmd); } return bad_copy; } else { close(fds[0]); write(fds[1], str, len); write(fds[1], "\n", 1); ................................................................................ hexdump(byte* bytes, size_t sz) { if(!_g_debug_msgs) return; alert(a_debug, "printing hex dump"); byte* st = bytes; write(2, _str("\t\x1b[94m")); for (size_t i = 0; i < sz; ++i) { char hex[5] = " "; kitoa(16, bytes[i], hex, hex + 2, nullptr, true); write(2, hex, 4); if(!((i+1)%8)) { write(2, _str("\x1b[;1m│\x1b[m ")); bytedump(st, 8); write(2, "\n\t\x1b[94m", (i == sz - 1 ? 1 : 7)); st += 8; } else if (i == sz - 1) { ................................................................................ /* either EOF or an error - either way, * we're finished here */ break; } } while(1); end_read_loop: term_clear(tty, term_clear_line); *p = 0; if (out_len!=nullptr) *out_len = p - dest; /* return the terminal to normal */ tcsetattr(tty, TCSANOW, &initial); if (tty != 1) close(tty); } else { alert(a_warn, "reading pw from standard input"); ................................................................................ return ok; } int dbopen(int flags) { const char* dbpath = getenv("kpw_db"); int db; if (dbpath == nullptr) { const char* cfg = getenv("XDG_CONFIG_HOME"); if (cfg == nullptr) { const char* home = getenv("HOME"); if (home == nullptr) exit(bad_insane); size_t homelen = strlen(home); pstr path[] = { {homelen, home}, _p("/.config/kpw.db") }; char buf[homelen + path[1].len + 1]; bzero(buf, sz(buf)); impose(path, sz(path), nullptr, buf); db = open(buf, flags, 0600); } else { size_t cfglen = strlen(cfg); pstr path[] = { {cfglen, cfg}, _p("/kpw.db") }; char buf[cfglen + path[1].len + 1]; bzero(buf, sz(buf)); impose(path, sz(path), nullptr, buf); db = open(buf, flags, 0600); } } else { db = open(dbpath, flags, 0600); } ................................................................................ alert(a_debug, "deriving secret"); if(crypto_pwhash(key, sz(key), dbpw, pwlen, salt, crypto_pwhash_OPSLIMIT_INTERACTIVE, crypto_pwhash_MEMLIMIT_INTERACTIVE, crypto_pwhash_ALG_DEFAULT) != 0) { return bad_mem; } memset(&dbpw, 0, (sizeof dbpw)); hexdump(key, sz(key)); alert(a_debug, "attempting to decrypt private key"); for (size_t i = 0; i < sz(key); ++i) { priv[i] = priv_enc[i] ^ key[i]; } hexdump(priv, sz(key)); ................................................................................ memcpy(dest, src, sz); return dest + sz; } enum bad emit_usage(const char* text) { say("\x1b[1musage:\x1b[m "); write(2, _g_binary_name, strlen(_g_binary_name)); if (text == nullptr) { write(2, kpw_optstr, sz(kpw_optstr)); write(2, kpw_usage, sz(kpw_usage)); } else write(2, text, strlen(text)); return bad_usage; } int ................................................................................ bool print = false, clobber = false, no_more_opts = false; # ifdef _CLIPBOARD bool copy_pw = true; # endif for (const char** arg = argv + 1; *arg != nullptr; ++arg) { if (!no_more_opts && (*arg)[0] == '-') { if ((*arg)[1] == '-') { /* long opt */ if((*arg)[2] == 0) { no_more_opts = true; continue; } unsigned char a; ................................................................................ } } else { if (param > sz(params)) return bad_syntax; params[param++] = *arg; } } if (op == getpw && param == 0) return emit_usage(nullptr); if (sodium_init() < 0) return bad_lib_sodium_init; switch(op) { # ifdef _SAVEKEY case logout: ................................................................................ key_priv* saved = shmat(shm, 0, 0); if (saved == (void*)-1) return bad_shm; memcpy(saved, priv, sz(priv)); shmdt(saved); } else { int shm = shmget(ipck, sizeof(key_priv), 0); if (shm == -1) return bad_no_shm; shmctl(shm, IPC_RMID, nullptr); } return ok; } # endif case genpw: ................................................................................ case addpw: { if (param == 0) return emit_usage( op == addpw ? " -a[p] <account> [<pw>]\n" : /* genpw */" -g[lmusp] <account> [<pw len>]\n"); if (param > 2 || param < 1) return bad_syntax; const char* acct = params[0], * prm = (param == 2 ? params[1] : nullptr); alert(a_debug, "opening database"); int db = dbopen(O_RDWR); if (db == -1) return bad_db_load; alert(a_debug, "reading in public key"); byte key [db_pubkey_len]; ssize_t e = read(db, key, sz(key)); ................................................................................ lseek(db, 0, SEEK_END); bool tty_in = isatty(0), tty_out = isatty(1); password pw; size_t pwlen; const char* acct_pw; if (op == addpw) { if (prm == nullptr) { pstr prompt_l[] = { _p("- new password for "), {0, acct}, _p(": "), }; char prompt[pstrsum(prompt_l, sz(prompt_l))]; if (tty_in) pstrcoll(prompt_l, sz(prompt_l), prompt); bad e = pwread(!print, pw, &pwlen, prompt, sz(prompt)); if (e != ok) return e; if (tty_in && !print) { password pw_conf; e = pwread(true, pw_conf, nullptr, _str("- confirm: ")); if (e != ok) return e; if (strcmp(pw,pw_conf) != 0) return bad_pw_match; } acct_pw = pw; } else acct_pw = prm, pwlen = strlen(prm); } else if (op == genpw) { unsigned long long len; if (prm != nullptr) { alert(a_debug, "converting length parameter to integer"); bad e = katoi(10, prm, &len); if (e != ok) return bad_num; } else alert(a_debug, "using default password length"), len = default_pw_len; alert(a_debug, "generating new password"); ................................................................................ /* op==chpw */ " -c <account> [<new pw>]\n"); if (param < 1 || param > (op == delpw ? 1 : 2)) return bad_syntax; const char* target = params[0]; const char* delta; if (param == 2) delta=params[1]; else delta=nullptr; int db = dbopen(O_RDWR); if (db == -1) return bad_db_load; const size_t dbsz = lseek(db, 0, SEEK_END); lseek(db, 0, SEEK_SET); ................................................................................ const char* newpass; size_t pwlen; if (op == regen) { alert(a_debug, "generating new password"); /* generating a new password. use the default * length if the user hasn't supplied one herself, * or if she has, convert it to an integer. */ if (delta == nullptr) pwlen = default_pw_len; else { unsigned long long value; bad k = katoi(10, delta, &value); if (k != ok) return bad_num; pwlen = value; } bad m = mkpw(mode, pwbuf, pwlen); if (m != ok) return m; newpass = pwbuf; } else if (op == chpw) { /* the user has requested a password change. take * it from the command line if available, otherwise * generate a prompt and read from stdin */ if (delta == nullptr) { pstr prompt_l[] = { _p("- new password for "), {0, target}, _p(": "), }; char prompt[pstrsum(prompt_l, sz(prompt_l))]; if (_g_term_type[0] > plain_term) pstrcoll(prompt_l, sz(prompt_l), prompt); bad p = pwread(!print, pwbuf, &pwlen, prompt, sz(prompt)); if (p != ok) return p; /* prompt again to make sure the user entered * her new password correctly */ if(!print && _g_term_type[0] > plain_term) { password passconf; p = pwread(!print, passconf, nullptr, _str("confirm: ")); if (p != ok) return p; if (strcmp(passconf, pwbuf) != 0) return bad_pw_match; } newpass = pwbuf; } else newpass = delta, pwlen = strlen(delta); } else return bad_assert; ................................................................................ return ok; } case getpw: /* kpw <acct> */ case lspw: { /* kpw -t[p] [<prefix>] */ const char* target; if (param == 1) target = params[0]; else if (param == 0) target = nullptr; else return bad_syntax; alert(a_debug, "opening database for reading"); int db = dbopen(O_RDONLY); if (db == -1) return bad_db_load; key_pub pub; ................................................................................ alert(a_notice, "database keypair generated, encrypting"); password dbpw; size_t pwlen; bad e = pwread(!print, dbpw, &pwlen, _str("- new database key: ")); if (e != ok) return e; if (!print && isatty(0)) { password dbpw_conf; e = pwread(!print, dbpw_conf, nullptr, _str("- confirm: ")); if (e != ok) return e; if(strcmp(dbpw,dbpw_conf) != 0) return bad_pw_match; } byte salt [crypto_pwhash_SALTBYTES], ................................................................................ int main (int argc, const char** argv) { const char* colorterm = getenv("COLORTERM"); const char* term = getenv("TERM"); bool color, ansi; if (colorterm != nullptr) color = true; else if (term == nullptr) ansi = false, color = false; else if (strstr(term, "color") == nullptr) ansi = true, color = false; else color = true; for (uint8_t i = 0; i < 3; ++i) { if(isatty(i)) { _g_term_type[i] = (color ? color_term : ansi ? ansi_term : plain_term); |
Modified makefile from [ca4a818574] to [6698dd488b].
32 33 34 35 36 37 38 39 40 41 42 |
safekill: safekill.c $(cc) $< -lX11 -o$@ $(cc-post) xpriv: xpriv.c $(cc) $< -lrt -lutil -lX11 -o $@ $(cc-post) kpw.bin: kpw/makefile $(MAKE) root=$(realpath .) flags=$(kpw-flags) -C kpw $(realpath .)/$@ .PHONY: kpw |
| |
32 33 34 35 36 37 38 39 40 41 42 |
safekill: safekill.c
$(cc) $< -lX11 -o$@ $(cc-post)
xpriv: xpriv.c
$(cc) $< -lrt -lutil -lX11 -o $@ $(cc-post)
kpw.bin: kpw/makefile kpw
$(MAKE) root=$(realpath .) flags=$(kpw-flags) -C kpw $(realpath .)/$@
.PHONY: kpw
|
Modified mkpw.c from [c81247c932] to [4a479fd587].
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 .. 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 ... 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 ... 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 ... 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
#define options \
o('l',lower,mode = lower) \
o('m',mix,mode = mix) \
o('u',upper,mode = upper)\
_cl_opt
enum /* constants */ {
null = 0, true = 1, false = 0
};
typedef enum bad {
ok = 0,
fail = 1,
bad_user,
bad_option,
bad_syntax,
bad_entropy,
bad_copy,
bad_usage = 64, /* fleabsd idiom */
} bad;
typedef _Bool bool;
typedef unsigned long long iaia_word_type;
typedef bad iaia_error_type;
enum /* iaia errors */ {
iaia_e_ok = ok,
iaia_e_base = fail,
iaia_e_domain = fail,
iaia_e_overflow = fail,
................................................................................
#ifdef _CLIPBOARD
char* const* cbd_cmds[] = {
/* NOTE: these commands must be specified in order of
* most- to least-specific. more than one utility may
* be present on a given system, so we need to make sure
* the right one is called. */
(char* const[]){"termux-clipboard-set", null},
(char* const[]){"xsel", "-bi", null},
/* TODO: allow command to be specified by env var */
null
};
#endif
int main(int argc, const char** argv) {
if (argc == 0) return -1;
if (argc == 1) {
size_t namelen = strlen(argv[0]);
say("\x1b[1musage:\x1b[m ");
................................................................................
unsigned long long len, q = 1;
bool gotlen = false;
bool gotq = false;
# ifdef _CLIPBOARD
bool copy = true;
# endif
for (const char** arg = argv; *arg != null; ++arg) {
if ((*arg)[0] == '-') {
if ((*arg)[1] == '-') { /* long opt */
unsigned char a;
if (tblget(sz(argtbl), argtbl, *arg + 2, &a) == ok) switch (a) {
# define o(short, long, code) case arg_##long:code;break;
options
# undef o
................................................................................
}
if (!gotlen) return bad_syntax;
# ifdef _CLIPBOARD
if (geteuid() == 0 && copy) {
/* on a sane system, what we'd do is hike up the process
* tree til we found a non-root user. alas, this is UNIX. */
const char* realuser = getenv("SUDO_USER");
if (realuser == null) realuser = "nobody";
say("\x1b[1;33mwarning:\x1b[m you are running \x1b[4m");
size_t namelen = strlen(argv[0]);
write(2,argv[0],namelen);
say("\x1b[24m as \x1b[1mroot\x1b[m! dropping to \x1b[1m");
write(2,realuser,strlen(realuser));
setenv("USER", realuser, true);
say("\x1b[m to prevent malicious behavior\n");
struct passwd* nobody = getpwnam(realuser);
if (nobody == null) {
say("\x1b[1;31mfatal:\x1b[m could not get UID to drop privileges; bailing");
return bad_user;
} else {
setenv("HOME", nobody -> pw_dir, true);
setenv("SHELL", "/dev/null", true);
setuid(nobody -> pw_uid);
if (geteuid() == 0)
say("\x1b[1;31mnice try:\x1b[m i don't fucking think so, you sneaky bastard");
}
}
# endif
................................................................................
char* const clipboard_env_arg = getenv("mkpw_clipboard_setter_arg");
// FIXME: allow multiple args
int fds[2];
if (pipe(fds) != 0) return 63;
if (!fork()) {
close(fds[1]);
dup2(fds[0], 0);
if (clipboard_env != null) {
execvp(clipboard_env, (char* const[]){
clipboard_env, clipboard_env_arg, null});
return bad_copy;
} else for(char* const** cmd = cbd_cmds; *cmd != null; ++cmd) {
execvp((*cmd)[0], *cmd);
}
return bad_copy; /* exec failed */
} else {
close(fds[0]);
write(fds[1], buf, len);
write(fds[1], "\n", 1);
|
< < < < < | | | | | | | | | | |
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 .. 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 ... 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 ... 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 ... 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
#define options \
o('l',lower,mode = lower) \
o('m',mix,mode = mix) \
o('u',upper,mode = upper)\
_cl_opt
typedef enum bad {
ok = 0,
fail = 1,
bad_user,
bad_option,
bad_syntax,
bad_entropy,
bad_copy,
bad_usage = 64, /* fleabsd idiom */
} bad;
typedef unsigned long long iaia_word_type;
typedef bad iaia_error_type;
enum /* iaia errors */ {
iaia_e_ok = ok,
iaia_e_base = fail,
iaia_e_domain = fail,
iaia_e_overflow = fail,
................................................................................
#ifdef _CLIPBOARD
char* const* cbd_cmds[] = {
/* NOTE: these commands must be specified in order of
* most- to least-specific. more than one utility may
* be present on a given system, so we need to make sure
* the right one is called. */
(char* const[]){"termux-clipboard-set", nullptr},
(char* const[]){"xsel", "-bi", nullptr},
/* TODO: allow command to be specified by env var */
nullptr
};
#endif
int main(int argc, const char** argv) {
if (argc == 0) return -1;
if (argc == 1) {
size_t namelen = strlen(argv[0]);
say("\x1b[1musage:\x1b[m ");
................................................................................
unsigned long long len, q = 1;
bool gotlen = false;
bool gotq = false;
# ifdef _CLIPBOARD
bool copy = true;
# endif
for (const char** arg = argv; *arg != nullptr; ++arg) {
if ((*arg)[0] == '-') {
if ((*arg)[1] == '-') { /* long opt */
unsigned char a;
if (tblget(sz(argtbl), argtbl, *arg + 2, &a) == ok) switch (a) {
# define o(short, long, code) case arg_##long:code;break;
options
# undef o
................................................................................
}
if (!gotlen) return bad_syntax;
# ifdef _CLIPBOARD
if (geteuid() == 0 && copy) {
/* on a sane system, what we'd do is hike up the process
* tree til we found a non-root user. alas, this is UNIX. */
const char* realuser = getenv("SUDO_USER");
if (realuser == nullptr) realuser = "nobody";
say("\x1b[1;33mwarning:\x1b[m you are running \x1b[4m");
size_t namelen = strlen(argv[0]);
write(2,argv[0],namelen);
say("\x1b[24m as \x1b[1mroot\x1b[m! dropping to \x1b[1m");
write(2,realuser,strlen(realuser));
setenv("USER", realuser, true);
say("\x1b[m to prevent malicious behavior\n");
struct passwd* nobody = getpwnam(realuser);
if (nobody == nullptr) {
say("\x1b[1;31mfatal:\x1b[m could not get UID to drop privileges; bailing");
return bad_user;
} else {
setenv("HOME", nobody -> pw_dir, true);
setenv("SHELL", "/dev/nullptr", true);
setuid(nobody -> pw_uid);
if (geteuid() == 0)
say("\x1b[1;31mnice try:\x1b[m i don't fucking think so, you sneaky bastard");
}
}
# endif
................................................................................
char* const clipboard_env_arg = getenv("mkpw_clipboard_setter_arg");
// FIXME: allow multiple args
int fds[2];
if (pipe(fds) != 0) return 63;
if (!fork()) {
close(fds[1]);
dup2(fds[0], 0);
if (clipboard_env != nullptr) {
execvp(clipboard_env, (char* const[]){
clipboard_env, clipboard_env_arg, nullptr});
return bad_copy;
} else for(char* const** cmd = cbd_cmds; *cmd != nullptr; ++cmd) {
execvp((*cmd)[0], *cmd);
}
return bad_copy; /* exec failed */
} else {
close(fds[0]);
write(fds[1], buf, len);
write(fds[1], "\n", 1);
|
Modified mkup.c from [c8562e1cb9] to [2ffe422dda].
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
null = 0, false = 0, true = 1
};
typedef _Bool bool;
#else
# define null nullptr
#endif
#define try(x) {bad _E_ = (x); if(_E_ != ok) return _E_;}
#define zero(x) memset(&(x), sizeof(x), 0)
#define mkup_error_list \
e(usage,"usage was displayed to user") \
e(insane,"your system is not in a sane state") \
e(file,"file specified could not be mapped") \
e(empty,"nothing to do; bailing")
|
| |
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
null = 0, false = 0, true = 1
};
typedef _Bool bool;
#else
# define null nullptr
#endif
#define try(x) {bad _E_ = (x); if(_E_ != ok) return _E_;}
#define zero(x) memset(&(x), 0, sizeof(x))
#define mkup_error_list \
e(usage,"usage was displayed to user") \
e(insane,"your system is not in a sane state") \
e(file,"file specified could not be mapped") \
e(empty,"nothing to do; bailing")
|
Modified newtab.c from [66bf54f80a] to [eee3f888cb].
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
...
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
* still remote-working on German time because his * employers are kind of assholes. i'm aware that's * not an excuse and i apologize sincerely. if * anyone wants to submit a MR to tidy up this * abomination without sacrificing performance, i * would welcome it gratefully. */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #include <dirent.h> #include <unistd.h> #define _POSIX_C_SOURCE 200809L #include <string.h> #define ssz(str) (str), (sizeof str) #define dupl(x) x,x #ifndef _default_qutebrowser_location # define _default_qutebrowser_location "/usr/bin/qutebrowser" ................................................................................ int sock = socket(AF_UNIX, SOCK_STREAM, 0); if (connect(sock, (struct sockaddr*)&srv, sizeof srv) != 0) return start_instance; const char msg_blank [] = json_msg_start json_msg_end; const size_t extra = uri != NULL ? strlen(uri) : 0; char msg_start [(sizeof json_msg_start) + extra]; const size_t msgsz = sizeof msg_blank + extra - 1; const char* msg; if (uri == NULL) msg = msg_blank; else { strcpy(msg_start, json_msg_start); strcpy(msg_start + (sizeof json_msg_start) - 1, uri); strcpy(msg_start + (sizeof json_msg_start) - 1 + extra, json_msg_end); |
>
>
<
|
|
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
...
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
* still remote-working on German time because his * employers are kind of assholes. i'm aware that's * not an excuse and i apologize sincerely. if * anyone wants to submit a MR to tidy up this * abomination without sacrificing performance, i * would welcome it gratefully. */ #define _POSIX_C_SOURCE 200809L #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #include <dirent.h> #include <unistd.h> #include <string.h> #define ssz(str) (str), (sizeof str) #define dupl(x) x,x #ifndef _default_qutebrowser_location # define _default_qutebrowser_location "/usr/bin/qutebrowser" ................................................................................ int sock = socket(AF_UNIX, SOCK_STREAM, 0); if (connect(sock, (struct sockaddr*)&srv, sizeof srv) != 0) return start_instance; const char msg_blank [] = json_msg_start json_msg_end; const size_t extra = uri != NULL ? strlen(uri) : 0; char msg_start [(sizeof json_msg_start) + extra + (sizeof json_msg_end) - 1]; const size_t msgsz = sizeof msg_blank + extra - 1; const char* msg; if (uri == NULL) msg = msg_blank; else { strcpy(msg_start, json_msg_start); strcpy(msg_start + (sizeof json_msg_start) - 1, uri); strcpy(msg_start + (sizeof json_msg_start) - 1 + extra, json_msg_end); |
Modified nkvd.c from [bc7c445885] to [7b2d881529].
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 |
{ nkvd_intcall(libc_eaccess,path,mode); }
#define max(a,b) ((a) > (b) ? (a) : (b))
int rename(const char* volatile from,
const char* volatile to) {
if (intercept) {
const size_t fromlen = strlen(from),
tolen = strlen(from);
char fromgulag[redir_len + tolen ],
togulag[redir_len + fromlen];
const char* fromfinal,
* tofinal;
if (interrogate(from, fromlen, fromgulag))
|
| |
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 |
{ nkvd_intcall(libc_eaccess,path,mode); }
#define max(a,b) ((a) > (b) ? (a) : (b))
int rename(const char* volatile from,
const char* volatile to) {
if (intercept) {
const size_t fromlen = strlen(from),
tolen = strlen(to);
char fromgulag[redir_len + tolen ],
togulag[redir_len + fromlen];
const char* fromfinal,
* tofinal;
if (interrogate(from, fromlen, fromgulag))
|
Modified wgsync/src/wgsync.c from [5c0a7396a9] to [1052d70b26].
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 |
char* connstr = getenv("wgsync_conn");
if(connstr == null) _fatal("no connection string supplied");
PGconn* db = PQconnectdb(connstr);
if(PQstatus(db) != CONNECTION_OK)
_fatal(PQerrorMessage(db));
PGresult* q_get_hosts = PQprepare(db, "get_hosts",
"select h.ref, array_remove("
/* "select h.ref, array_remove(array_agg(wgv4::inet) ||" */
"array_agg(wgv6::inet), null)"
"from ns, hostref h "
"where ns.host = h.host and kind = 'pubkey' "
" group by h.host, h.ref;", 0, null);
/*"select ns.wgv4::inet, ns.wgv6::inet, h.ref from ns "
"right join hostref h "
"on h.host = ns.host "
"where h.kind = 'pubkey';"*/
if(!(q_get_hosts && PQresultStatus(q_get_hosts) == PGRES_COMMAND_OK))
_fatal(PQerrorMessage(db));
|
| | |
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 |
char* connstr = getenv("wgsync_conn");
if(connstr == null) _fatal("no connection string supplied");
PGconn* db = PQconnectdb(connstr);
if(PQstatus(db) != CONNECTION_OK)
_fatal(PQerrorMessage(db));
PGresult* q_get_hosts = PQprepare(db, "get_hosts",
"select h.ref, h.public_key, h.preshared_key, array_remove("
/* "select h.ref, array_remove(array_agg(wgv4::inet) ||" */
"array_agg(wgv6::inet), null)"
"from ns, hostref h "
"where ns.host = h.host and kind in ('pubkey', 'psk') "
" group by h.host, h.ref;", 0, null);
/*"select ns.wgv4::inet, ns.wgv6::inet, h.ref from ns "
"right join hostref h "
"on h.host = ns.host "
"where h.kind = 'pubkey';"*/
if(!(q_get_hosts && PQresultStatus(q_get_hosts) == PGRES_COMMAND_OK))
_fatal(PQerrorMessage(db));
|