diff options
Diffstat (limited to 'libseaudit/src/filter.c')
-rw-r--r-- | libseaudit/src/filter.c | 1124 |
1 files changed, 1124 insertions, 0 deletions
diff --git a/libseaudit/src/filter.c b/libseaudit/src/filter.c new file mode 100644 index 0000000..298a309 --- /dev/null +++ b/libseaudit/src/filter.c @@ -0,0 +1,1124 @@ +/** + * @file + * Implementation of seaudit filters. + * + * If adding new filter criteria, make sure you do the following: + * + * <ol> + * <li>add field(s) to seaudit_filter_t</li> + * <li>update filter constructor, seaudit_filter_create()</li> + * <li>update copy-constructor, seaudit_filter_create_from_filter()</li> + * <li>update destructor, seaudit_filter_destroy()</li> + * <li>add accessor(s) and modifier(s) as necessary</li> + * <li>add a record to filter_criteria table (in filter-internal.c), + * implementing the five necessary functions</li> + * </ol> + * + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * @author Jeremy Solt jsolt@tresys.com + * + * Copyright (C) 2004-2007 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "seaudit_internal.h" +#include "filter-internal.h" + +#include <apol/util.h> + +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +seaudit_filter_t *seaudit_filter_create(const char *name) +{ + seaudit_filter_t *s = calloc(1, sizeof(*s)); + if (s == NULL) { + return NULL; + } + if (name == NULL) { + name = "Untitled"; + } + if ((s->name = strdup(name)) == NULL) { + int error = errno; + seaudit_filter_destroy(&s); + errno = error; + return NULL; + } + return s; +} + +seaudit_filter_t *seaudit_filter_create_from_filter(const seaudit_filter_t * filter) +{ + seaudit_filter_t *f = NULL; + int error = 0; + if (filter == NULL) { + error = EINVAL; + goto cleanup; + } + if ((f = seaudit_filter_create(filter->name)) == NULL || (filter->desc != NULL && (f->desc = strdup(filter->desc)) == NULL)) { + error = errno; + goto cleanup; + } + f->strict = filter->strict; + if ((filter->src_users != NULL + && (f->src_users = apol_vector_create_from_vector(filter->src_users, apol_str_strdup, NULL, free)) == NULL) + || (filter->src_roles != NULL + && (f->src_roles = apol_vector_create_from_vector(filter->src_roles, apol_str_strdup, NULL, free)) == NULL) + || (filter->src_types != NULL + && (f->src_types = apol_vector_create_from_vector(filter->src_types, apol_str_strdup, NULL, free)) == NULL) + || (filter->src_mls_lvl != NULL + && (f->src_mls_lvl = apol_vector_create_from_vector(filter->src_mls_lvl, apol_str_strdup, NULL, free)) == NULL) + || (filter->src_mls_clr != NULL + && (f->src_mls_clr = apol_vector_create_from_vector(filter->src_mls_clr, apol_str_strdup, NULL, free)) == NULL) + || (filter->tgt_users != NULL + && (f->tgt_users = apol_vector_create_from_vector(filter->tgt_users, apol_str_strdup, NULL, free)) == NULL) + || (filter->tgt_roles != NULL + && (f->tgt_roles = apol_vector_create_from_vector(filter->tgt_roles, apol_str_strdup, NULL, free)) == NULL) + || (filter->tgt_types != NULL + && (f->tgt_types = apol_vector_create_from_vector(filter->tgt_types, apol_str_strdup, NULL, free)) == NULL) + || (filter->tgt_mls_lvl != NULL + && (f->tgt_mls_lvl = apol_vector_create_from_vector(filter->tgt_mls_lvl, apol_str_strdup, NULL, free)) == NULL) + || (filter->tgt_mls_clr != NULL + && (f->tgt_mls_clr = apol_vector_create_from_vector(filter->tgt_mls_clr, apol_str_strdup, NULL, free)) == NULL) + || (filter->tgt_classes != NULL + && (f->tgt_classes = apol_vector_create_from_vector(filter->tgt_classes, apol_str_strdup, NULL, free)) == NULL)) { + error = errno; + goto cleanup; + } + if ((filter->perm != NULL && (f->perm = strdup(filter->perm)) == NULL) || + (filter->exe != NULL && (f->exe = strdup(filter->exe)) == NULL) || + (filter->host != NULL && (f->host = strdup(filter->host)) == NULL) || + (filter->path != NULL && (f->path = strdup(filter->path)) == NULL) || + (filter->comm != NULL && (f->comm = strdup(filter->comm)) == NULL) || + (filter->anyaddr != NULL && (f->anyaddr = strdup(filter->anyaddr)) == NULL) || + (filter->netif != NULL && (f->netif = strdup(filter->netif)) == NULL)) { + error = errno; + goto cleanup; + } + if ((filter->laddr != NULL && (f->laddr = strdup(filter->laddr)) == NULL) || + (filter->faddr != NULL && (f->faddr = strdup(filter->faddr)) == NULL) || + (filter->saddr != NULL && (f->saddr = strdup(filter->saddr)) == NULL) || + (filter->daddr != NULL && (f->daddr = strdup(filter->daddr)) == NULL)) { + error = errno; + goto cleanup; + } + f->match = filter->match; + f->inode = filter->inode; + f->pid = filter->pid; + f->anyport = filter->anyport; + f->lport = filter->lport; + f->fport = filter->fport; + f->sport = filter->sport; + f->dport = filter->dport; + f->port = filter->port; + f->key = filter->key; + f->cap = filter->cap; + f->avc_msg_type = filter->avc_msg_type; + if (filter->start != NULL) { + if ((f->start = calloc(1, sizeof(*f->start))) == NULL) { + error = errno; + goto cleanup; + } + memcpy(f->start, filter->start, sizeof(*f->start)); + } + if (filter->end != NULL) { + if ((f->end = calloc(1, sizeof(*f->end))) == NULL) { + error = errno; + goto cleanup; + } + memcpy(f->end, filter->end, sizeof(*f->end)); + } + f->date_match = filter->date_match; + f->model = NULL; + cleanup: + if (error != 0) { + seaudit_filter_destroy(&f); + errno = error; + return NULL; + } + return f; +} + +/** + * Callback invoked when free()ing a vector of filters. + * + * @param v Filter object to free. + */ +static void filter_free(void *v) +{ + seaudit_filter_t *f = v; + seaudit_filter_destroy(&f); +} + +apol_vector_t *seaudit_filter_create_from_file(const char *filename) +{ + struct filter_parse_state state; + int retval, error; + memset(&state, 0, sizeof(state)); + if ((state.filters = apol_vector_create(filter_free)) == NULL) { + return NULL; + } + retval = filter_parse_xml(&state, filename); + error = errno; + free(state.view_name); + if (retval < 0) { + apol_vector_destroy(&state.filters); + errno = error; + return NULL; + } + return state.filters; +} + +void seaudit_filter_destroy(seaudit_filter_t ** filter) +{ + if (filter != NULL && *filter != NULL) { + free((*filter)->name); + free((*filter)->desc); + apol_vector_destroy(&(*filter)->src_users); + apol_vector_destroy(&(*filter)->src_roles); + apol_vector_destroy(&(*filter)->src_types); + apol_vector_destroy(&(*filter)->src_mls_lvl); + apol_vector_destroy(&(*filter)->src_mls_clr); + apol_vector_destroy(&(*filter)->tgt_users); + apol_vector_destroy(&(*filter)->tgt_roles); + apol_vector_destroy(&(*filter)->tgt_types); + apol_vector_destroy(&(*filter)->tgt_mls_lvl); + apol_vector_destroy(&(*filter)->tgt_mls_clr); + apol_vector_destroy(&(*filter)->tgt_classes); + free((*filter)->perm); + free((*filter)->exe); + free((*filter)->host); + free((*filter)->path); + free((*filter)->comm); + free((*filter)->anyaddr); + free((*filter)->laddr); + free((*filter)->faddr); + free((*filter)->saddr); + free((*filter)->daddr); + free((*filter)->netif); + free((*filter)->start); + free((*filter)->end); + free(*filter); + *filter = NULL; + } +} + +int seaudit_filter_set_match(seaudit_filter_t * filter, seaudit_filter_match_e match) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + filter->match = match; + if (filter->model != NULL) { + model_notify_filter_changed(filter->model, filter); + } + return 0; +} + +seaudit_filter_match_e seaudit_filter_get_match(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return 0; + } + return filter->match; +} + +int seaudit_filter_set_name(seaudit_filter_t * filter, const char *name) +{ + char *new_name = NULL; + if (filter == NULL) { + errno = EINVAL; + return -1; + } + if (name != filter->name) { + if (name != NULL && (new_name = strdup(name)) == NULL) { + return -1; + } + free(filter->name); + filter->name = new_name;; + } + return 0; +} + +const char *seaudit_filter_get_name(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->name; +} + +int seaudit_filter_set_description(seaudit_filter_t * filter, const char *desc) +{ + char *new_desc = NULL; + if (filter == NULL) { + errno = EINVAL; + return -1; + } + if (desc != filter->desc) { + if (desc != NULL && (new_desc = strdup(desc)) == NULL) { + return -1; + } + free(filter->desc); + filter->desc = new_desc; + } + return 0; +} + +const char *seaudit_filter_get_description(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->desc; +} + +int seaudit_filter_set_strict(seaudit_filter_t * filter, bool is_strict) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + if (filter->strict != is_strict) { + filter->strict = is_strict; + if (filter->model != NULL) { + model_notify_filter_changed(filter->model, filter); + } + } + return 0; +} + +bool seaudit_filter_get_strict(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return false; + } + return filter->strict; +} + +/** + * Helper function to set a criterion's vector, by duping the vector + * and its strings. Dupe the vector before destroying the existing + * one, in case v is the same as tgt. + */ +static int filter_set_vector(seaudit_filter_t * filter, apol_vector_t ** tgt, const apol_vector_t * v) +{ + apol_vector_t *new_v = NULL; + if (v != NULL) { + if ((new_v = apol_vector_create_from_vector(v, apol_str_strdup, NULL, free)) == NULL) { + return -1; + } + } + apol_vector_destroy(tgt); + *tgt = new_v; + if (filter->model != NULL) { + model_notify_filter_changed(filter->model, filter); + } + return 0; +} + +/** + * Helper function to set a criterion string, by dupping the src + * string. As a check, if the pointers are already the same then do + * nothing. + */ +static int filter_set_string(seaudit_filter_t * filter, char **dest, const char *src) +{ + if (src != *dest) { + char *new_s = NULL; + if (src != NULL && (new_s = strdup(src)) == NULL) { + return -1; + } + free(*dest); + *dest = new_s; + if (filter->model != NULL) { + model_notify_filter_changed(filter->model, filter); + } + } + return 0; +} + +static int filter_set_ulong(seaudit_filter_t * filter, unsigned long *dest, const ulong src) +{ + if (src != *dest) { + *dest = src; + if (filter->model != NULL) { + model_notify_filter_changed(filter->model, filter); + } + } + return 0; +} + +static int filter_set_uint(seaudit_filter_t * filter, unsigned int *dest, const ulong src) +{ + if (src != *dest) { + *dest = src; + if (filter->model != NULL) { + model_notify_filter_changed(filter->model, filter); + } + } + return 0; +} + +static int filter_set_int(seaudit_filter_t * filter, int *dest, const int src) +{ + int s = src; + if (src <= 0) { + s = 0; + } + if (s != *dest) { + *dest = s; + if (filter->model != NULL) { + model_notify_filter_changed(filter->model, filter); + } + } + return 0; +} + +/******************** public accessors / modifiers ********************/ + +int seaudit_filter_set_source_user(seaudit_filter_t * filter, const apol_vector_t * v) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_vector(filter, &filter->src_users, v); +} + +const apol_vector_t *seaudit_filter_get_source_user(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->src_users; +} + +int seaudit_filter_set_source_role(seaudit_filter_t * filter, const apol_vector_t * v) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_vector(filter, &filter->src_roles, v); +} + +const apol_vector_t *seaudit_filter_get_source_role(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->src_roles; +} + +int seaudit_filter_set_source_type(seaudit_filter_t * filter, const apol_vector_t * v) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_vector(filter, &filter->src_types, v); +} + +const apol_vector_t *seaudit_filter_get_source_type(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->src_types; +} + +int seaudit_filter_set_source_mls_lvl(seaudit_filter_t * filter, const apol_vector_t * v) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_vector(filter, &filter->src_mls_lvl, v); +} + +const apol_vector_t *seaudit_filter_get_source_mls_lvl(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->src_mls_lvl; +} + +int seaudit_filter_set_source_mls_clr(seaudit_filter_t * filter, const apol_vector_t * v) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_vector(filter, &filter->src_mls_clr, v); +} + +const apol_vector_t *seaudit_filter_get_source_mls_clr(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->src_mls_clr; +} +int seaudit_filter_set_target_user(seaudit_filter_t * filter, const apol_vector_t * v) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_vector(filter, &filter->tgt_users, v); +} + +const apol_vector_t *seaudit_filter_get_target_user(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->tgt_users; +} + +int seaudit_filter_set_target_role(seaudit_filter_t * filter, const apol_vector_t * v) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_vector(filter, &filter->tgt_roles, v); +} + +const apol_vector_t *seaudit_filter_get_target_role(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->tgt_roles; +} + +int seaudit_filter_set_target_type(seaudit_filter_t * filter, const apol_vector_t * v) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_vector(filter, &filter->tgt_types, v); +} + +const apol_vector_t *seaudit_filter_get_target_type(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->tgt_types; +} + +int seaudit_filter_set_target_mls_lvl(seaudit_filter_t * filter, const apol_vector_t * v) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_vector(filter, &filter->tgt_mls_lvl, v); +} + +const apol_vector_t *seaudit_filter_get_target_mls_lvl(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->tgt_mls_lvl; +} + +int seaudit_filter_set_target_mls_clr(seaudit_filter_t * filter, const apol_vector_t * v) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_vector(filter, &filter->tgt_mls_clr, v); +} + +const apol_vector_t *seaudit_filter_get_target_mls_clr(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->tgt_mls_clr; +} + +int seaudit_filter_set_target_class(seaudit_filter_t * filter, const apol_vector_t * v) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_vector(filter, &filter->tgt_classes, v); +} + +const apol_vector_t *seaudit_filter_get_target_class(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->tgt_classes; +} + +int seaudit_filter_set_permission(seaudit_filter_t * filter, const char *perm) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_string(filter, &filter->perm, perm); +} + +const char *seaudit_filter_get_permission(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->perm; +} + +int seaudit_filter_set_executable(seaudit_filter_t * filter, const char *exe) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_string(filter, &filter->exe, exe); +} + +const char *seaudit_filter_get_executable(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->exe; +} + +int seaudit_filter_set_host(seaudit_filter_t * filter, const char *host) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_string(filter, &filter->host, host); +} + +const char *seaudit_filter_get_host(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->host; +} + +int seaudit_filter_set_path(seaudit_filter_t * filter, const char *path) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_string(filter, &filter->path, path); +} + +const char *seaudit_filter_get_path(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->path; +} + +int seaudit_filter_set_inode(seaudit_filter_t * filter, unsigned long inode) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_ulong(filter, &filter->inode, inode); + return 0; +} + +unsigned long seaudit_filter_get_inode(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return 0; + } + return filter->inode; +} + +int seaudit_filter_set_pid(seaudit_filter_t * filter, unsigned int pid) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_uint(filter, &filter->pid, pid); + return 0; +} + +unsigned int seaudit_filter_get_pid(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return 0; + } + return filter->pid; +} + +int seaudit_filter_set_command(seaudit_filter_t * filter, const char *command) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_string(filter, &filter->comm, command); +} + +const char *seaudit_filter_get_command(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->comm; +} + +int seaudit_filter_set_anyaddr(seaudit_filter_t * filter, const char *ipaddr) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_string(filter, &filter->anyaddr, ipaddr); +} + +const char *seaudit_filter_get_anyaddr(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->anyaddr; +} + +int seaudit_filter_set_anyport(seaudit_filter_t * filter, const int port) +{ + if (filter == NULL) { + errno = EINVAL; + return 0; + } + return filter_set_int(filter, &filter->anyport, port); +} + +int seaudit_filter_get_anyport(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return 0; + } + return filter->anyport; +} + +int filter_set_ipaddress_vers_4_1(seaudit_filter_t * filter, const char *ipaddr) +{ + return seaudit_filter_set_anyaddr(filter, ipaddr); +} + +const char *filter_get_ipaddress_vers_4_1(const seaudit_filter_t * filter) +{ + return seaudit_filter_get_anyaddr(filter); +} + +int filter_set_port_vers_4_1(seaudit_filter_t * filter, const int port) +{ + return seaudit_filter_set_anyport(filter, port); +} + +int filter_get_port_vers_4_1(const seaudit_filter_t * filter) +{ + return seaudit_filter_get_anyport(filter); +} + +#if LINK_SHARED == 1 +__asm__(".symver filter_set_ipaddress_vers_4_1,seaudit_filter_set_ipaddress@VERS_4.1"); +__asm__(".symver filter_get_ipaddress_vers_4_1,seaudit_filter_get_ipaddress@VERS_4.1"); +__asm__(".symver filter_set_port_vers_4_1,seaudit_filter_set_port@VERS_4.1"); +__asm__(".symver filter_get_port_vers_4_1,seaudit_filter_get_port@VERS_4.1"); +#endif + +int seaudit_filter_set_laddr(seaudit_filter_t * filter, const char *laddr) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_string(filter, &filter->laddr, laddr); +} + +const char *seaudit_filter_get_laddr(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->laddr; +} + +int seaudit_filter_set_lport(seaudit_filter_t * filter, const int lport) +{ + if (filter == NULL) { + errno = EINVAL; + return 0; + } + return filter_set_int(filter, &filter->lport, lport); +} + +int seaudit_filter_get_lport(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return 0; + } + return filter->lport; +} + +int seaudit_filter_set_faddr(seaudit_filter_t * filter, const char *faddr) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_string(filter, &filter->faddr, faddr); +} + +const char *seaudit_filter_get_faddr(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->faddr; +} + +int seaudit_filter_set_fport(seaudit_filter_t * filter, const int fport) +{ + if (filter == NULL) { + errno = EINVAL; + return 0; + } + return filter_set_int(filter, &filter->fport, fport); +} + +int seaudit_filter_get_fport(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return 0; + } + return filter->fport; +} + +int seaudit_filter_set_saddr(seaudit_filter_t * filter, const char *saddr) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_string(filter, &filter->saddr, saddr); +} + +const char *seaudit_filter_get_saddr(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->saddr; +} + +int seaudit_filter_set_sport(seaudit_filter_t * filter, const int sport) +{ + if (filter == NULL) { + errno = EINVAL; + return 0; + } + return filter_set_int(filter, &filter->sport, sport); +} + +int seaudit_filter_get_sport(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return 0; + } + return filter->sport; +} + +int seaudit_filter_set_daddr(seaudit_filter_t * filter, const char *daddr) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_string(filter, &filter->daddr, daddr); +} + +const char *seaudit_filter_get_daddr(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->daddr; +} + +int seaudit_filter_set_dport(seaudit_filter_t * filter, const int dport) +{ + if (filter == NULL) { + errno = EINVAL; + return 0; + } + return filter_set_int(filter, &filter->dport, dport); +} + +int seaudit_filter_get_dport(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return 0; + } + return filter->dport; +} + +int filter_set_port_vers_4_2(seaudit_filter_t * filter, const int port) +{ + if (filter == NULL) { + errno = EINVAL; + return 0; + } + return filter_set_int(filter, &filter->port, port); +} + +int filter_get_port_vers_4_2(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return 0; + } + return filter->port; +} + +#if LINK_SHARED == 1 +__asm__(".symver filter_set_port_vers_4_2,seaudit_filter_set_port@@VERS_4.2"); +__asm__(".symver filter_get_port_vers_4_2,seaudit_filter_get_port@@VERS_4.2"); +#endif + +int seaudit_filter_set_key(seaudit_filter_t * filter, const int key) +{ + if (filter == NULL) { + errno = EINVAL; + return 0; + } + return filter_set_int(filter, &filter->key, key); +} + +int seaudit_filter_get_key(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return 0; + } + return filter->key; +} + +int seaudit_filter_set_cap(seaudit_filter_t * filter, const int cap) +{ + if (filter == NULL) { + errno = EINVAL; + return 0; + } + return filter_set_int(filter, &filter->cap, cap); +} + +int seaudit_filter_get_cap(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return 0; + } + return filter->cap; +} + +int seaudit_filter_set_netif(seaudit_filter_t * filter, const char *netif) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + return filter_set_string(filter, &filter->netif, netif); +} + +const char *seaudit_filter_get_netif(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return NULL; + } + return filter->netif; +} + +int seaudit_filter_set_message_type(seaudit_filter_t * filter, const seaudit_avc_message_type_e message_type) +{ + if (filter == NULL) { + errno = EINVAL; + return -1; + } + filter->avc_msg_type = message_type; + if (filter->model != NULL) { + model_notify_filter_changed(filter->model, filter); + } + return 0; +} + +seaudit_avc_message_type_e seaudit_filter_get_message_type(const seaudit_filter_t * filter) +{ + if (filter == NULL) { + errno = EINVAL; + return SEAUDIT_AVC_UNKNOWN; + } + return filter->avc_msg_type; +} + +int seaudit_filter_set_date(seaudit_filter_t * filter, const struct tm *start, const struct tm *end, + seaudit_filter_date_match_e date_match) +{ + struct tm *new_tm = NULL; + if (filter == NULL) { + errno = EINVAL; + return -1; + } + /* the following weird branching exists because start and end + * could be shadowing filter->start and filter->end. if + * filters->start and filter->end are free()d to early, then + * there may be a dereference of free()d memory */ + if (filter->start != start) { + new_tm = NULL; + if (start != NULL) { + if ((new_tm = calloc(1, sizeof(*new_tm))) == NULL) { + return -1; + } + memcpy(new_tm, start, sizeof(*start)); + } + free(filter->start); + filter->start = new_tm; + } + if (start != NULL) { + if (filter->end != end) { + new_tm = NULL; + if (end != NULL) { + if ((new_tm = calloc(1, sizeof(*new_tm))) == NULL) { + return -1; + } + memcpy(new_tm, end, sizeof(*end)); + } + free(filter->end); + filter->end = new_tm; + } + } else { + free(filter->end); + filter->end = NULL; + } + filter->date_match = date_match; + if (filter->model != NULL) { + model_notify_filter_changed(filter->model, filter); + } + return 0; +} + +void seaudit_filter_get_date(const seaudit_filter_t * filter, const struct tm **start, const struct tm **end, + seaudit_filter_date_match_e * match) +{ + if (start != NULL) { + *start = NULL; + } + if (end != NULL) { + *end = NULL; + } + if (match != NULL) { + *match = SEAUDIT_FILTER_DATE_MATCH_BEFORE; + } + if (filter == NULL || start == NULL || end == NULL || match == NULL) { + errno = EINVAL; + return; + } + *start = filter->start; + *end = filter->end; + *match = filter->date_match; +} + +int seaudit_filter_save_to_file(const seaudit_filter_t * filter, const char *filename) +{ + FILE *file; + const char *XML_VER = "<?xml version=\"1.0\"?>\n"; + + if (filter == NULL || filename == NULL) { + errno = EINVAL; + return -1; + } + if ((file = fopen(filename, "w")) == NULL) { + return -1; + } + fprintf(file, XML_VER); + fprintf(file, "<view xmlns=\"http://oss.tresys.com/projects/setools/seaudit-%s/\">\n", FILTER_FILE_FORMAT_VERSION); + filter_append_to_file(filter, file, 1); + fprintf(file, "</view>\n"); + fclose(file); + return 0; +} + +/******************** protected functions below ********************/ + +void filter_set_model(seaudit_filter_t * filter, seaudit_model_t * model) +{ + filter->model = model; +} |