AmendHub

jcs

/

subtext

/

amendments

/

14

user+session: Implement user authentication


jcs made amendment 14 over 2 years ago
--- session.c Fri Dec 3 10:07:56 2021 +++ session.c Mon Dec 6 10:01:19 2021 @@ -21,6 +21,7 @@ #include "subtext.h" #include "session.h" +#include "user.h" #include "uthread.h" #include "util.h" @@ -29,6 +30,7 @@ short nsessions = 0; char session_tbuf[512]; void session_run(struct uthread *uthread, void *arg); +short session_login(struct session *s); struct session * session_create(char *node, struct node_funcs *node_funcs) @@ -53,6 +55,25 @@ session_create(char *node, struct node_funcs *node_fun return session; } +void +session_run(struct uthread *uthread, void *arg) +{ + struct session *s = (struct session *)arg; + + session_output(s, "\r\n" + "Welcome to %s (%s)\r\n" + "\r\n", db->config.name, s->node); + + if (session_login(s) == AUTH_USER_OK) + session_output(s, "Welcome, %s\r\n", s->user->username); + else + session_output(s, "Thanks for playing\r\n"); + + for (;;) { + uthread_yield(); + } +} + short session_output(struct session *session, const char *format, ...) { @@ -73,7 +94,6 @@ session_output(struct session *session, const char *fo memcpy(session->obuf + session->obuflen, session_tbuf, len); session->obuflen += len; session->node_funcs->output(session); - uthread_yield(); return len; } @@ -83,7 +103,6 @@ session_output_char(struct session *session, const cha { session->obuf[session->obuflen++] = c; session->node_funcs->output(session); - uthread_yield(); return 1; } @@ -110,7 +129,7 @@ session_input_char(struct session *session) } char * -session_field_input(struct session *session, unsigned short len) +session_field_input(struct session *session, unsigned short len, char mask) { short ilen = 0, ipos = 0, lastlen = 0; char *field; @@ -158,7 +177,7 @@ session_field_input(struct session *session, unsigned ipos++; ilen++; field[ipos] = '\0'; - session_output_char(session, c); + session_output_char(session, mask ? mask : c); } } @@ -166,22 +185,55 @@ session_field_input(struct session *session, unsigned return NULL; } -void -session_run(struct uthread *uthread, void *arg) +short +session_login(struct session *s) { - struct session *s = (struct session *)arg; - char *line; + struct user *user; + char junk[SHA256_DIGEST_STRING_LENGTH]; + char *username; + char *password; + short n; + size_t len; + + for (n = 1; n <= 3; n++) { + session_output(s, "login: "); + username = session_field_input(s, 32, 0); + session_output(s, "\r\n"); - session_output(s, "\r\n" - "Welcome to %s (%s)\r\n" - "\r\n", db->config.name, s->node); + if (strcmp(username, "guest") == 0) { + /* TODO */ + } else if (strcmp(username, "signup") == 0 || + strcmp(username, "new") == 0) { + /* TODO */ + } else { + user = user_find(db, username); + } + + session_output(s, "Password: "); + password = session_field_input(s, 64, '*'); + session_output(s, "\r\n"); - session_output(s, "login: "); - line = session_field_input(s, 50); - session_output(s, "\r\nHi, %s\r\n", line); - free(line); - - for (;;) { - uthread_yield(); + if (user) { + if (user_authenticate(db, user, password) == AUTH_USER_OK) + s->user = user; + } else + /* kill some time */ + SHA256Data((const u_int8_t *)password, strlen(password), junk); + + len = strlen(username); + memset(username, 0, len); + free(username); + + len = strlen(password); + memset(password, 0, len); + free(password); + + if (s->user) + return AUTH_USER_OK; + + uthread_sleep(60); + session_output(s, "Login incorrect\r\n"); } -} + + return AUTH_USER_FAILED; +} --- session.h Tue Nov 30 13:23:40 2021 +++ session.h Sun Dec 5 16:50:30 2021 @@ -47,6 +47,7 @@ struct session { void *cookie; struct node_funcs *node_funcs; struct uthread *uthread; + struct user *user; }; extern struct session **sessions; @@ -57,6 +58,7 @@ void session_idle(struct session *session); char session_input_char(struct session *session); short session_output(struct session *session, const char *format, ...); short session_output_char(struct session *session, const char c); -char *session_field_input(struct session *session, unsigned short len); +char *session_field_input(struct session *session, unsigned short len, + char mask); #endif /* __SESSION_H__ */ --- subtext.h Fri Dec 3 09:58:22 2021 +++ subtext.h Sun Dec 5 22:16:23 2021 @@ -21,16 +21,18 @@ #define PROGRAM_NAME "Subtext" -#define MBAR_ID 128 +#define MBAR_ID 128 -#define APPLE_MENU_ID 128 -#define APPLE_MENU_ABOUT_ID 1 +#define APPLE_MENU_ID 128 +#define APPLE_MENU_ABOUT_ID 1 -#define FILE_MENU_ID 129 -#define FILE_MENU_QUIT_ID 1 +#define FILE_MENU_ID 129 +#define FILE_MENU_QUIT_ID 1 -extern struct db *db; +#define STR_LAST_DB 128 +extern struct db *db; +extern short mainResFile; extern MenuHandle file_menu; #endif /* __SUBTEXT_H__ */ --- user.c Sun Dec 5 16:06:29 2021 +++ user.c Sun Dec 5 20:21:25 2021 @@ -206,7 +206,33 @@ user_parse(struct db *tdb, Handle huser) short user_authenticate(struct db *tdb, struct user *user, char *password) { + char hash[SHA256_DIGEST_STRING_LENGTH]; + char *salted; + unsigned long tmp[8]; + size_t plen, slen; + short n; + unsigned char res; + + plen = strlen(password); + slen = SHA256_DIGEST_STRING_LENGTH - 1 + plen; + salted = xmalloc(slen); + memcpy(salted, user->password_salt, SHA256_DIGEST_STRING_LENGTH - 1); + memcpy(salted + SHA256_DIGEST_STRING_LENGTH - 1, password, plen); + SHA256Data((const u_int8_t *)salted, slen, hash); + + /* timing-safe comparison */ + for (res = 0, n = 0; n < SHA256_DIGEST_STRING_LENGTH; n++) + res |= (hash[n] ^ user->password_hash[n]); + + memset(&hash, 0, sizeof(hash)); + memset(salted, 0, slen); + free(salted); + + if (res == 0) + return AUTH_USER_OK; + + return AUTH_USER_FAILED; } void @@ -216,20 +242,23 @@ user_set_password(struct db *tdb, struct user *user, c char salt[SHA256_DIGEST_STRING_LENGTH]; char *salted; unsigned long tmp[8]; - size_t plen; + size_t plen, slen; short n; + /* make a random salt out of a sha256 of some random longs */ for (n = 0; n < sizeof(tmp); n++) tmp[n] = xorshift32(); SHA256Data((const u_int8_t *)tmp, sizeof(tmp), salt); - memcpy(&user->password_salt, &salt, sizeof(user->password_salt)); - + memcpy(&user->password_salt, &salt, sizeof(salt)); + plen = strlen(password); - salted = xmalloc(plen + sizeof(salt)); - memcpy(salted, salt, sizeof(salt)); - memcpy(salted + sizeof(salt), password, plen); - SHA256Data((const u_int8_t *)salted, plen + sizeof(salt), hash); + slen = plen + sizeof(salt) - 1; + salted = xmalloc(slen); + memcpy(salted, salt, sizeof(salt) - 1); /* exclude null */ + memcpy(salted + sizeof(salt) - 1, password, plen); + SHA256Data((const u_int8_t *)salted, slen, hash); + memset(salted, 0, slen); free(salted); memcpy(&user->password_hash, &hash, sizeof(user->password_hash));