B4BY.588
Home
Terminal
Upload
information
Create File
Create Folder
About
Tools
:
/
disk1
/
worms
/
padel
/
2026may20
/
gsocket
/
tools
/
Filename :
ids.c
back
Copy
/* * For GS-NETCAT. * * Monitor various aspect of the system (such as new user login * and idle time of users). */ #include "common.h" #include "pkt_mgr.h" #include "utils.h" struct utmp_db_user { char user[UT_NAMESIZE]; char msg[128]; int idle; int idle_old; int token; }; GS_LIST udb; static int is_udb_init; // Bloody __OpenBSD__, does not have utmpx.h #ifndef HAVE_UTMPX_H # if !defined(__OpenBSD__) # error "Which forsaken OS (beside OpenBSD) does not have utmpx.h?" # endif # ifndef UT_NAMESIZE # define UT_NAMESIZE (32) # endif # ifndef UT_LINESIZE # define UT_LINESIZE (8) # endif # ifndef UT_HOSTSIZE # define UT_HOSTSIZE (256) # endif # ifndef USER_PROCESS # define USER_PROCESS (0) # endif // FIXME: Implement non utmpx support (only OpenBSD still uses good old utmp?) struct utmpx { int ut_type; char ut_line[UT_LINESIZE]; char ut_user[UT_NAMESIZE]; char ut_host[UT_HOSTSIZE]; time_t ut_time; }; void setutxent(void){ } // DUMMY void endutxent(void){ } // DUMMY void *getutxent(void){ return NULL; } // DUMMY #endif static int utmp_db_find(const char *needle, struct utmp_db_user **uret) { GS_LIST_ITEM *li = NULL; while (1) { li = GS_LIST_next(&udb, li); if (li == NULL) break; struct utmp_db_user *u = (struct utmp_db_user *)li->data; if (strcmp(u->user, needle) != 0) continue; // User Name matches the needle *uret = u; return 0; } *uret = NULL; return -1; // User Name not found } static struct utmp_db_user * utmp_db_add(const char *user, int idle, int token) { struct utmp_db_user *new; DEBUGF_C("Adding new user %s with idle %d\n", user, idle); new = malloc(sizeof *new); new->idle = idle; new->idle_old = 0; new->token = token; snprintf(new->user, sizeof new->user, "%s", user); GS_LIST_add(&udb, NULL, new, new->idle); return new; } /* */ void GS_IDS_utmp_free(void) { GS_LIST_ITEM *li = NULL; while (1) { li = GS_LIST_next(&udb, NULL); if (li == NULL) break; XFREE(li->data); GS_LIST_del(li); } is_udb_init = 0; } // When to consider a user transitioning from IDLE to not IDLE #ifdef DEBUG #define IDLE_THRESHOLD (10) #else #define IDLE_THRESHOLD (60 * 60) // 1h #endif /* * Call every second. * Compare DB from memory with utmp file. * * Find any new user. * Find any known user that is no longer idle. * Find least idle user. */ void GS_IDS_utmp(GS_LIST *new_login, GS_LIST *new_active, char **least_idle, int *sec_idle, int *n_users) { struct utmpx *ut; int idle; int ret; struct stat s; char buf[MAX(UT_NAMESIZE, 128)]; int token = gopt.tv_now.tv_sec; if (is_udb_init == 0) { GS_LIST_init(&udb, 0); } *least_idle = NULL; *sec_idle = INT_MAX; gettimeofday(&gopt.tv_now, NULL); setutxent(); while ((ut = getutxent()) != NULL) { if (ut->ut_type != USER_PROCESS) continue; ut->ut_user[UT_NAMESIZE - 1] = 0x00; // be sure for strcmp... // Get idle time of the user's tty snprintf(buf, sizeof buf, "/dev/%s", ut->ut_line); stat(buf, &s); idle = MAX(0, gopt.tv_now.tv_sec - s.st_atime); struct utmp_db_user *u; snprintf(buf, sizeof buf, "%s", ut->ut_user); // -Wstringop-overflow ret = utmp_db_find(buf, &u); if (ret != 0) { // NOT found. Add user. u = utmp_db_add(ut->ut_user, idle, token); if (is_udb_init != 0) { snprintf(u->msg, sizeof u->msg, "%.20s [%.20s]", ut->ut_user, ut->ut_host[0]?ut->ut_host:"console"); DEBUGF("New Login detected '%s'\n", u->msg); GS_LIST_add(new_login, NULL, u->msg, 0); } } else { // Update idle if this is a new run over utmp. // Otherwise u->idle will never get larger when user // idles. Slower method would be to set all records // u->idle to INT_MAX before while loop. if (u->token != token) { u->token = token; u->idle = idle; } // Update current user's idle if lower. if (idle < u->idle) { // DEBUGF_W("Updating idle to %d of user %s\n", idle, u->user); u->idle = idle; } } XASSERT(u != NULL, "utmp entry is NULL\n"); if (idle > *sec_idle) continue; // HERE: least idle user (so far) *sec_idle = idle; *least_idle = u->user; } endutxent(); if (is_udb_init == 0) goto done; // Check which user has awoken (from IDLE to NOT IDLE) GS_LIST_ITEM *li = NULL; li = GS_LIST_next(&udb, NULL); while (li != NULL) { if (li == NULL) break; struct utmp_db_user *u = (struct utmp_db_user *)li->data; if (u->token != token) { // User in db is no longer in utmp. Remove from db. DEBUGF("Removing DB user %s\n", u->user); GS_LIST_ITEM *next = GS_LIST_next(&udb, li); XFREE(li->data); GS_LIST_del(li); li = next; continue; } if ((u->idle_old >= IDLE_THRESHOLD) && (u->idle < u->idle_old)) { snprintf(u->msg, sizeof u->msg, "%.20s [idled for %d mins]", u->user, u->idle_old / 60); GS_LIST_add(new_active, NULL, u->msg, 0); DEBUGF_R("Now ACTIVE (was %d, now %d): '%s'\n", u->idle_old, u->idle, u->msg); } u->idle_old = u->idle; li = GS_LIST_next(&udb, li); } done: *n_users = udb.n_items; is_udb_init = 1; } static void add_log_str(struct _peer *p, uint8_t type, const char *str) { struct _pkt_app_log *log = malloc(sizeof *log); log->type = type; snprintf((char *)log->msg, sizeof log->msg, "%.62s", str); GS_LIST_add(&p->logs, NULL, log, GS_LIST_ID_COUNT(&p->logs)); p->is_pending_logs = 1; GS_SELECT_FD_SET_W(p->gs); } /* * Report to any other connected GS-PEER (that is requesting IDS info) * that a new GS user has logged in via gs-netcat. */ void ids_gs_login(struct _peer *self_peer) { GS_LIST_ITEM *li = NULL; struct _peer *other_peer; while (1) { li = GS_LIST_next(&gopt.ids_peers, li); if (li == NULL) break; other_peer = (struct _peer *)li->data; if (self_peer == other_peer) continue; // Do not send to myself char buf[128]; snprintf(buf, sizeof buf, "[%d] GS login detected. Total Users: %d.", self_peer->id, gopt.peer_count); add_log_str(other_peer, GS_PKT_APP_LOG_TYPE_INFO /*green*/, buf); } } void ids_gs_logout(struct _peer *self_peer) { GS_LIST_ITEM *li = NULL; struct _peer *other_peer; while (1) { li = GS_LIST_next(&gopt.ids_peers, li); if (li == NULL) break; other_peer = (struct _peer *)li->data; if (self_peer == other_peer) continue; // Do not send to myself char buf[128]; snprintf(buf, sizeof buf, "[%d] GS logout detected. Remaining Users: %d%s.", self_peer->id, gopt.peer_count - 1, (gopt.peer_count-1)==1?" {you}":""); add_log_str(other_peer, GS_PKT_APP_LOG_TYPE_NOTICE /*yellow*/, buf); } }