static void feed_auparse(llist *l, auparse_callback_ptr callback) { const lnode *n; list_first(l); n = list_get_cur(l); if (!n) { fprintf(stderr, "Error - no elements in record."); return; } au = auparse_init(AUSOURCE_FEED, 0); auparse_set_escape_mode(au, escape_mode); auparse_add_callback(au, callback, NULL, NULL); do { // Records need to be terminated by a newline // Temporarily replace it. if (l->fmt == LF_ENRICHED) n->message[n->mlen] = AUDIT_INTERP_SEPARATOR; n->message[n->tlen] = 0x0a; auparse_feed(au, n->message, n->tlen+1); if (l->fmt == LF_ENRICHED) n->message[n->mlen] = 0; n->message[n->tlen] = 0; } while ((n=list_next(l))); auparse_flush_feed(au); auparse_destroy(au); }
/* Initialize an auparse_state_t with the correct log source. */ auparse_state_t *init_auparse(void) { auparse_state_t *au = NULL; if (stdin_flag) { au = auparse_init(AUSOURCE_FILE_POINTER, stdin); } else if (file) { au = auparse_init(AUSOURCE_FILE, file); } else { if (getuid()) { fprintf(stderr, "You probably need to be root for " "this to work\n"); } au = auparse_init(AUSOURCE_LOGS, NULL); } if (au == NULL) { fprintf(stderr, "Error: %s\n", strerror(errno)); } return au; }
int main(int argc, char *argv[]) { char tmp[MAX_AUDIT_MESSAGE_LENGTH+1]; struct sigaction sa; /* Register sighandlers */ sa.sa_flags = 0; sigemptyset(&sa.sa_mask); /* Set handler for the ones we care about */ sa.sa_handler = term_handler; sigaction(SIGTERM, &sa, NULL); sa.sa_handler = hup_handler; sigaction(SIGHUP, &sa, NULL); /* Initialize the auparse library */ au = auparse_init(AUSOURCE_FEED, 0); if (au == NULL) { printf("audisp-example is exiting due to auparse init errors"); return -1; } auparse_add_callback(au, handle_event, NULL, NULL); do { /* Load configuration */ if (hup) { reload_config(); } /* Now the event loop */ while (fgets_unlocked(tmp, MAX_AUDIT_MESSAGE_LENGTH, stdin) && hup==0 && stop==0) { auparse_feed(au, tmp, strnlen(tmp, MAX_AUDIT_MESSAGE_LENGTH)); } if (feof(stdin)) break; } while (stop == 0); /* Flush any accumulated events from queue */ auparse_flush_feed(au); auparse_destroy(au); if (stop) printf("audisp-example is exiting on stop request\n"); else printf("audisp-example is exiting on stdin EOF\n"); return 0; }
int main(int argc, char *argv[]) { int i, use_stdin = 0; char *user = NULL, *file = NULL; struct passwd *p; auparse_state_t *au; setlocale (LC_ALL, ""); for (i=1; i<argc; i++) { if (argv[i][0] != '-') { //take input and lookup as if it were a user name //if that fails assume its a tty if (user == NULL) { p = getpwnam(argv[i]); if (p) { cuid = p->pw_uid; user = argv[i]; continue; } } if (cterm == NULL) { cterm = argv[i]; } else { usage(); return 1; } } else { if (strcmp(argv[i], "-f") == 0) { if (use_stdin == 0) { i++; file = argv[i]; } else { fprintf(stderr,"stdin already given\n"); return 1; } } else if (strcmp(argv[i], "--bad") == 0) { bad = 1; } else if (strcmp(argv[i], "--proof") == 0) { proof = 1; } else if (strcmp(argv[i], "--extract") == 0) { f = fopen("aulast.log", "wt"); } else if (strcmp(argv[i], "--stdin") == 0) { if (file == NULL) use_stdin = 1; else { fprintf(stderr, "file already given\n"); return 1; } } else if (strcmp(argv[i], "--debug") == 0) { debug = 1; } else { usage(); return 1; } } } list_create(&l); // Search for successful user logins if (file) au = auparse_init(AUSOURCE_FILE, file); else if (use_stdin) au = auparse_init(AUSOURCE_FILE_POINTER, stdin); else { if (getuid()) { fprintf(stderr, "You probably need to be root for this to work\n"); } au = auparse_init(AUSOURCE_LOGS, NULL); } if (au == NULL) { fprintf(stderr, "Error - %s\n", strerror(errno)); goto error_exit_1; } // The theory: iterate though events // 1) when LOGIN is found, create a new session node // 2) if that session number exists, close out the old one // 3) when USER_LOGIN is found, update session node // 4) When USER_END is found update session node and close it out // 5) When BOOT record found make new record and check for previous // 6) If previous boot found, set status to crash and logout everyone // 7) When SHUTDOWN found, close out reboot record while (auparse_next_event(au) > 0) { // We will take advantage of the fact that all events // of interest are one record long int type = auparse_get_type(au); if (type < 0) continue; switch (type) { case AUDIT_LOGIN: create_new_session(au); extract_record(au); break; case AUDIT_USER_LOGIN: update_session_login(au); extract_record(au); break; case AUDIT_USER_END: update_session_logout(au); extract_record(au); break; case AUDIT_SYSTEM_BOOT: process_bootup(au); extract_record(au); break; case AUDIT_SYSTEM_SHUTDOWN: process_shutdown(au); extract_record(au); break; case AUDIT_DAEMON_START: process_kernel(au); extract_record(au); break; } } auparse_destroy(au); // Now output the leftovers list_first(&l); do { lnode *cur = list_get_cur(&l); report_session(cur); } while (list_next(&l)); free(kernel); list_clear(&l); if (f) fclose(f); return 0; error_exit_1: list_clear(&l); if (f) fclose(f); return 1; }
int main(int argc, char *argv[]) { char tmp[MAX_AUDIT_MESSAGE_LENGTH+1]; struct sigaction sa; /* Register sighandlers */ sa.sa_flags = 0; sigemptyset(&sa.sa_mask); /* Set handler for the ones we care about */ sa.sa_handler = term_handler; sigaction(SIGTERM, &sa, NULL); sa.sa_handler = hup_handler; sigaction(SIGHUP, &sa, NULL); /* Initialize the auparse library */ au = auparse_init(AUSOURCE_FEED, 0); if (au == NULL) { printf("audisp-example is exiting due to auparse init errors"); return -1; } auparse_add_callback(au, handle_event, NULL, NULL); do { fd_set read_mask; struct timeval tv; int retval; /* Load configuration */ if (hup) { reload_config(); } do { tv.tv_sec = 5; tv.tv_usec = 0; FD_ZERO(&read_mask); FD_SET(0, &read_mask); if (auparse_feed_has_data(au)) retval= select(1, &read_mask, NULL, NULL, &tv); else retval= select(1, &read_mask, NULL, NULL, NULL); } while (retval == -1 && errno == EINTR && !hup && !stop); /* Now the event loop */ if (!stop && !hup && retval > 0) { if (fgets_unlocked(tmp, MAX_AUDIT_MESSAGE_LENGTH, stdin)) { auparse_feed(au, tmp, strnlen(tmp, MAX_AUDIT_MESSAGE_LENGTH)); } } else if (retval == 0) auparse_flush_feed(au); if (feof(stdin)) break; } while (stop == 0); /* Flush any accumulated events from queue */ auparse_flush_feed(au); auparse_destroy(au); if (stop) printf("audisp-example is exiting on stop request\n"); else printf("audisp-example is exiting on stdin EOF\n"); return 0; }
int main(int argc, char **argv) { int i, c, ret = 0; int n_files; unsigned long n_units = DEFAULT_N_LINES; char forever = 0, mode = M_LINES; char **filenames; //struct file_struct *files = NULL; int event_cnt = 1; /* Set up logging */ openlog("AUDITD_BRO", 0, LOG_USER); au = auparse_init(AUSOURCE_FEED, 0); auparse_add_callback(au, auparse_callback, &event_cnt, NULL); if (au == NULL) { printf("Error - %s\n", strerror(errno)); return 1; } while ((c = getopt_long(argc, argv, "c:n:fvVh", long_opts, NULL)) != -1) { switch (c) { case 'c': mode = M_BYTES; /* fall through */ case 'n': if (*optarg == '+') { from_begin = 1; optarg++; } else if (*optarg == '-') optarg++; if (!is_digit(*optarg)) { fprintf(stderr, "Error: Invalid number of units: %s\n", optarg); exit(EXIT_FAILURE); } n_units = strtoul(optarg, NULL, 0); break; case 'f': forever = 1; break; case 'v': verbose = 1; break; case 'V': fprintf(stdout, "%s %s\n", PROGRAM_NAME, VERSION); exit(EXIT_SUCCESS); case 'h': usage(EXIT_SUCCESS); default: usage(EXIT_FAILURE); } } /* Do we have some files to read from? */ if (optind < argc) { n_files = argc - optind; filenames = argv + optind; } else { /* It must be stdin then */ static char *dummy_stdin = "-"; n_files = 1; filenames = &dummy_stdin; /* POSIX says that -f is ignored if no file operand is specified and standard input is a pipe. */ if (forever) { struct stat finfo; int rc = fstat(STDIN_FILENO, &finfo); if (unlikely(rc == -1)) { fprintf(stderr, "Error: Could not stat stdin (%s)\n", strerror(errno)); exit(EXIT_FAILURE); } if (rc == 0 && IS_PIPELIKE(finfo.st_mode)) forever = 0; } } // end stdin files = emalloc(n_files * sizeof(struct file_struct)); for (i = 0; i < n_files; i++) { files[i].name = filenames[i]; setup_file(&files[i]); ret = tail_file(&files[i], n_units, mode, forever); if (ret < 0) ignore_file(&files[i]); } if (forever) ret = watch_files(files, n_files); free(files); auparse_flush_feed(au); auparse_destroy(au); closelog(); return ret; }
char tmp[MAX_AUDIT_MESSAGE_LENGTH+1]; struct sigaction sa; fd_set rfds; struct timeval tv; /* Register sighandlers */ sa.sa_flags = 0; sigemptyset(&sa.sa_mask); /* Set handler for the ones we care about */ sa.sa_handler = term_handler; sigaction(SIGTERM, &sa, NULL); sa.sa_handler = hup_handler; sigaction(SIGHUP, &sa, NULL); /* Initialize the auparse library */ au = auparse_init(AUSOURCE_FEED, 0); if (au == NULL) { syslog(LOG_ERR,"sedispatch is exiting due to auparse init errors"); return -1; } auparse_add_callback(au, handle_event, NULL, NULL); #ifdef HAVE_LIBCAP_NG capng_clear(CAPNG_SELECT_BOTH); capng_apply(CAPNG_SELECT_BOTH); #endif do { /* Load configuration */ if (hup) { reload_config(); }
int main(int argc, char *argv[]) { int rc; const char *cpath; char buf[1024]; struct sigaction sa; sigset_t ss; auparse_state_t *au; ssize_t len; mypid = getpid(); log_info("starting with pid=%d", mypid); /* * install signal handlers */ sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sa.sa_handler = term_handler; sigaction(SIGTERM, &sa, NULL); sa.sa_handler = hup_handler; sigaction(SIGHUP, &sa, NULL); sa.sa_handler = alarm_handler; sigaction(SIGALRM, &sa, NULL); /* * the main program accepts a single (optional) argument: * it's configuration file (this is NOT the plugin configuration * usually located at /etc/audisp/plugin.d) * We use the default (def_config_file) if no arguments are given */ if (argc == 1) { cpath = def_config_file; log_warn("No configuration file specified - using default (%s)", cpath); } else if (argc == 2) { cpath = argv[1]; log_info("Using configuration file: %s", cpath); } else { log_err("Error - invalid number of parameters passed. Aborting"); return 1; } /* initialize record counter */ conf.counter = 1; /* initialize configuration with default values */ plugin_clear_config(&conf); /* initialize the submission queue */ if (init_queue(conf.q_depth) != 0) { log_err("Error - Can't initialize event queue. Aborting"); return -1; } /* set stdin to O_NONBLOCK */ if (fcntl(0, F_SETFL, O_NONBLOCK) == -1) { log_err("Error - Can't set input to Non-blocking mode: %s. Aborting", strerror(errno)); return -1; } do { hup = 0; /* don't flush unless hup == 1 */ /* * initialization is done in 4 steps: */ /* * load configuration and * increase queue depth if needed */ rc = plugin_load_config(&conf, cpath); if (rc != 0) { log_err("Error - Can't load configuration. Aborting"); return -1; } increase_queue_depth(conf.q_depth); /* 1 */ /* initialize auparse */ au = auparse_init(AUSOURCE_FEED, 0); /* 2 */ /* * Block signals for everyone, * Initialize submission thread, and * Unblock signals for this thread */ sigfillset(&ss); pthread_sigmask(SIG_BLOCK, &ss, NULL); pthread_create(&submission_thread, NULL, submission_thread_main, NULL); pthread_sigmask(SIG_UNBLOCK, &ss, NULL); /* 3 */ /* add our event consumer callback */ auparse_add_callback(au, push_event, NULL, NULL); /* 4 */ /* main loop */ while (hup == 0 && stop == 0) { fd_set rfds; struct timeval tv; FD_ZERO(&rfds); FD_SET(0, &rfds); tv.tv_sec = 5; tv.tv_usec = 0; rc = select(1, &rfds, NULL, NULL, &tv); if (rc == -1) { if (errno == EINTR) { log_debug("Select call interrupted"); continue; } else { log_err("Error - Fatal error while monitoring input: %s. Aborting", strerror(errno)); stop = 1; } } else if (rc) { len = read(0, buf, 1024); if (len > 0) /* let our callback know of the new data */ auparse_feed(au, buf, len); else if (len == 0) { log_debug("End of input - Exiting"); stop = 1; } else { /* ignore interrupted call or empty pipe */ if (errno != EINTR && errno != EAGAIN) { log_err("Error - Fatal error while reading input: %s. Aborting", strerror(errno)); stop = 1; } else { log_debug("Ignoring read interruption: %s", strerror(errno)); } } } } /* flush everything, in order */ auparse_flush_feed(au); /* 4 */ alarm(10); /* 10 seconds to clear the queue */ pthread_join(submission_thread, NULL); /* 3 */ alarm(0); /* cancel any pending alarm */ auparse_destroy(au); /* 2 */ plugin_free_config(&conf); /* 1 */ } while (hup && stop == 0); /* destroy queue before leaving */ destroy_queue(); log_info("Exiting"); return 0; }
int main(int argc, char **argv) { char *filename = NULL; auparse_esc_t em; FILE *fd; #define BUFSZ 2048 char buf[BUFSZ]; size_t len; int *event_cnt = NULL; auparse_state_t *au; int i; /* Argument parsing */ while (1) { int option_index = 0; int c; static struct option long_options[] = { { "verbose", no_argument, 0, 'v'}, { "file", required_argument, 0, 'f'}, { "stdin", no_argument, 0, 's'}, { "check", no_argument, 0, 'c'}, { "escape", required_argument, 0, 'e'}, { 0, 0, 0, 0} }; c = getopt_long(argc, argv, "cvf:e:s", long_options, &option_index); if (c == -1) break; switch (c) { case 'e': /* escape mode */ switch (*optarg) { case 'R': case 'r': em = AUPARSE_ESC_RAW; break; case 'T': case 't': em = AUPARSE_ESC_TTY; break; case 'S': case 's': em = AUPARSE_ESC_SHELL; break; case 'Q': case 'q': em = AUPARSE_ESC_SHELL_QUOTE; break; default: fprintf(stderr, "%s: Unknown escape character 0x%2.2X\n", argv[0], *optarg); usage(); return 1; } auparse_set_escape_mode(NULL, em); break; case 'c': /* check */ flags |= F_CHECK; break; case 'v': /* verbose */ flags |= F_VERBOSE; break; case 's': /* stdin */ flags |= F_USESTDIN; break; case 'f': /* file */ filename = optarg; break; case '?': default: fprintf(stderr, "%s: Unknown option 0x%2.2X\n", argv[0], c); usage(); return 1; } } if ((flags & F_USESTDIN) && filename != NULL) { fprintf(stderr, "%s: --stdin cannot be used with file argument\n", argv[0]); usage(); return 1; } if (!(flags & F_USESTDIN) && filename == NULL) { fprintf(stderr, "%s: Missing --stdin or -f file argument\n", argv[0]); usage(); return 1; } if ((event_cnt = malloc(sizeof(int))) == NULL) { fprintf(stderr, "%s: No memory to allocate %lu bytes\n", argv[0], sizeof(int)); return 1; } if (flags & F_USESTDIN) { fd = stdin; } else { if ((fd = fopen(filename, "r")) == NULL) { fprintf(stderr, "could not open ’%s’, %s\n", filename, strerror(errno)); (void) free(event_cnt); return 1; } } au = auparse_init(AUSOURCE_FEED, NULL); *event_cnt = 1; auparse_add_callback(au, auparse_callback, event_cnt, free); i = 0; while ((len = fread(buf, 1, sizeof(buf), fd))) { auparse_feed(au, buf, len); i++; } auparse_flush_feed(au); auparse_destroy(au); /* this also free's event_cnt */ if (!(flags & F_USESTDIN)) fclose(fd); return 0; }
int main(int argc, char **argv) { /* we're probably going to be started by auditd so, you know, whatever */ /* set up stdin to be searched ruthlessly */ FILE *log; auparse_state_t *auparse; uint32_t syscall; int auid, uid; int wtf; uint32_t _argc, i; const char *exe, *path, *success; char *cmdline, *tmp_cmd; char _argv[8]; struct passwd *au, *u; char *real_user, *apparent_user; _argc = 0; cmdline = NULL; log = fopen("/tmp/exemon.log", "w"); /* auparse = auparse_init(AUSOURCE_LOGS, NULL); */ auparse = auparse_init(AUSOURCE_FILE_POINTER, stdin); if (!auparse) { fprintf(log, "Couldn't do the thing with the thing.\n"); exit(1); } while ((wtf = auparse_next_event(auparse)) > 0) { /* Start fresh */ auid = -1; uid = -1; exe = NULL; path = NULL; success = NULL; _argc = 0; if (cmdline) free(cmdline); cmdline = NULL; /* Now we're doing the thing */ /* auparse_first_field(auparse); */ /* auparse_first_record(auparse); */ auparse_first_field(auparse); if (auparse_find_field(auparse, "syscall")) { syscall = auparse_get_field_int(auparse); if (syscall == 59 || syscall == 11) { if (auparse_exhaustive_find_field(auparse, "auid")) { auid = auparse_get_field_int(auparse); au = getpwuid(auid); if (au) real_user = strdup(au->pw_name); else asprintf(&real_user, "UID_%i", auid); au = NULL; } if (auparse_exhaustive_find_field(auparse, "uid")) { uid = auparse_get_field_int(auparse); u = getpwuid(uid); if (u) apparent_user = strdup(u->pw_name); else asprintf(&apparent_user, "UID_%i", uid); u = NULL; } if (auparse_exhaustive_find_field(auparse, "success")) success = auparse_get_field_str(auparse); if (auparse_exhaustive_find_field(auparse, "exe")) exe = auparse_get_field_str(auparse); if (auparse_exhaustive_find_field(auparse, "argc")) { _argc = auparse_get_field_int(auparse); for (i = 0; i < _argc; i++) { snprintf(_argv, 8, "a%i", i); if (auparse_find_field(auparse, _argv)) { if (!cmdline) asprintf(&cmdline, "%s", auparse_interpret_field(auparse)); else { asprintf(&tmp_cmd, "%s %s", cmdline, auparse_interpret_field(auparse)); free(cmdline); /* avoid leaking cmdline */ cmdline = tmp_cmd; } } } } if (auparse_exhaustive_find_field(auparse, "cwd")) path = auparse_get_field_str(auparse); else path = strdup("(unknown)"); if (exe && uid >= 0 && path && success) { if (auid == uid || auid == -1) { if (cmdline && (success[0] == 'y' || success[0] == 'Y')) { fprintf(log, "%s ran %s in path %s with args: %s\n", apparent_user, exe, path, cmdline); } else { fprintf(log, "%s failed to run %s in path %s\n", apparent_user, exe, path); if (!cmdline) { fprintf(log, "note: no cmdline: record: \n"); auparse_dump_records(auparse, log); } } } else { if (cmdline && (success[0] == 'y' || success[0] == 'Y')) { fprintf(log, "%s (as %s) ran %s in path %s with args: %s\n", real_user, apparent_user, exe, path, cmdline); } else { fprintf(log, "%s (as %s) failed to run %s in path %s\n", real_user, apparent_user, exe, path); } } } else { fprintf(log, "Incomplete record? path = %x, success = %x, uid = %i, exe = %x\n", path, success, uid, exe); fprintf(log, "record:\n"); auparse_dump_records(auparse, log); } fflush(log); /* avoid leaking on usernames and unknown paths */ free(apparent_user); free(real_user); if (path[0] == '(') { free(path); path = NULL; } apparent_user = NULL; real_user = NULL; } } } fprintf(log, "destroyed\n"); fclose(log); auparse_destroy(auparse); return 0; }