Пример #1
0
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);
}
Пример #2
0
/* 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;
}
Пример #3
0
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;
}
Пример #4
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;
}
Пример #5
0
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;
}
Пример #6
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;
}
Пример #7
0
	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();
		}
Пример #8
0
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;
}
Пример #9
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;
}
Пример #10
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;
}