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 9 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);