Пример #1
0
// Returns < 0 on error, 0 no data, > 0 success
int ausearch_next_event(auparse_state_t *au)
{
	int rc;

	if (au->expr == NULL) {
		errno = EINVAL;
		return -1;
	}
	if (au->expr->started == 0) {
		if ((rc = auparse_first_record(au)) <= 0)
			return rc;
		au->expr->started = 1;
	} else {
		if ((rc = auparse_next_event(au)) <= 0)
			return rc;
	}
        do {
		do {
			if ((rc = ausearch_compare(au)) > 0) {
				ausearch_reposition_cursors(au);
				return 1;
			} else if (rc < 0)
				return rc;
               	} while ((rc = auparse_next_record(au)) > 0);
		if (rc < 0)
			return rc;
        } while ((rc = auparse_next_event(au)) > 0);
	if (rc < 0)
		return rc;
	
	return 0;
}
Пример #2
0
/* Functions that traverse records in the same event */
int auparse_first_record(auparse_state_t *au)
{
	int rc;
	rnode *r;

	// Its OK if au->le == NULL because get_cnt handles it
	if (aup_list_get_cnt(au->le) == 0) {
		// This function loads interpretations
		rc = auparse_next_event(au);
		if (rc <= 0)
			return rc;
	}
	aup_list_first(au->le);
	r = aup_list_get_cur(au->le);
	free_interpretation_list();
	load_interpretation_list(r->interp);
	aup_list_first_field(au->le);
	
	return 1;
}
Пример #3
0
static void consume_feed(auparse_state_t *au, int flush)
{
	//if (debug) printf("consume feed, flush %d\n", flush);
	while (auparse_next_event(au) > 0) {
		if (au->callback) {
			(*au->callback)(au, AUPARSE_CB_EVENT_READY,
					au->callback_user_data);
		}
	}
	if (flush) {
		// FIXME: might need a call here to force auparse_next_event()
		// to consume any partial data not fully consumed.

		/* Terminate all outstanding events, as we are at end of input
		 * (ie mark BUILDING events as COMPLETE events) then if we
		 * have a callback execute the callback on each event
		 * FIXME: Should we implement a 'checkpoint' concept as per
		 * ausearch or accept these 'partial' events?
		 */
		event_list_t	*l;

		//if (debug) printf("terminate all events in flush\n");
		au_terminate_all_events(au);
		while ((l = au_get_ready_event(au, 0)) != NULL) {
			rnode *r;
			au->le = l;  // make this current the event of interest
			aup_list_first(l);
			r = aup_list_get_cur(l);
			free_interpretation_list();
			load_interpretation_list(r->interp);
			aup_list_first_field(l);

			if (au->callback) {
				(*au->callback)(au, AUPARSE_CB_EVENT_READY,
					au->callback_user_data);
			}
		}
	}
}
Пример #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)
{
	int rc = 0;
	auparse_state_t *au = NULL;

	setlocale(LC_ALL, "");
	if (parse_args(argc, argv))
		goto error;
	if (help_flag) {
		usage(stdout);
		goto exit;
	}

	/* Initialize event list*/
	events = list_new((list_free_data_fn*) event_free);
	if (events == NULL)
		goto unexpected_error;

	/* Initialize auparse */
	au = init_auparse();
	if (au == NULL)
		goto error;
	if (create_search_criteria(au))
		goto error;

	while (ausearch_next_event(au) > 0) {
		int err = 0;

		switch(auparse_get_type(au)) {
		case AUDIT_VIRT_MACHINE_ID:
			err = process_machine_id_event(au);
			break;
		case AUDIT_VIRT_CONTROL:
			err = process_control_event(au);
			break;
		case AUDIT_VIRT_RESOURCE:
			err = process_resource_event(au);
			break;
		case AUDIT_AVC:
			err = process_avc(au);
			break;
		case AUDIT_FIRST_ANOM_MSG ... AUDIT_LAST_ANOM_MSG:
		case AUDIT_FIRST_KERN_ANOM_MSG ... AUDIT_LAST_KERN_ANOM_MSG:
			err = process_anom(au);
			break;
		case AUDIT_SYSTEM_SHUTDOWN:
			err = process_shutdown(au);
			break;
		}
		if (err) {
			goto unexpected_error;
		}
		auparse_next_event(au);
	}

	/* Show results */
	if (summary_flag) {
		print_summary();
	} else {
		print_events();
	}

	/* success */
	goto exit;

unexpected_error:
	fprintf(stderr, "Unexpected error\n");
error:
	rc = 1;
exit:
	if (au)
		auparse_destroy(au);
	list_free(events);
	if (debug)
		fprintf(stdout, "Exit code: %d\n", rc);
	return rc;
}
Пример #6
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;
}