AmendHub

jcs

/

subtext

/

amendments

/

137

session: Close on banned username login attempt, track logged-in status

Ignore sessions that haven't logged in yet, and don't show guest
username in 'who' and logs.
Also show whether a user is a sysop in 'who'.

jcs made amendment 137 5 months ago
--- session.c Sun Jun 12 09:38:55 2022 +++ session.c Sun Jun 12 12:06:51 2022 @@ -113,6 +113,8 @@ session_run(struct uthread *uthread, void *arg) return; } + s->logged_in = 1; + /* update session log */ if (s->user) { s->user->last_seen_at = Time; @@ -341,7 +343,9 @@ session_log(struct session *session, const char *forma va_end(ap); return logger_printf(logger, "[%s] [%s] %s", session->node, - session->user ? session->user->username : "guest", session_log_tbuf); + session->logged_in ? + (session->user ? session->user->username : "guest") : "-", + session_log_tbuf); } size_t @@ -756,6 +760,12 @@ session_login(struct session *s) return AUTH_USER_SIGNUP; } else { user = user_find_by_username(username); + + if (!user && user_username_is_banned(username)) { + session_log(s, "Attempted login as banned username %s", + username); + return AUTH_USER_FAILED; + } } if (s->autologin_username[0]) { @@ -1198,6 +1208,7 @@ void session_who(struct session *s) { char idle_s[20]; + char username[20]; unsigned long idle; short n; @@ -1207,7 +1218,7 @@ session_who(struct session *s) session_flush(s); for (n = 0; n < MAX_SESSIONS; n++) { - if (sessions[n] == NULL) + if (sessions[n] == NULL || !sessions[n]->logged_in) continue; idle = Time - sessions[n]->last_input_at; @@ -1220,9 +1231,13 @@ session_who(struct session *s) else sprintf(idle_s, "%ldd", idle / (60 * 60 * 24)); + snprintf(username, sizeof(username), "%s%s", + sessions[n]->user ? sessions[n]->user->username : GUEST_USERNAME, + sessions[n]->user && sessions[n]->user->is_sysop ? " (sysop)" : ""); + session_printf(s, "%-7s %-20s %-7s %-6d %-6s\r\n", sessions[n]->node, - sessions[n]->user ? sessions[n]->user->username : GUEST_USERNAME, + username, sessions[n]->via, sessions[n]->tspeed, idle_s); --- session.h Sun Jun 12 09:24:34 2022 +++ session.h Sun Jun 12 11:45:43 2022 @@ -89,6 +89,7 @@ struct session { unsigned char chatting; unsigned char chatting_with_node[10]; unsigned char chat_ring_idx; + unsigned char logged_in; struct session_log log; char autologin_username[DB_USERNAME_LENGTH + 1]; struct user *user; --- telnet.c Wed Jun 1 13:10:41 2022 +++ telnet.c Sun Jun 12 08:41:43 2022 @@ -280,10 +280,7 @@ telnet_input(struct session *session) unsigned char c; char iac_out[8] = { IAC, 0 }; - if (session->ending) - return 0; - - if (node->ibuflen >= sizeof(node->ibuf)) + if (session->ending || node->ibuflen >= sizeof(node->ibuf)) return 0; if (node->rcv_pb.ioResult > 0) --- user.c Wed Jun 8 10:39:02 2022 +++ user.c Sun Jun 12 10:38:54 2022 @@ -213,19 +213,17 @@ user_set_password(struct user *user, const char *passw memset(&salt, 0, sizeof(salt)); } -short +bool user_valid_username(struct user *user, char *username, char **error) { - char *lower = NULL; struct user *ouser; unsigned long ouser_id; size_t len, n; char c; - short ret = 0; if (username == NULL) { *error = xstrdup("username cannot be empty"); - goto done; + return false; } len = strlen(username); @@ -233,11 +231,9 @@ user_valid_username(struct user *user, char *username, *error = xmalloc(61); snprintf(*error, 60, "username cannot be more than %d characters", DB_USERNAME_LENGTH); - goto done; + return false; } - lower = xmalloc(len + 1); - for (n = 0; n < len; n++) { c = username[n]; @@ -245,25 +241,19 @@ user_valid_username(struct user *user, char *username, (c >= 'a' && c <= 'z') || c == '_')) { *error = xstrdup("username cannot contain non-alphanumeric " "characters"); - goto done; + return false; } - - lower[n] = tolower(username[n]); } - lower[len] = '\0'; - if (strcmp(GUEST_USERNAME, lower) == 0) { + if (strcasecmp(username, GUEST_USERNAME) == 0) { *error = xstrdup("username is already in use"); - goto done; + return false; } - if (!(user != NULL && user->is_sysop)) { - for (n = 0; n < nitems(BANNED_USERNAMES); n++) { - if (strcmp(lower, BANNED_USERNAMES[n]) == 0) { - *error = xstrdup("username is not permitted"); - goto done; - } - } + if (!(user != NULL && user->is_sysop) && + user_username_is_banned(username)) { + *error = xstrdup("username is not permitted"); + return false; } if ((ouser = user_find_by_username(username))) { @@ -272,16 +262,24 @@ user_valid_username(struct user *user, char *username, if (user == NULL || ouser_id != user->id) { *error = xstrdup("username is already in use"); - goto done; + return false; } } - ret = 1; + return true; +} + +bool +user_username_is_banned(char *username) +{ + size_t n; -done: - if (lower != NULL) - free(lower); - return ret; + for (n = 0; n < nitems(BANNED_USERNAMES); n++) { + if (strcasecmp(username, BANNED_USERNAMES[n]) == 0) + return true; + } + + return false; } char * --- user.h Wed Jun 8 10:38:23 2022 +++ user.h Sun Jun 12 10:39:41 2022 @@ -49,7 +49,8 @@ struct user * user_find_by_username(const char *userna struct username_cache * user_find_username(unsigned long id); short user_authenticate(struct user *user, const char *password); void user_set_password(struct user *user, const char *password); -short user_valid_username(struct user *user, char *username, char **error); +bool user_valid_username(struct user *user, char *username, char **error); +bool user_username_is_banned(char *username); char * user_first_sysop_username(void); void user_change_password(struct session *s, struct user *user); void user_delete(struct user *user);