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);
}
Example #2
0
static void process_bootup(auparse_state_t *au)
{
	lnode *cur;
	int start;

	// See if we have unclosed boot up and make into CRASH record
	list_first(&l);
	cur = list_get_cur(&l);
	while (cur) {
		if (cur->name) {
			cur->user_end_proof = auparse_get_serial(au);
			cur->status = CRASH;
			cur->end = auparse_get_time(au);
			report_session(cur);
		}
		cur = list_next(&l);
	}

	// Logout and process anyone still left in the machine
	list_first(&l);
	cur = list_get_cur(&l);
	while (cur) {
		if (cur->status != CRASH) {
			cur->user_end_proof = auparse_get_serial(au);
			cur->status = DOWN;
			cur->end = auparse_get_time(au);
			report_session(cur);
		}
		cur = list_next(&l);
	}

	// Since this is a boot message, all old entries should be gone
	list_clear(&l);
	list_create(&l);

	// make reboot record - user:reboot, tty:system boot, host: kernel 
	start = auparse_get_time(au);
	list_create_session(&l, 0, 0, 0, auparse_get_serial(au));
	cur = list_get_cur(&l);
	cur->start = start;
	cur->name = strdup("reboot");
	cur->term = strdup("system boot");
	if (kernel)
		cur->host = strdup(kernel);
	cur->result = 0;
}
Example #3
0
static void process_bootup(auparse_state_t *au)
{
    lnode *cur;
    int start;
    struct utsname ubuf;

    // See if we have unclosed boot up and make into CRASH record
    list_first(&l);
    cur = list_get_cur(&l);
    while(cur) {
        if (cur->name) {
            cur->user_end_proof = auparse_get_serial(au);
            cur->status = CRASH;
            cur->end = auparse_get_time(au);
            report_session(cur);
        }
        cur = list_next(&l);
    }

    // Logout and process anyone still left in the machine
    list_first(&l);
    cur = list_get_cur(&l);
    while(cur) {
        if (cur->status != CRASH) {
            cur->user_end_proof = auparse_get_serial(au);
            cur->status = DOWN;
            cur->end = auparse_get_time(au);
            report_session(cur);
        }
        cur = list_next(&l);
    }
    list_clear(&l);
    list_create(&l);

    // make reboot record - user:reboot, tty:system boot, host: uname -r
    uname(&ubuf);
    start = auparse_get_time(au);
    list_create_session(&l, 0, 0, 0, auparse_get_serial(au));
    cur = list_get_cur(&l);
    cur->start = start;
    cur->name = strdup("reboot");
    cur->term = strdup("system boot");
    cur->host = strdup(ubuf.release);
    cur->result = 0;
}
Example #4
0
/* This function will output the record as is */
static void output_raw(llist *l)
{
	const lnode *n;

	list_first(l);
	n = list_get_cur(l);
	if (!n) {
		fprintf(stderr, "Error - no elements in record.");
		return;
	}
	do {
		printf("%s\n", n->message);
	} while ((n=list_next(l)));
}
Example #5
0
static void report_finding(struct result_info *res, llist *l, probe_ctx *ctx)
{
        SEXP_t *item;
        SEXP_t se_lport_mem, se_rport_mem, se_lfull_mem, se_ffull_mem, *se_uid_mem = NULL;
	lnode *n = NULL;

	if (l) {
		n = list_get_cur(l);
	}

	if (n) {
                item = probe_item_create(OVAL_LINUX_INET_LISTENING_SERVER, NULL,
                                 "protocol",             OVAL_DATATYPE_STRING,  res->proto,
                                 "local_address",        OVAL_DATATYPE_STRING,  res->laddr,
				 "local_port",           OVAL_DATATYPE_SEXP, SEXP_number_newu_64_r(&se_lport_mem, res->lport),
                                 "local_full_address",   OVAL_DATATYPE_SEXP,    SEXP_string_newf_r(&se_lfull_mem,
                                                                                                   "%s:%u", res->laddr, res->lport),
                                 "program_name",         OVAL_DATATYPE_STRING,  n->cmd,
                                 "foreign_address",      OVAL_DATATYPE_STRING,  res->raddr,
				 "foreign_port",         OVAL_DATATYPE_SEXP, SEXP_number_newu_64_r(&se_rport_mem, res->rport),
                                 "foreign_full_address", OVAL_DATATYPE_SEXP,    SEXP_string_newf_r(&se_ffull_mem,
                                                                                                   "%s:%u", res->raddr, res->rport),
                                 "pid",                  OVAL_DATATYPE_INTEGER, (int64_t)n->pid,
				 "user_id",              OVAL_DATATYPE_SEXP, se_uid_mem = SEXP_number_newu_64(n->uid),
                                 NULL);
	} else {
                item = probe_item_create(OVAL_LINUX_INET_LISTENING_SERVER, NULL,
                                 "protocol",             OVAL_DATATYPE_STRING,  res->proto,
                                 "local_address",        OVAL_DATATYPE_STRING,  res->laddr,
				 "local_port",           OVAL_DATATYPE_SEXP, SEXP_number_newu_64_r(&se_lport_mem, res->lport),
                                 "local_full_address",   OVAL_DATATYPE_SEXP,    SEXP_string_newf_r(&se_lfull_mem,
                                                                                                   "%s:%u", res->laddr, res->lport),
                                 "foreign_address",      OVAL_DATATYPE_STRING,  res->raddr,
				 "foreign_port",         OVAL_DATATYPE_SEXP, SEXP_number_newu_64_r(&se_rport_mem, res->rport),
                                 "foreign_full_address", OVAL_DATATYPE_SEXP,    SEXP_string_newf_r(&se_ffull_mem,
                                                                                                   "%s:%u", res->raddr, res->rport),
                                 NULL);
	}

        probe_item_collect(ctx, item);

        SEXP_free_r(&se_lport_mem);
        SEXP_free_r(&se_rport_mem);
        SEXP_free_r(&se_lfull_mem);
        SEXP_free_r(&se_ffull_mem);
        SEXP_free(se_uid_mem);
}
/* This function will output the record as is */
static void output_raw(llist *l)
{
	const lnode *n;

	list_first(l);
	n = list_get_cur(l);
	if (!n) {
		fprintf(stderr, "Error - no elements in record.");
		return;
	}
	do {
		// Only add the separator for enriched events.
		if (l->fmt == LF_ENRICHED)
			n->message[n->mlen] = AUDIT_INTERP_SEPARATOR;
		puts(n->message);
	} while ((n=list_next(l)));
}
Example #7
0
/*
 * This function will take the linked list and format it for output. No
 * interpretation is performed. The output order is lifo for everything.
 */
static void output_default(llist *l)
{
	const lnode *n;

	list_last(l);
	n = list_get_cur(l);
	printf("----\ntime->%s", ctime(&l->e.sec));
	if (!n) {
		fprintf(stderr, "Error - no elements in record.");
		return;
	}
	if (n->type >= AUDIT_DAEMON_START && n->type < AUDIT_SYSCALL) 
		printf("%s\n", n->message);
	else {
		do {
			printf("%s\n", n->message);
		} while ((n=list_prev(l)));
	}
}
Example #8
0
/*
 * This function will take the linked list and format it for output. 
 * Interpretation is performed to aid understanding of records. The output
 * order is lifo for everything.
 */
static void output_interpreted(llist *l)
{
	const lnode *n;

	list_last(l);
	n = list_get_cur(l);
	printf("----\n");
	if (!n) {
		fprintf(stderr, "Error - no elements in record.");
		return;
	}
	if (n->type >= AUDIT_DAEMON_START && n->type < AUDIT_SYSCALL) 
		output_interpreted_node(n);
	else {
		do {
			output_interpreted_node(n);
		} while ((n=list_prev(l)));
	}
}
Example #9
0
static void process_shutdown(auparse_state_t *au)
{
	lnode *cur;

	// Find reboot record
	list_first(&l);
	cur = list_get_cur(&l);
	while (cur) {
		if (cur->name) {
			// Found it - close it out and display it
			time_t end = auparse_get_time(au);
			list_update_logout(&l, end, auparse_get_serial(au));
			report_session(cur);
			list_delete_cur(&l);
			return;
		}
		cur = list_next(&l);
	}
}
/*
 * This function will take the linked list and format it for output. No
 * interpretation is performed. The output order is lifo for everything.
 */
static void output_default(llist *l)
{
	const lnode *n;

	list_last(l);
	n = list_get_cur(l);
	printf("----\ntime->%s", ctime(&l->e.sec));
	if (!n) {
		fprintf(stderr, "Error - no elements in record.");
		return;
	}
	if (n->type >= AUDIT_DAEMON_START && n->type < AUDIT_SYSCALL)
		puts(n->message); // No injection possible
	else {
		do {
			safe_print_string_n(n->message, n->mlen, 1);
		} while ((n=list_prev(l)));
	}
}
Example #11
0
static void report_finding(struct result_info *res, llist *l, probe_ctx *ctx, oval_schema_version_t over)
{
        SEXP_t *item, *user_id;
	lnode *n = list_get_cur(l);

	if (oval_schema_version_cmp(over, OVAL_SCHEMA_VERSION(5.10)) < 0)
		user_id = SEXP_string_newf("%d", n->uid);
	else
		user_id = SEXP_number_newi_64((int64_t)n->uid);

	item = probe_item_create(OVAL_LINUX_IFLISTENERS, NULL,
                                 "interface_name",       OVAL_DATATYPE_STRING,  res->interface_name,
                                 "protocol",             OVAL_DATATYPE_STRING,  res->protocol,
                                 "hw_address",           OVAL_DATATYPE_STRING,  res->hw_address,
                                 "program_name",         OVAL_DATATYPE_STRING,  n->cmd,
                                 "pid",                  OVAL_DATATYPE_INTEGER, (int64_t)n->pid,
				 "user_id",              OVAL_DATATYPE_SEXP, user_id,
                                 NULL);

        probe_item_collect(ctx, item);
	SEXP_free(user_id);

}
Example #12
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;
}
Example #13
0
int match(llist *l)
{
	// Are we within time range?
	if (start_time == 0 || l->e.sec >= start_time) {
		if (end_time == 0 || l->e.sec <= end_time) {
			if (event_id == -1 || event_id == l->e.serial) {
				// OK - do the heavier checking
				if (extract_search_items(l)) {
					return 0;
				}

				// perform additional tests for the field
				if (event_node_list) {
					const snode *sn;
					int found=0;
					slist *sptr = event_node_list;

					if (l->e.node == NULL)
				  		return 0;

					slist_first(sptr);
					sn=slist_get_cur(sptr);
					while (sn && !found) {
						if (sn->str &&  (!strcmp(sn->str, l->e.node)))
							found++;
						else
							sn=slist_next(sptr);
					}
					if (!found)
						return 0;
				}
				if (user_match(l) == 0)
					return 0;
				if (group_match(l) == 0)
					return 0;
				if ((event_ppid != -1) && 
						(event_ppid != l->s.ppid))
					return 0;
				if ((event_pid != -1) && 
						(event_pid != l->s.pid))
					return 0;
				if (event_machine != -1 && 
						(event_machine !=
					audit_elf_to_machine(l->s.arch)))
					return 0;
				if ((event_syscall != -1) && 
					(event_syscall != l->s.syscall))
						return 0;
				if ((event_session_id != -2) &&
					(event_session_id != l->s.session_id))
					return 0;
				if (event_exit_is_set) {
					if (l->s.exit_is_set == 0)
						return 0;
					if (event_exit != l->s.exit)
						return 0;
				}

				if ((event_success != S_UNSET) &&
						(event_success != l->s.success))
					return 0;
				// event_type requires looking at each item
				if (event_type != NULL) {
					int found = 0;
					const lnode *n;

					list_first(l);
					n = list_get_cur(l);
					do {
						int_node *in;
						ilist_first(event_type);
						in = ilist_get_cur(event_type);
						do {
							if (in->num == n->type){
								found = 1;
								break;
							}
						} while((in = 
						    ilist_next(event_type)));
						if (found)
							break;
					} while ((n = list_next(l)));
					if (!found)
						return 0;
				}

				// Done all the easy compares, now do the 
				// string searches.
				if (event_filename) {
					int found = 0;
					if (l->s.filename == NULL && l->s.cwd == NULL)
						return 0;
					if (l->s.filename) {
						const snode *sn;
						slist *sptr = l->s.filename;

						slist_first(sptr);
						sn=slist_get_cur(sptr);
						do {
							if (sn->str == NULL)
								return 0;
							if (strmatch(
								event_filename,
								sn->str)) {
								found = 1;
								break;
							}
						} while ((sn=slist_next(sptr)));

						if (!found && l->s.cwd == NULL)
							return 0;
					}
					if (l->s.cwd && !found) {
						/* Check cwd, too */
						if (strmatch(event_filename,
								l->s.cwd) == 0)
							return 0;
					}
				}
				if (event_hostname) {
					if (l->s.hostname == NULL)
						return 0;
					if (strmatch(event_hostname, 
						l->s.hostname) == 0)
						return 0; 
				}
				if (event_terminal) {
					if (l->s.terminal == NULL)
						return 0;
					if (strmatch(event_terminal, 
						l->s.terminal) == 0)
						return 0; 
				}
				if (event_exe) {
					if (l->s.exe == NULL)
						return 0;
					if (strmatch(event_exe, 
						l->s.exe) == 0)
						return 0; 
				}				
				if (event_comm) {
					if (l->s.comm == NULL)
						return 0;
					if (strmatch(event_comm, 
						l->s.comm) == 0)
						return 0; 
				}				
				if (event_key) {
					if (l->s.key == NULL)
						return 0;
					else {
						int found = 0;
						const snode *sn;
						slist *sptr = l->s.key;

						slist_first(sptr);
						sn=slist_get_cur(sptr);
						do {
							if (sn->str == NULL)
								return 0;
							if (strmatch(
								event_key,
								sn->str)) {
								found = 1;
								break;
							}
						} while ((sn=slist_next(sptr)));
						if (!found)
							return 0;
					}
				}				
				if (event_vmname) {
					if (l->s.vmname == NULL)
						return 0;
					if (strmatch(event_vmname,
							l->s.vmname) == 0)
						return 0;
				}
				if (event_uuid) {
					if (l->s.uuid == NULL)
						return 0;
					if (strmatch(event_uuid,
							l->s.uuid) == 0)
						return 0;
				}
				if (context_match(l) == 0)
					return 0;
				return 1;
			}
		}
	}
	return 0;
}