2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-30 22:05:27 +00:00

- Converted to using libapparmor

- Now it will send out all known information about an event in a
  somewhat structured way.
This commit is contained in:
Matt Barringer
2007-07-29 05:30:51 +00:00
parent 85eecb0dae
commit d53da59344
8 changed files with 2835 additions and 1964 deletions

View File

@@ -93,6 +93,7 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -116,8 +117,6 @@ SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_STRIP = @ac_ct_STRIP@
ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__include = @am__include@
@@ -128,19 +127,26 @@ am__untar = @am__untar@
bindir = @bindir@
build_alias = @build_alias@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host_alias = @host_alias@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@

View File

@@ -4,9 +4,9 @@
# norootforbuild
Name: apparmor-dbus
BuildRequires: audit-devel dbus-1-devel pcre-devel pkgconfig
Requires: audit dbus-1 pcre
Version: 1.0
BuildRequires: audit-devel dbus-1-devel pkgconfig libapparmor-devel
Requires: audit dbus-1 libapparmor
Version: 1.1
Release: 0
License: GPL
Group: System/Management

View File

@@ -1,14 +1,17 @@
/* config.h.in. Generated from configure.in by autoheader. */
/* Define to 1 if you have the <aalogparse/aalogparse.h> header file. */
#undef HAVE_AALOGPARSE_AALOGPARSE_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `apparmor' library (-lapparmor). */
#undef HAVE_LIBAPPARMOR
/* Define to 1 if you have the <libaudit.h> header file. */
#undef HAVE_LIBAUDIT_H
/* Define to 1 if you have the `pcre' library (-lpcre). */
#undef HAVE_LIBPCRE
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H

File diff suppressed because it is too large Load Diff

View File

@@ -8,6 +8,7 @@ AC_PROG_CC
AC_CHECK_HEADERS(libaudit.h)
PKG_CHECK_MODULES(DBUS, dbus-1 >= 0.60)
AC_CHECK_LIB(pcre, pcre_compile)
AC_CHECK_HEADERS(aalogparse/aalogparse.h)
AC_CHECK_LIB(apparmor, parse_record)
AC_OUTPUT(Makefile src/Makefile)

View File

@@ -2,8 +2,7 @@ bin_PROGRAMS = apparmor-dbus
apparmor_dbus_SOURCES = aadbus.c
# set the include path found by configure
INCLUDES= $(all_includes) `$(PKG_CONFIG) --cflags dbus-1`
INCLUDES= $(all_includes) `$(PKG_CONFIG) --cflags dbus-1`
# the library search path.
apparmor_dbus_LDFLAGS = $(all_libraries) -laudit -lpcre `$(PKG_CONFIG) --libs dbus-1`
apparmor_dbus_LDFLAGS = $(all_libraries) -laudit `$(PKG_CONFIG) --libs dbus-1`

View File

@@ -85,6 +85,7 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -108,8 +109,6 @@ SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_STRIP = @ac_ct_STRIP@
ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__include = @am__include@
@@ -120,19 +119,26 @@ am__untar = @am__untar@
bindir = @bindir@
build_alias = @build_alias@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host_alias = @host_alias@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
@@ -140,10 +146,10 @@ target_alias = @target_alias@
apparmor_dbus_SOURCES = aadbus.c
# set the include path found by configure
INCLUDES = $(all_includes) `$(PKG_CONFIG) --cflags dbus-1`
INCLUDES = $(all_includes) `$(PKG_CONFIG) --cflags dbus-1`
# the library search path.
apparmor_dbus_LDFLAGS = $(all_libraries) -laudit -lpcre `$(PKG_CONFIG) --libs dbus-1`
apparmor_dbus_LDFLAGS = $(all_libraries) -laudit `$(PKG_CONFIG) --libs dbus-1`
all: all-am
.SUFFIXES:

View File

@@ -11,7 +11,9 @@
#include <locale.h>
#include <libaudit.h>
#include <dbus/dbus.h>
#include <pcre.h>
#include <aalogparse/aalogparse.h>
#define NULLSPACE(x) (x == NULL) ? &empty_string : &x
// Local data
static volatile int signaled = 0;
@@ -39,7 +41,7 @@ int main(int argc, char *argv[])
setlocale (LC_ALL, "");
#ifndef DEBUG
// Make sure we are root
/* Make sure we are root */
if (getuid() != 0) {
printf("You must be root to run this program.\n");
return 4;
@@ -68,6 +70,9 @@ int main(int argc, char *argv[])
return event_loop();
}
/* This function is needed for "old" messages which lumped
* everything together under one audit ID.
*/
static int is_reject (char *data)
{
int ret = -1;
@@ -87,21 +92,23 @@ static int is_reject (char *data)
static int event_loop(void)
{
void* data;
char *empty_string = " "; /* This is a quick way to indicate a 'null' value in our DBUS message */
struct iovec vec[2];
struct audit_dispatcher_header hdr;
DBusError error; /* Error, if any */
DBusMessage *message; /* Message to send */
DBusMessageIter iter; /* Iterator for message data */
const char *what; /* What to send */
static DBusConnection *con = NULL; /* Connection to DBUS server */
pcre *reject_regex;
const char *pcre_error, *matched_mode, *matched_resource, *matched_program, *matched_pid, *matched_profile, *matched_active;
int pcre_reject_vector[30];
int pcre_reject_vector_size = 30;
int pcre_erroffset, pcre_exec_return;
char *line;
char *pcre_reject_string = "^audit\\(\\d+\\.\\d+:\\d+\\): REJECTING (\\D+) access to (\\S+) \\((\\D+)\\((\\d+)\\) profile (\\S+) active (\\S+)\\)";
char *line = NULL, *parsable_line = NULL;
int real_data_size;
aa_log_record *record;
int is_rejection = 0;
if (con && !dbus_connection_get_is_connected(con))
{
dbus_connection_unref(con);
@@ -130,20 +137,13 @@ static int event_loop(void)
return 1;
}
/* Compile the regular expression */
reject_regex = pcre_compile(pcre_reject_string, 0, &pcre_error, &pcre_erroffset, NULL);
if (reject_regex == NULL)
{
printf("Could not compile the reject regular expression.\n");
printf("The error message was: %s\n", pcre_error);
return 1;
}
memset(data, 0, MAX_AUDIT_MESSAGE_LENGTH);
memset(&hdr, 0, sizeof(hdr));
do
{
int rc;
parsable_line = NULL;
is_rejection = 0;
struct timeval tv;
fd_set fd;
tv.tv_sec = 1;
@@ -170,58 +170,104 @@ static int event_loop(void)
printf("rc == %d(%s)\n", rc, strerror(errno));
break;
}
/* Handle the AppArmor events */
if ((hdr.type >= 1500) && (hdr.type <= 1599))
/* Handle the AppArmor events.
* 1500 is used for "old" style messages.
* 1503 is used for APPARMOR_DENIED messages.
*/
if ((hdr.type == 1500) || (hdr.type == 1503))
{
line = (char *) data;
record = NULL;
if (hdr.type == 1503)
is_rejection = 1;
if ((hdr.type == 1500) && (is_reject(line) == 0))
is_rejection = 1;
/* We only care about REJECTING messages */
if (is_reject(line) == 0)
{
pcre_exec_return = pcre_exec(reject_regex,
NULL,
line,
strlen(line),
0,
0,
pcre_reject_vector,
pcre_reject_vector_size);
if (pcre_exec_return > 0)
if (is_rejection == 1)
{
/* parse_record expects things like they appear in audit.log -
* which means we need to prepend TYPE=APPARMOR (if hdr.type is 1500)
* or type=APPARMOR_DENIED (if hdr.type is 1503). This is not ideal.
*/
real_data_size = strlen(line);
if (hdr.type == 1500)
{
pcre_get_substring(line, pcre_reject_vector, pcre_exec_return, 1, &matched_mode);
pcre_get_substring(line, pcre_reject_vector, pcre_exec_return, 2, &matched_resource);
pcre_get_substring(line, pcre_reject_vector, pcre_exec_return, 3, &matched_program);
pcre_get_substring(line, pcre_reject_vector, pcre_exec_return, 4, &matched_pid);
pcre_get_substring(line, pcre_reject_vector, pcre_exec_return, 5, &matched_profile);
pcre_get_substring(line, pcre_reject_vector, pcre_exec_return, 6, &matched_active);
message = dbus_message_new_signal("/com/Novell/AppArmor","com.novell.apparmor", "REJECT");
dbus_message_iter_init_append(message, &iter);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &data);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &matched_mode);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &matched_resource);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &matched_program);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &matched_pid);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &matched_profile);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &matched_active);
dbus_connection_send(con, message, NULL);
dbus_connection_flush(con);
dbus_message_unref(message);
pcre_free_substring(matched_mode);
pcre_free_substring(matched_resource);
pcre_free_substring(matched_program);
pcre_free_substring(matched_pid);
pcre_free_substring(matched_profile);
pcre_free_substring(matched_active);
parsable_line = (char *) malloc(real_data_size + 20);
snprintf(parsable_line, real_data_size + 19, "type=APPARMOR msg=%s", line);
}
else
{
parsable_line = (char *) malloc(real_data_size + 27);
snprintf(parsable_line, real_data_size + 26, "type=APPARMOR_REJECT msg=%s", line);
}
}
}
record = parse_record(parsable_line);
message = dbus_message_new_signal("/com/Novell/AppArmor","com.novell.apparmor", "REJECT");
dbus_message_iter_init_append(message, &iter);
/*
* The message has a number of fields appended to it,
* all of which map to the aa_log_record struct that we get back from
* parse_record(). If an entry in the struct is NULL or otherwise invalid,
* the field is still appended as a single blank space (in the case of strings), or a
* 0 in case of integers (which are all PIDs and unlikely to ever be 0).
*
* TODO: Pass a bitmask int along for the denied & requested masks
*
* 1 - The full string - DBUS_TYPE_STRING
* 2 - The PID (record->pid) - DBUS_TYPE_INT64
* 3 - The task (record->task) - DBUS_TYPE_INT64
* 4 - The audit ID (record->audit_id) - DBUS_TYPE_STRING
* 5 - The operation (record->operation: "Exec" "ptrace" etc) - DBUS_TYPE_STRING
* 6 - The denied mask (record->denied_mask: "rwx" etc) - DBUS_TYPE_STRING
* 7 - The requested mask (record->requested_mask) - DBUS_TYPE_STRING
* 8 - The name of the profile (record->profile) - DBUS_TYPE_STRING
* 9 - The first name field (record->name) - DBUS_TYPE_STRING
* 10- The second name field (record->name2) - DBUS_TYPE_STRING
* 11- The attribute (record->attribute) - DBUS_TYPE_STRING
* 12- The parent task (record->parent) - DBUS_TYPE_STRING
* 13- The magic token (record->magic_token) - DBUS_TYPE_STRING
* 14- The info field (record->info) - DBUS_TYPE_STRING
* 15- The active hat (record->active_hat) - DBUS_TYPE_STRING
*/
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &data);
if (record != NULL)
{
dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT64, &record->pid);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT64, &record->task);
// Please note: NULLSPACE is defined at the top of this file, and will expand to
// a ternary conditional:
// (record->audit_id == NULL) ? &empty_string : &record->audit_id
// for example.
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, NULLSPACE(record->audit_id));
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, NULLSPACE(record->operation));
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, NULLSPACE(record->denied_mask));
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, NULLSPACE(record->requested_mask));
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, NULLSPACE(record->profile));
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, NULLSPACE(record->name));
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, NULLSPACE(record->name2));
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, NULLSPACE(record->attribute));
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, NULLSPACE(record->parent));
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, NULLSPACE(record->magic_token));
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, NULLSPACE(record->info));
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, NULLSPACE(record->active_hat));
}
dbus_connection_send(con, message, NULL);
dbus_connection_flush(con);
dbus_message_unref(message);
free_record(record);
if (parsable_line != NULL)
free(parsable_line);
}
}
} while(!signaled);
//dbus_message_unref(message);
if (con)
dbus_connection_close(con);
pcre_free(reject_regex);
dbus_connection_unref(con);
free(data);
return 0;
}