comparison auth/hash_password.c @ 264:04fee26ecce0

add authenticated JRPG conversation platform Add reusable auth/session storage, owned conversation recovery, guest quotas, admin workflows, URL-routed conversation UI, mobile frame support, and parallel browser acceptance. Co-authored-by: Copilot <[email protected]>
author MrJuneJune <me@mrjunejune.com>
date Fri, 07 Aug 2026 07:34:12 -0700
parents
children
comparison
equal deleted inserted replaced
263:ee04e4e69fed 264:04fee26ecce0
1 #include "auth/auth_crypto.h"
2
3 #include <openssl/crypto.h>
4
5 #include <stdio.h>
6 #include <string.h>
7 #include <termios.h>
8 #include <unistd.h>
9
10 #define PW_MAX AUTH_CRYPTO_PASSWORD_MAX_BYTES
11
12 static int read_password(int fd, char *buf, size_t capacity)
13 {
14 size_t len = 0;
15 int too_long = 0;
16 for (;;)
17 {
18 unsigned char c;
19 int r = (int)read(fd, &c, 1);
20 if (r < 0)
21 return -1;
22 if (r == 0)
23 break;
24 if (c == '\n' || c == '\r')
25 break;
26 if (len + 1 >= capacity)
27 {
28 too_long = 1;
29 continue;
30 }
31 buf[len++] = (char)c;
32 }
33 buf[len] = '\0';
34 return too_long ? -2 : (int)len;
35 }
36
37 int main(int argc, char **argv)
38 {
39 (void)argc;
40 (void)argv;
41
42 int fd = STDIN_FILENO;
43 int is_tty = isatty(fd);
44 struct termios old_term;
45 struct termios new_term;
46 int restored = 0;
47
48 if (is_tty)
49 {
50 if (tcgetattr(fd, &old_term) != 0)
51 {
52 fprintf(stderr, "hash_password: failed to get terminal attributes\n");
53 return 1;
54 }
55 new_term = old_term;
56 new_term.c_lflag &= (tcflag_t)~(ECHO | ECHOE | ECHOK | ECHONL);
57 new_term.c_lflag |= ICANON;
58 if (tcsetattr(fd, TCSAFLUSH, &new_term) != 0)
59 {
60 fprintf(stderr, "hash_password: failed to disable echo\n");
61 return 1;
62 }
63 restored = 1;
64 fprintf(stderr, "Password: ");
65 fflush(stderr);
66 }
67
68 char pw[PW_MAX + 1];
69 memset(pw, 0, sizeof(pw));
70 int n = read_password(fd, pw, sizeof(pw));
71
72 if (restored)
73 {
74 tcsetattr(fd, TCSAFLUSH, &old_term);
75 fprintf(stderr, "\n");
76 }
77
78 if (n == -2)
79 {
80 fprintf(stderr, "hash_password: %s\n",
81 Auth_Crypto_Result_String(AUTH_CRYPTO_PASSWORD_TOO_LONG));
82 OPENSSL_cleanse(pw, sizeof(pw));
83 return 1;
84 }
85 if (n < 0)
86 {
87 fprintf(stderr, "hash_password: read error\n");
88 OPENSSL_cleanse(pw, sizeof(pw));
89 return 1;
90 }
91 if (n == 0)
92 {
93 fprintf(stderr, "hash_password: empty password\n");
94 OPENSSL_cleanse(pw, sizeof(pw));
95 return 1;
96 }
97
98 char encoded_hash[AUTH_CRYPTO_PASSWORD_HASH_ENCODED_SIZE];
99 Auth_Crypto_Result result =
100 Auth_Crypto_Password_Hash(pw, encoded_hash, sizeof(encoded_hash));
101 OPENSSL_cleanse(pw, sizeof(pw));
102
103 if (result != AUTH_CRYPTO_OK)
104 {
105 fprintf(stderr, "hash_password: %s\n", Auth_Crypto_Result_String(result));
106 return 1;
107 }
108
109 puts(encoded_hash);
110 return 0;
111 }