00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "seaudit_internal.h"
00026 #include "filter-internal.h"
00027
00028 #include <apol/util.h>
00029
00030 #include <errno.h>
00031 #include <fnmatch.h>
00032 #include <stdbool.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <time.h>
00036 #include <libxml/uri.h>
00037
00038
00039
00040 static int filter_string_vector_read(apol_vector_t ** v, const xmlChar * ch)
00041 {
00042 char *s;
00043 if (*v == NULL && (*v = apol_vector_create_with_capacity(1, free)) == NULL) {
00044 return -1;
00045 }
00046 if ((s = xmlURIUnescapeString((const char *)ch, 0, NULL)) == NULL || apol_vector_append(*v, s) < 0) {
00047 free(s);
00048 return -1;
00049 }
00050 return 0;
00051 }
00052
00053 static int filter_string_read(char **dest, const xmlChar * ch)
00054 {
00055 free(*dest);
00056 *dest = NULL;
00057 if ((*dest = xmlURIUnescapeString((const char *)ch, 0, NULL)) == NULL) {
00058 return -1;
00059 }
00060 return 0;
00061 }
00062
00063 static int filter_ulong_read(unsigned long *dest, const xmlChar * ch)
00064 {
00065 char *s, *endptr;
00066 int retval = -1;
00067 if ((s = xmlURIUnescapeString((const char *)ch, 0, NULL)) == NULL) {
00068 return -1;
00069 }
00070 *dest = strtoul(s, &endptr, 10);
00071 if (*s != '\0' && *endptr == '\0') {
00072 retval = 0;
00073 }
00074 free(s);
00075 return retval;
00076 }
00077
00078 static unsigned int filter_uint_read(unsigned int *dest, const xmlChar * ch)
00079 {
00080 char *s, *endptr;
00081 int retval = -1;
00082 if ((s = xmlURIUnescapeString((const char *)ch, 0, NULL)) == NULL) {
00083 return -1;
00084 }
00085 *dest = (unsigned int)(strtoul(s, &endptr, 10));
00086 if (*s != '\0' && *endptr == '\0') {
00087 retval = 0;
00088 }
00089 free(s);
00090 return retval;
00091 }
00092
00093 static int filter_int_read(int *dest, const xmlChar * ch)
00094 {
00095 char *s, *endptr;
00096 int retval = -1;
00097 if ((s = xmlURIUnescapeString((const char *)ch, 0, NULL)) == NULL) {
00098 return -1;
00099 }
00100 *dest = (int)(strtol(s, &endptr, 10));
00101 if (*s != '\0' && *endptr == '\0') {
00102 retval = 0;
00103 }
00104 free(s);
00105 return retval;
00106 }
00107
00108 static void filter_string_vector_print(const char *criteria_name, apol_vector_t * v, FILE * f, int tabs)
00109 {
00110 int i;
00111 size_t j;
00112 if (v == NULL) {
00113 return;
00114 }
00115 for (i = 0; i < tabs; i++)
00116 fprintf(f, "\t");
00117 fprintf(f, "<criteria type=\"%s\">\n", criteria_name);
00118 for (j = 0; j < apol_vector_get_size(v); j++) {
00119 xmlChar *s = xmlCharStrdup(apol_vector_get_element(v, j));
00120 xmlChar *escaped = xmlURIEscapeStr(s, NULL);
00121 for (i = 0; i < tabs + 1; i++) {
00122 fprintf(f, "\t");
00123 }
00124 fprintf(f, "<item>%s</item>\n", escaped);
00125 free(escaped);
00126 free(s);
00127 }
00128 for (i = 0; i < tabs; i++)
00129 fprintf(f, "\t");
00130 fprintf(f, "</criteria>\n");
00131 }
00132
00133 static void filter_string_print(const char *criteria_name, const char *s, FILE * f, int tabs)
00134 {
00135 int i;
00136 xmlChar *t, *escaped;
00137 if (s == NULL) {
00138 return;
00139 }
00140 t = xmlCharStrdup(s);
00141 escaped = xmlURIEscapeStr(t, NULL);
00142 for (i = 0; i < tabs; i++)
00143 fprintf(f, "\t");
00144 fprintf(f, "<criteria type=\"%s\">\n", criteria_name);
00145 for (i = 0; i < tabs + 1; i++) {
00146 fprintf(f, "\t");
00147 }
00148 fprintf(f, "<item>%s</item>\n", escaped);
00149 for (i = 0; i < tabs; i++)
00150 fprintf(f, "\t");
00151 fprintf(f, "</criteria>\n");
00152 free(escaped);
00153 free(t);
00154 }
00155
00156 static void filter_ulong_print(const char *criteria_name, const unsigned long val, FILE * f, int tabs)
00157 {
00158 int i;
00159 for (i = 0; i < tabs; i++)
00160 fprintf(f, "\t");
00161 fprintf(f, "<criteria type=\"%s\">\n", criteria_name);
00162 for (i = 0; i < tabs + 1; i++) {
00163 fprintf(f, "\t");
00164 }
00165 fprintf(f, "<item>%lu</item>\n", val);
00166 for (i = 0; i < tabs; i++)
00167 fprintf(f, "\t");
00168 fprintf(f, "</criteria>\n");
00169 }
00170
00171 static void filter_uint_print(const char *criteria_name, const unsigned int val, FILE * f, int tabs)
00172 {
00173 int i;
00174 for (i = 0; i < tabs; i++)
00175 fprintf(f, "\t");
00176 fprintf(f, "<criteria type=\"%s\">\n", criteria_name);
00177 for (i = 0; i < tabs + 1; i++) {
00178 fprintf(f, "\t");
00179 }
00180 fprintf(f, "<item>%u</item>\n", val);
00181 for (i = 0; i < tabs; i++)
00182 fprintf(f, "\t");
00183 fprintf(f, "</criteria>\n");
00184 }
00185
00186 static void filter_int_print(const char *criteria_name, const int val, FILE * f, int tabs)
00187 {
00188 int i;
00189 for (i = 0; i < tabs; i++)
00190 fprintf(f, "\t");
00191 fprintf(f, "<criteria type=\"%s\">\n", criteria_name);
00192 for (i = 0; i < tabs + 1; i++) {
00193 fprintf(f, "\t");
00194 }
00195 fprintf(f, "<item>%d</item>\n", val);
00196 for (i = 0; i < tabs; i++)
00197 fprintf(f, "\t");
00198 fprintf(f, "</criteria>\n");
00199 }
00200
00201
00202
00203 static bool filter_src_user_is_set(const seaudit_filter_t * filter)
00204 {
00205 return filter->src_users != NULL;
00206 }
00207
00208 static int filter_src_user_support(const seaudit_message_t * msg)
00209 {
00210 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->suser != NULL;
00211 }
00212
00213 static int filter_src_user_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00214 {
00215 size_t i;
00216 return apol_vector_get_index(filter->src_users, msg->data.avc->suser, apol_str_strcmp, NULL, &i) == 0;
00217 }
00218
00219 static int filter_src_user_read(seaudit_filter_t * filter, const xmlChar * ch)
00220 {
00221 return filter_string_vector_read(&filter->src_users, ch);
00222 }
00223
00224 static void filter_src_user_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00225 {
00226 filter_string_vector_print(name, filter->src_users, f, tabs);
00227 }
00228
00229 static bool filter_src_role_is_set(const seaudit_filter_t * filter)
00230 {
00231 return filter->src_roles != NULL;
00232 }
00233
00234 static int filter_src_role_support(const seaudit_message_t * msg)
00235 {
00236 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->srole != NULL;
00237 }
00238
00239 static int filter_src_role_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00240 {
00241 size_t i;
00242 return apol_vector_get_index(filter->src_roles, msg->data.avc->srole, apol_str_strcmp, NULL, &i) == 0;
00243 }
00244
00245 static int filter_src_role_read(seaudit_filter_t * filter, const xmlChar * ch)
00246 {
00247 return filter_string_vector_read(&filter->src_roles, ch);
00248 }
00249
00250 static void filter_src_role_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00251 {
00252 filter_string_vector_print(name, filter->src_roles, f, tabs);
00253 }
00254
00255 static bool filter_src_type_is_set(const seaudit_filter_t * filter)
00256 {
00257 return filter->src_types != NULL;
00258 }
00259
00260 static int filter_src_type_support(const seaudit_message_t * msg)
00261 {
00262 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->stype != NULL;
00263 }
00264
00265 static int filter_src_type_read(seaudit_filter_t * filter, const xmlChar * ch)
00266 {
00267 return filter_string_vector_read(&filter->src_types, ch);
00268 }
00269
00270 static int filter_src_type_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00271 {
00272 size_t i;
00273 return apol_vector_get_index(filter->src_types, msg->data.avc->stype, apol_str_strcmp, NULL, &i) == 0;
00274 }
00275
00276 static void filter_src_type_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00277 {
00278 filter_string_vector_print(name, filter->src_types, f, tabs);
00279 }
00280
00281 static bool filter_tgt_user_is_set(const seaudit_filter_t * filter)
00282 {
00283 return filter->tgt_users != NULL;
00284 }
00285
00286 static int filter_tgt_user_support(const seaudit_message_t * msg)
00287 {
00288 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->tuser != NULL;
00289 }
00290
00291 static int filter_tgt_user_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00292 {
00293 size_t i;
00294 return apol_vector_get_index(filter->tgt_users, msg->data.avc->tuser, apol_str_strcmp, NULL, &i) == 0;
00295 }
00296
00297 static int filter_tgt_user_read(seaudit_filter_t * filter, const xmlChar * ch)
00298 {
00299 return filter_string_vector_read(&filter->tgt_users, ch);
00300 }
00301
00302 static void filter_tgt_user_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00303 {
00304 filter_string_vector_print(name, filter->tgt_users, f, tabs);
00305 }
00306
00307 static bool filter_tgt_role_is_set(const seaudit_filter_t * filter)
00308 {
00309 return filter->tgt_roles != NULL;
00310 }
00311
00312 static int filter_tgt_role_support(const seaudit_message_t * msg)
00313 {
00314 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->trole != NULL;
00315 }
00316
00317 static int filter_tgt_role_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00318 {
00319 size_t i;
00320 return apol_vector_get_index(filter->tgt_roles, msg->data.avc->trole, apol_str_strcmp, NULL, &i) == 0;
00321 }
00322
00323 static int filter_tgt_role_read(seaudit_filter_t * filter, const xmlChar * ch)
00324 {
00325 return filter_string_vector_read(&filter->tgt_roles, ch);
00326 }
00327
00328 static void filter_tgt_role_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00329 {
00330 filter_string_vector_print(name, filter->tgt_roles, f, tabs);
00331 }
00332
00333 static bool filter_tgt_type_is_set(const seaudit_filter_t * filter)
00334 {
00335 return filter->tgt_types != NULL;
00336 }
00337
00338 static int filter_tgt_type_support(const seaudit_message_t * msg)
00339 {
00340 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->ttype != NULL;
00341 }
00342
00343 static int filter_tgt_type_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00344 {
00345 size_t i;
00346 return apol_vector_get_index(filter->tgt_types, msg->data.avc->ttype, apol_str_strcmp, NULL, &i) == 0;
00347 }
00348
00349 static int filter_tgt_type_read(seaudit_filter_t * filter, const xmlChar * ch)
00350 {
00351 return filter_string_vector_read(&filter->tgt_types, ch);
00352 }
00353
00354 static void filter_tgt_type_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00355 {
00356 filter_string_vector_print(name, filter->tgt_types, f, tabs);
00357 }
00358
00359 static bool filter_tgt_class_is_set(const seaudit_filter_t * filter)
00360 {
00361 return filter->tgt_classes != NULL;
00362 }
00363
00364 static int filter_tgt_class_support(const seaudit_message_t * msg)
00365 {
00366 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->tclass != NULL;
00367 }
00368
00369 static int filter_tgt_class_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00370 {
00371 size_t i;
00372 return apol_vector_get_index(filter->tgt_classes, msg->data.avc->tclass, apol_str_strcmp, NULL, &i) == 0;
00373 }
00374
00375 static int filter_tgt_class_read(seaudit_filter_t * filter, const xmlChar * ch)
00376 {
00377 return filter_string_vector_read(&filter->tgt_classes, ch);
00378 }
00379
00380 static void filter_tgt_class_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00381 {
00382 filter_string_vector_print(name, filter->tgt_classes, f, tabs);
00383 }
00384
00385 static bool filter_perm_is_set(const seaudit_filter_t * filter)
00386 {
00387 return filter->perm != NULL;
00388 }
00389
00390 static int filter_perm_support(const seaudit_message_t * msg)
00391 {
00392 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->perms != NULL &&
00393 apol_vector_get_size(msg->data.avc->perms) >= 1;
00394 }
00395
00396 static int filter_perm_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00397 {
00398 size_t i;
00399 for (i = 0; i < apol_vector_get_size(msg->data.avc->perms); i++) {
00400 const char *p = apol_vector_get_element(msg->data.avc->perms, i);
00401 if (fnmatch(filter->perm, p, 0) == 0) {
00402 return 1;
00403 }
00404 }
00405 return 0;
00406 }
00407
00408 static int filter_perm_read(seaudit_filter_t * filter, const xmlChar * ch)
00409 {
00410 return filter_string_read(&filter->perm, ch);
00411 }
00412
00413 static void filter_perm_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00414 {
00415 filter_string_print(name, filter->perm, f, tabs);
00416 }
00417
00418 static bool filter_exe_is_set(const seaudit_filter_t * filter)
00419 {
00420 return filter->exe != NULL;
00421 }
00422
00423 static int filter_exe_support(const seaudit_message_t * msg)
00424 {
00425 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->exe != NULL;
00426 }
00427
00428 static int filter_exe_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00429 {
00430 return fnmatch(filter->exe, msg->data.avc->exe, 0) == 0;
00431 }
00432
00433 static int filter_exe_read(seaudit_filter_t * filter, const xmlChar * ch)
00434 {
00435 return filter_string_read(&filter->exe, ch);
00436 }
00437
00438 static void filter_exe_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00439 {
00440 filter_string_print(name, filter->exe, f, tabs);
00441 }
00442
00443 static bool filter_host_is_set(const seaudit_filter_t * filter)
00444 {
00445 return filter->host != NULL;
00446 }
00447
00448 static int filter_host_support(const seaudit_message_t * msg)
00449 {
00450 return msg->host != NULL;
00451 }
00452
00453 static int filter_host_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00454 {
00455 return fnmatch(filter->host, msg->host, 0) == 0;
00456 }
00457
00458 static int filter_host_read(seaudit_filter_t * filter, const xmlChar * ch)
00459 {
00460 return filter_string_read(&filter->host, ch);
00461 }
00462
00463 static void filter_host_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00464 {
00465 filter_string_print(name, filter->host, f, tabs);
00466 }
00467
00468 static bool filter_path_is_set(const seaudit_filter_t * filter)
00469 {
00470 return filter->path != NULL;
00471 }
00472
00473 static int filter_path_support(const seaudit_message_t * msg)
00474 {
00475 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->path != NULL;
00476 }
00477
00478 static int filter_path_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00479 {
00480 return fnmatch(filter->path, msg->data.avc->path, 0) == 0;
00481 }
00482
00483 static int filter_path_read(seaudit_filter_t * filter, const xmlChar * ch)
00484 {
00485 return filter_string_read(&filter->path, ch);
00486 }
00487
00488 static void filter_path_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00489 {
00490 filter_string_print(name, filter->path, f, tabs);
00491 }
00492
00493 static bool filter_inode_is_set(const seaudit_filter_t * filter)
00494 {
00495 return filter->inode != 0;
00496 }
00497
00498 static int filter_inode_support(const seaudit_message_t * msg)
00499 {
00500 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->is_inode;
00501 }
00502
00503 static int filter_inode_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00504 {
00505 return filter->inode == msg->data.avc->inode;
00506 }
00507
00508 static int filter_inode_read(seaudit_filter_t * filter, const xmlChar * ch)
00509 {
00510 return filter_ulong_read(&filter->inode, ch);
00511 }
00512
00513 static void filter_inode_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00514 {
00515 filter_ulong_print(name, filter->inode, f, tabs);
00516 }
00517
00518 static bool filter_pid_is_set(const seaudit_filter_t * filter)
00519 {
00520 return filter->pid != 0;
00521 }
00522
00523 static int filter_pid_support(const seaudit_message_t * msg)
00524 {
00525 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->is_pid;
00526 }
00527
00528 static int filter_pid_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00529 {
00530 return filter->pid == msg->data.avc->pid;
00531 }
00532
00533 static int filter_pid_read(seaudit_filter_t * filter, const xmlChar * ch)
00534 {
00535 return filter_uint_read(&filter->pid, ch);
00536 }
00537
00538 static void filter_pid_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00539 {
00540 filter_uint_print(name, filter->pid, f, tabs);
00541 }
00542
00543 static bool filter_comm_is_set(const seaudit_filter_t * filter)
00544 {
00545 return filter->comm != NULL;
00546 }
00547
00548 static int filter_comm_support(const seaudit_message_t * msg)
00549 {
00550 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->comm != NULL;
00551 }
00552
00553 static int filter_comm_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00554 {
00555 return fnmatch(filter->comm, msg->data.avc->comm, 0) == 0;
00556 }
00557
00558 static int filter_comm_read(seaudit_filter_t * filter, const xmlChar * ch)
00559 {
00560 return filter_string_read(&filter->comm, ch);
00561 }
00562
00563 static void filter_comm_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00564 {
00565 filter_string_print(name, filter->comm, f, tabs);
00566 }
00567
00568 static bool filter_anyaddr_is_set(const seaudit_filter_t * filter)
00569 {
00570 return filter->anyaddr != NULL;
00571 }
00572
00573 static int filter_anyaddr_support(const seaudit_message_t * msg)
00574 {
00575 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && (msg->data.avc->saddr != NULL
00576 || msg->data.avc->daddr != NULL
00577 || msg->data.avc->faddr != NULL
00578 || msg->data.avc->laddr != NULL || msg->data.avc->ipaddr != NULL);
00579 }
00580
00581 static int filter_anyaddr_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00582 {
00583 if (msg->data.avc->saddr && fnmatch(filter->anyaddr, msg->data.avc->saddr, 0) == 0)
00584 return 1;
00585 if (msg->data.avc->daddr && fnmatch(filter->anyaddr, msg->data.avc->daddr, 0) == 0)
00586 return 1;
00587 if (msg->data.avc->faddr && fnmatch(filter->anyaddr, msg->data.avc->faddr, 0) == 0)
00588 return 1;
00589 if (msg->data.avc->laddr && fnmatch(filter->anyaddr, msg->data.avc->laddr, 0) == 0)
00590 return 1;
00591 if (msg->data.avc->ipaddr && fnmatch(filter->anyaddr, msg->data.avc->ipaddr, 0) == 0)
00592 return 1;
00593 return 0;
00594 }
00595
00596 static int filter_anyaddr_read(seaudit_filter_t * filter, const xmlChar * ch)
00597 {
00598 return filter_string_read(&filter->anyaddr, ch);
00599 }
00600
00601 static void filter_anyaddr_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00602 {
00603 filter_string_print(name, filter->anyaddr, f, tabs);
00604 }
00605
00606 static bool filter_anyport_is_set(const seaudit_filter_t * filter)
00607 {
00608 return filter->anyport != 0;
00609 }
00610
00611 static int filter_anyport_support(const seaudit_message_t * msg)
00612 {
00613 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && (msg->data.avc->port != 0 ||
00614 msg->data.avc->source != 0 ||
00615 msg->data.avc->dest != 0 ||
00616 msg->data.avc->fport != 0 || msg->data.avc->lport != 0);
00617 }
00618
00619 static int filter_anyport_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00620 {
00621 if (msg->data.avc->port != 0 && filter->anyport == msg->data.avc->port) {
00622 return 1;
00623 }
00624 if (msg->data.avc->source != 0 && filter->anyport == msg->data.avc->source) {
00625 return 1;
00626 }
00627 if (msg->data.avc->dest != 0 && filter->anyport == msg->data.avc->dest) {
00628 return 1;
00629 }
00630 if (msg->data.avc->fport != 0 && filter->anyport == msg->data.avc->fport) {
00631 return 1;
00632 }
00633 if (msg->data.avc->lport != 0 && filter->anyport == msg->data.avc->lport) {
00634 return 1;
00635 }
00636 return 0;
00637 }
00638
00639 static int filter_anyport_read(seaudit_filter_t * filter, const xmlChar * ch)
00640 {
00641 return filter_int_read(&filter->anyport, ch);
00642 }
00643
00644 static void filter_anyport_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00645 {
00646 filter_int_print(name, filter->anyport, f, tabs);
00647 }
00648
00649 static bool filter_laddr_is_set(const seaudit_filter_t * filter)
00650 {
00651 return filter->laddr != NULL;
00652 }
00653
00654 static int filter_laddr_support(const seaudit_message_t * msg)
00655 {
00656 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->laddr != NULL;
00657 }
00658
00659 static int filter_laddr_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00660 {
00661 return fnmatch(filter->laddr, msg->data.avc->laddr, 0) == 0;
00662 }
00663
00664 static int filter_laddr_read(seaudit_filter_t * filter, const xmlChar * ch)
00665 {
00666 return filter_string_read(&filter->laddr, ch);
00667 }
00668
00669 static void filter_laddr_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00670 {
00671 filter_string_print(name, filter->laddr, f, tabs);
00672 }
00673
00674 static bool filter_lport_is_set(const seaudit_filter_t * filter)
00675 {
00676 return filter->lport != 0;
00677 }
00678
00679 static int filter_lport_support(const seaudit_message_t * msg)
00680 {
00681 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->lport != 0;
00682 }
00683
00684 static int filter_lport_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00685 {
00686 return filter->lport == msg->data.avc->lport;
00687 }
00688
00689 static int filter_lport_read(seaudit_filter_t * filter, const xmlChar * ch)
00690 {
00691 return filter_int_read(&filter->lport, ch);
00692 }
00693
00694 static void filter_lport_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00695 {
00696 filter_int_print(name, filter->lport, f, tabs);
00697 }
00698
00699 static bool filter_faddr_is_set(const seaudit_filter_t * filter)
00700 {
00701 return filter->faddr != NULL;
00702 }
00703
00704 static int filter_faddr_support(const seaudit_message_t * msg)
00705 {
00706 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->faddr != NULL;
00707 }
00708
00709 static int filter_faddr_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00710 {
00711 return fnmatch(filter->faddr, msg->data.avc->faddr, 0) == 0;
00712 }
00713
00714 static int filter_faddr_read(seaudit_filter_t * filter, const xmlChar * ch)
00715 {
00716 return filter_string_read(&filter->faddr, ch);
00717 }
00718
00719 static void filter_faddr_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00720 {
00721 filter_string_print(name, filter->faddr, f, tabs);
00722 }
00723
00724 static bool filter_fport_is_set(const seaudit_filter_t * filter)
00725 {
00726 return filter->fport != 0;
00727 }
00728
00729 static int filter_fport_support(const seaudit_message_t * msg)
00730 {
00731 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->fport != 0;
00732 }
00733
00734 static int filter_fport_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00735 {
00736 return filter->fport == msg->data.avc->fport;
00737 }
00738
00739 static int filter_fport_read(seaudit_filter_t * filter, const xmlChar * ch)
00740 {
00741 return filter_int_read(&filter->fport, ch);
00742 }
00743
00744 static void filter_fport_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00745 {
00746 filter_int_print(name, filter->fport, f, tabs);
00747 }
00748
00749 static bool filter_saddr_is_set(const seaudit_filter_t * filter)
00750 {
00751 return filter->saddr != NULL;
00752 }
00753
00754 static int filter_saddr_support(const seaudit_message_t * msg)
00755 {
00756 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->saddr != NULL;
00757 }
00758
00759 static int filter_saddr_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00760 {
00761 return fnmatch(filter->saddr, msg->data.avc->saddr, 0) == 0;
00762 }
00763
00764 static int filter_saddr_read(seaudit_filter_t * filter, const xmlChar * ch)
00765 {
00766 return filter_string_read(&filter->saddr, ch);
00767 }
00768
00769 static void filter_saddr_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00770 {
00771 filter_string_print(name, filter->saddr, f, tabs);
00772 }
00773
00774 static bool filter_sport_is_set(const seaudit_filter_t * filter)
00775 {
00776 return filter->sport != 0;
00777 }
00778
00779 static int filter_sport_support(const seaudit_message_t * msg)
00780 {
00781 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->source != 0;
00782 }
00783
00784 static int filter_sport_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00785 {
00786 return filter->sport == msg->data.avc->source;
00787 }
00788
00789 static int filter_sport_read(seaudit_filter_t * filter, const xmlChar * ch)
00790 {
00791 return filter_int_read(&filter->sport, ch);
00792 }
00793
00794 static void filter_sport_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00795 {
00796 filter_int_print(name, filter->sport, f, tabs);
00797 }
00798
00799 static bool filter_daddr_is_set(const seaudit_filter_t * filter)
00800 {
00801 return filter->daddr != NULL;
00802 }
00803
00804 static int filter_daddr_support(const seaudit_message_t * msg)
00805 {
00806 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->daddr != NULL;
00807 }
00808
00809 static int filter_daddr_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00810 {
00811 return fnmatch(filter->daddr, msg->data.avc->daddr, 0) == 0;
00812 }
00813
00814 static int filter_daddr_read(seaudit_filter_t * filter, const xmlChar * ch)
00815 {
00816 return filter_string_read(&filter->daddr, ch);
00817 }
00818
00819 static void filter_daddr_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00820 {
00821 filter_string_print(name, filter->daddr, f, tabs);
00822 }
00823
00824 static bool filter_dport_is_set(const seaudit_filter_t * filter)
00825 {
00826 return filter->dport != 0;
00827 }
00828
00829 static int filter_dport_support(const seaudit_message_t * msg)
00830 {
00831 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->dest != 0;
00832 }
00833
00834 static int filter_dport_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00835 {
00836 return filter->dport == msg->data.avc->dest;
00837 }
00838
00839 static int filter_dport_read(seaudit_filter_t * filter, const xmlChar * ch)
00840 {
00841 return filter_int_read(&filter->dport, ch);
00842 }
00843
00844 static void filter_dport_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00845 {
00846 filter_int_print(name, filter->dport, f, tabs);
00847 }
00848
00849 static bool filter_port_is_set(const seaudit_filter_t * filter)
00850 {
00851 return filter->port != 0;
00852 }
00853
00854 static int filter_port_support(const seaudit_message_t * msg)
00855 {
00856 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->port != 0;
00857 }
00858
00859 static int filter_port_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00860 {
00861 return filter->port == msg->data.avc->port;
00862 }
00863
00864 static int filter_port_read(seaudit_filter_t * filter, const xmlChar * ch)
00865 {
00866 return filter_int_read(&filter->port, ch);
00867 }
00868
00869 static void filter_port_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00870 {
00871 filter_int_print(name, filter->port, f, tabs);
00872 }
00873
00874 static bool filter_netif_is_set(const seaudit_filter_t * filter)
00875 {
00876 return filter->netif != NULL;
00877 }
00878
00879 static int filter_netif_support(const seaudit_message_t * msg)
00880 {
00881 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->netif != NULL;
00882 }
00883
00884 static int filter_netif_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00885 {
00886 return strcmp(filter->netif, msg->data.avc->netif) == 0;
00887 }
00888
00889 static int filter_netif_read(seaudit_filter_t * filter, const xmlChar * ch)
00890 {
00891 return filter_string_read(&filter->netif, ch);
00892 }
00893
00894 static void filter_netif_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00895 {
00896 filter_string_print(name, filter->netif, f, tabs);
00897 }
00898
00899 static bool filter_key_is_set(const seaudit_filter_t * filter)
00900 {
00901 return filter->key != 0;
00902 }
00903
00904 static int filter_key_support(const seaudit_message_t * msg)
00905 {
00906 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->is_key;
00907 }
00908
00909 static int filter_key_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00910 {
00911 return filter->key == msg->data.avc->key;
00912 }
00913
00914 static int filter_key_read(seaudit_filter_t * filter, const xmlChar * ch)
00915 {
00916 return filter_int_read(&filter->key, ch);
00917 }
00918
00919 static void filter_key_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00920 {
00921 filter_int_print(name, filter->key, f, tabs);
00922 }
00923
00924 static bool filter_cap_is_set(const seaudit_filter_t * filter)
00925 {
00926 return filter->cap != 0;
00927 }
00928
00929 static int filter_cap_support(const seaudit_message_t * msg)
00930 {
00931 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && msg->data.avc->is_capability;
00932 }
00933
00934 static int filter_cap_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00935 {
00936 return filter->key == msg->data.avc->capability;
00937 }
00938
00939 static int filter_cap_read(seaudit_filter_t * filter, const xmlChar * ch)
00940 {
00941 return filter_int_read(&filter->cap, ch);
00942 }
00943
00944 static void filter_cap_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00945 {
00946 filter_int_print(name, filter->cap, f, tabs);
00947 }
00948
00949 static bool filter_avc_msg_type_is_set(const seaudit_filter_t * filter)
00950 {
00951 return filter->avc_msg_type != SEAUDIT_AVC_UNKNOWN;
00952 }
00953
00954 static int filter_avc_msg_type_support(const seaudit_message_t * msg __attribute__ ((unused)))
00955 {
00956 return 1;
00957 }
00958
00959 static int filter_avc_msg_type_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
00960 {
00961 return msg->type == SEAUDIT_MESSAGE_TYPE_AVC && filter->avc_msg_type == msg->data.avc->msg;
00962 }
00963
00964 static int filter_avc_msg_type_read(seaudit_filter_t * filter, const xmlChar * ch)
00965 {
00966 char *s;
00967 if ((s = xmlURIUnescapeString((const char *)ch, 0, NULL)) == NULL) {
00968 return -1;
00969 }
00970 filter->avc_msg_type = atoi(s);
00971 free(s);
00972 return 0;
00973 }
00974
00975 static void filter_avc_msg_type_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
00976 {
00977 int i;
00978 if (filter->avc_msg_type == SEAUDIT_AVC_UNKNOWN) {
00979 return;
00980 }
00981 for (i = 0; i < tabs; i++)
00982 fprintf(f, "\t");
00983 fprintf(f, "<criteria type=\"%s\">\n", name);
00984 for (i = 0; i < tabs + 1; i++) {
00985 fprintf(f, "\t");
00986 }
00987 fprintf(f, "<item>%d</item>\n", filter->avc_msg_type);
00988 for (i = 0; i < tabs; i++)
00989 fprintf(f, "\t");
00990 fprintf(f, "</criteria>\n");
00991 }
00992
00993 static bool filter_date_is_set(const seaudit_filter_t * filter)
00994 {
00995 return filter->start != NULL;
00996 }
00997
00998 static int filter_date_support(const seaudit_message_t * msg)
00999 {
01000 return msg->date_stamp != NULL;
01001 }
01002
01003
01004
01005
01006
01007 static int filter_date_comp(const struct tm *t1, const struct tm *t2)
01008 {
01009
01010
01011 int retval;
01012 if (t1->tm_year != 0 && t2->tm_year != 0 && (retval = t1->tm_year - t2->tm_year) != 0) {
01013 return retval;
01014 }
01015 if ((retval = t1->tm_mon - t2->tm_mon) != 0) {
01016 return retval;
01017 }
01018 if ((retval = t1->tm_mday - t2->tm_mday) != 0) {
01019 return retval;
01020 }
01021 if ((retval = t1->tm_hour - t2->tm_hour) != 0) {
01022 return retval;
01023 }
01024 if ((retval = t1->tm_min - t2->tm_min) != 0) {
01025 return retval;
01026 }
01027 if ((retval = t1->tm_sec - t2->tm_sec) != 0) {
01028 return retval;
01029 }
01030 return 0;
01031 }
01032
01033 static int filter_date_accept(const seaudit_filter_t * filter, const seaudit_message_t * msg)
01034 {
01035 int compval = filter_date_comp(filter->start, msg->date_stamp);
01036 if (filter->date_match == SEAUDIT_FILTER_DATE_MATCH_BEFORE) {
01037 return compval > 0;
01038 } else if (filter->date_match == SEAUDIT_FILTER_DATE_MATCH_AFTER) {
01039 return compval < 0;
01040 } else {
01041 if (compval > 0)
01042 return 0;
01043 compval = filter_date_comp(msg->date_stamp, filter->end);
01044 return compval < 0;
01045 }
01046 }
01047
01048 static int filter_date_read(seaudit_filter_t * filter, const xmlChar * ch)
01049 {
01050 char *s;
01051 if ((s = xmlURIUnescapeString((const char *)ch, 0, NULL)) == NULL) {
01052 return -1;
01053 }
01054 if (filter->start == NULL) {
01055 if ((filter->start = calloc(1, sizeof(*(filter->start)))) == NULL) {
01056 free(s);
01057 return -1;
01058 }
01059 strptime(s, "%a %b %d %T %Y", filter->start);
01060 } else if (filter->end == NULL) {
01061 if ((filter->end = calloc(1, sizeof(*(filter->end)))) == NULL) {
01062 free(s);
01063 return -1;
01064 }
01065 strptime(s, "%a %b %d %T %Y", filter->end);
01066 } else {
01067 filter->date_match = atoi(s);
01068 }
01069 free(s);
01070 return 0;
01071 }
01072
01073 static void filter_date_print(const seaudit_filter_t * filter, const char *name, FILE * f, int tabs)
01074 {
01075 int i;
01076 xmlChar *s, *escaped;
01077 if (filter->start == NULL) {
01078 return;
01079 }
01080 for (i = 0; i < tabs; i++)
01081 fprintf(f, "\t");
01082 fprintf(f, "<criteria type=\"%s\">\n", name);
01083 s = xmlCharStrdup(asctime(filter->start));
01084 escaped = xmlURIEscapeStr(s, NULL);
01085 for (i = 0; i < tabs + 1; i++) {
01086 fprintf(f, "\t");
01087 }
01088 fprintf(f, "<item>%s</item>\n", escaped);
01089 free(s);
01090 free(escaped);
01091 s = xmlCharStrdup(asctime(filter->end));
01092 escaped = xmlURIEscapeStr(s, NULL);
01093 for (i = 0; i < tabs + 1; i++)
01094 fprintf(f, "\t");
01095 fprintf(f, "<item>%s</item>\n", escaped);
01096 free(s);
01097 free(escaped);
01098 for (i = 0; i < tabs + 1; i++)
01099 fprintf(f, "\t");
01100 fprintf(f, "<item>%d</item>\n", filter->date_match);
01101 for (i = 0; i < tabs; i++)
01102 fprintf(f, "\t");
01103 fprintf(f, "</criteria>\n");
01104 }
01105
01106 typedef bool(filter_is_set_func) (const seaudit_filter_t * filter);
01107 typedef int (filter_support_func) (const seaudit_message_t * msg);
01108 typedef int (filter_accept_func) (const seaudit_filter_t * filter, const seaudit_message_t * msg);
01109 typedef void (filter_print_func) (const seaudit_filter_t * filter, const char *name, FILE * f, int tabs);
01110
01111 struct filter_criteria_t
01112 {
01113 const char *name;
01114 filter_is_set_func *is_set;
01115 filter_support_func *support;
01116 filter_accept_func *accept;
01117 filter_read_func *read;
01118 filter_print_func *print;
01119 };
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129 static const struct filter_criteria_t filter_criteria[] = {
01130 {"src_user", filter_src_user_is_set, filter_src_user_support, filter_src_user_accept, filter_src_user_read,
01131 filter_src_user_print},
01132 {"src_role", filter_src_role_is_set, filter_src_role_support, filter_src_role_accept, filter_src_role_read,
01133 filter_src_role_print},
01134 {"src_type", filter_src_type_is_set, filter_src_type_support, filter_src_type_accept, filter_src_type_read,
01135 filter_src_type_print},
01136 {"tgt_user", filter_tgt_user_is_set, filter_tgt_user_support, filter_tgt_user_accept, filter_tgt_user_read,
01137 filter_tgt_user_print},
01138 {"tgt_role", filter_tgt_role_is_set, filter_tgt_role_support, filter_tgt_role_accept, filter_tgt_role_read,
01139 filter_tgt_role_print},
01140 {"tgt_type", filter_tgt_type_is_set, filter_tgt_type_support, filter_tgt_type_accept, filter_tgt_type_read,
01141 filter_tgt_type_print},
01142 {"obj_class", filter_tgt_class_is_set, filter_tgt_class_support, filter_tgt_class_accept, filter_tgt_class_read,
01143 filter_tgt_class_print},
01144 {"perm", filter_perm_is_set, filter_perm_support, filter_perm_accept, filter_perm_read, filter_perm_print},
01145 {"exe", filter_exe_is_set, filter_exe_support, filter_exe_accept, filter_exe_read, filter_exe_print},
01146 {"host", filter_host_is_set, filter_host_support, filter_host_accept, filter_host_read, filter_host_print},
01147 {"path", filter_path_is_set, filter_path_support, filter_path_accept, filter_path_read, filter_path_print},
01148 {"inode", filter_inode_is_set, filter_inode_support, filter_inode_accept, filter_inode_read, filter_inode_print},
01149 {"pid", filter_pid_is_set, filter_pid_support, filter_pid_accept, filter_pid_read, filter_pid_print},
01150 {"comm", filter_comm_is_set, filter_comm_support, filter_comm_accept, filter_comm_read, filter_comm_print},
01151 {"ipaddr", filter_anyaddr_is_set, filter_anyaddr_support, filter_anyaddr_accept, filter_anyaddr_read, filter_anyaddr_print},
01152 {"anyport", filter_anyport_is_set, filter_anyport_support, filter_anyport_accept, filter_anyport_read,
01153 filter_anyport_print},
01154 {"laddr", filter_laddr_is_set, filter_laddr_support, filter_laddr_accept, filter_laddr_read, filter_laddr_print},
01155 {"lport", filter_lport_is_set, filter_lport_support, filter_lport_accept, filter_lport_read, filter_lport_print},
01156 {"faddr", filter_faddr_is_set, filter_faddr_support, filter_faddr_accept, filter_faddr_read, filter_faddr_print},
01157 {"fport", filter_fport_is_set, filter_fport_support, filter_fport_accept, filter_fport_read, filter_fport_print},
01158 {"saddr", filter_saddr_is_set, filter_saddr_support, filter_saddr_accept, filter_saddr_read, filter_saddr_print},
01159 {"sport", filter_sport_is_set, filter_sport_support, filter_sport_accept, filter_sport_read, filter_sport_print},
01160 {"daddr", filter_daddr_is_set, filter_daddr_support, filter_daddr_accept, filter_daddr_read, filter_daddr_print},
01161 {"dport", filter_dport_is_set, filter_dport_support, filter_dport_accept, filter_dport_read, filter_dport_print},
01162 {"port", filter_port_is_set, filter_port_support, filter_port_accept, filter_port_read, filter_port_print},
01163 {"netif", filter_netif_is_set, filter_netif_support, filter_netif_accept, filter_netif_read, filter_netif_print},
01164 {"key", filter_key_is_set, filter_key_support, filter_key_accept, filter_key_read, filter_key_print},
01165 {"cap", filter_cap_is_set, filter_cap_support, filter_cap_accept, filter_cap_read, filter_cap_print},
01166 {"msg", filter_avc_msg_type_is_set, filter_avc_msg_type_support, filter_avc_msg_type_accept, filter_avc_msg_type_read,
01167 filter_avc_msg_type_print},
01168 {"date_time", filter_date_is_set, filter_date_support, filter_date_accept, filter_date_read, filter_date_print}
01169 };
01170
01171
01172
01173 int filter_is_accepted(const seaudit_filter_t * filter, const seaudit_message_t * msg)
01174 {
01175 bool tried_criterion = false;
01176 int acceptval;
01177 size_t i;
01178
01179 for (i = 0; i < sizeof(filter_criteria) / sizeof(filter_criteria[0]); i++) {
01180 if (filter_criteria[i].is_set(filter)) {
01181 tried_criterion = true;
01182 if (filter_criteria[i].support(msg)) {
01183 acceptval = filter_criteria[i].accept(filter, msg);
01184 } else if (filter->strict) {
01185
01186
01187
01188 acceptval = 0;
01189 } else {
01190
01191
01192
01193 continue;
01194 }
01195 if (filter->match == SEAUDIT_FILTER_MATCH_ANY && acceptval == 1) {
01196 return 1;
01197 }
01198 if (filter->match == SEAUDIT_FILTER_MATCH_ALL && acceptval == 0) {
01199 return 0;
01200 }
01201 }
01202 }
01203 if (!tried_criterion) {
01204
01205 if (filter->strict) {
01206
01207 return 0;
01208 }
01209 return 1;
01210 }
01211 if (filter->match == SEAUDIT_FILTER_MATCH_ANY) {
01212
01213 return 0;
01214 }
01215
01216 return 1;
01217 }
01218
01219 static bool filter_parse_is_valid_tag(const xmlChar * tag)
01220 {
01221 static const char *parse_valid_tags[] = { "item", "criteria", "view", "filter", "desc", NULL };
01222 size_t i;
01223 for (i = 0; parse_valid_tags[i] != NULL; i++) {
01224 if (xmlStrcmp(tag, (xmlChar *) parse_valid_tags[i]) == 0) {
01225 return 1;
01226 }
01227 }
01228 return 0;
01229 }
01230
01231 static filter_read_func *filter_get_read_func(const xmlChar * name)
01232 {
01233 size_t i;
01234 for (i = 0; i < sizeof(filter_criteria) / sizeof(filter_criteria[0]); i++) {
01235 if (xmlStrcmp(name, (xmlChar *) filter_criteria[i].name) == 0) {
01236 return filter_criteria[i].read;
01237 }
01238 }
01239 return NULL;
01240 }
01241
01242 static void filter_parse_start_element(void *user_data, const xmlChar * name, const xmlChar ** attrs)
01243 {
01244 struct filter_parse_state *state = user_data;
01245 size_t i;
01246 if (!filter_parse_is_valid_tag(name)) {
01247 state->warnings = 1;
01248 return;
01249 }
01250 if (xmlStrcmp(name, (xmlChar *) "view") == 0) {
01251 for (i = 0; attrs[i] != NULL && attrs[i + 1] != NULL; i += 2) {
01252 if (xmlStrcmp(attrs[i], (xmlChar *) "name") == 0) {
01253 free(state->view_name);
01254 state->view_name = xmlURIUnescapeString((const char *)attrs[i + 1], 0, NULL);
01255 } else if (xmlStrcmp(attrs[i], (xmlChar *) "match") == 0) {
01256 if (xmlStrcmp(attrs[i + 1], (xmlChar *) "all") == 0) {
01257 state->view_match = SEAUDIT_FILTER_MATCH_ALL;
01258 } else if (xmlStrcmp(attrs[i + 1], (xmlChar *) "any") == 0) {
01259 state->view_match = SEAUDIT_FILTER_MATCH_ANY;
01260 }
01261 } else if (xmlStrcmp(attrs[i], (xmlChar *) "show") == 0) {
01262 if (xmlStrcmp(attrs[i + 1], (xmlChar *) "true") == 0) {
01263 state->view_visible = SEAUDIT_FILTER_VISIBLE_SHOW;
01264 } else if (xmlStrcmp(attrs[i + 1], (xmlChar *) "hide") == 0) {
01265 state->view_visible = SEAUDIT_FILTER_VISIBLE_HIDE;
01266 }
01267 }
01268 }
01269 } else if (xmlStrcmp(name, (xmlChar *) "filter") == 0) {
01270
01271 char *filter_name = NULL;
01272 seaudit_filter_match_e match = SEAUDIT_FILTER_MATCH_ALL;
01273 bool strict = false;
01274 for (i = 0; attrs[i] != NULL && attrs[i + 1] != NULL; i += 2) {
01275 if (xmlStrcmp(attrs[i], (xmlChar *) "name") == 0) {
01276 free(filter_name);
01277 filter_name = xmlURIUnescapeString((const char *)attrs[i + 1], 0, NULL);
01278 } else if (xmlStrcmp(attrs[i], (xmlChar *) "match") == 0) {
01279 if (xmlStrcmp(attrs[i + 1], (xmlChar *) "all") == 0) {
01280 match = SEAUDIT_FILTER_MATCH_ALL;
01281 } else if (xmlStrcmp(attrs[i + 1], (xmlChar *) "any") == 0) {
01282 match = SEAUDIT_FILTER_MATCH_ANY;
01283 }
01284 } else if (xmlStrcmp(attrs[i], (xmlChar *) "strict") == 0) {
01285 if (xmlStrcmp(attrs[i + 1], (xmlChar *) "true") == 0) {
01286 strict = true;
01287 } else if (xmlStrcmp(attrs[i + 1], (xmlChar *) "false") == 0) {
01288 strict = false;
01289 }
01290 }
01291 }
01292 if ((state->cur_filter = seaudit_filter_create(filter_name)) != NULL) {
01293 if (apol_vector_append(state->filters, state->cur_filter) < 0) {
01294 seaudit_filter_destroy(&state->cur_filter);
01295 } else {
01296 seaudit_filter_set_match(state->cur_filter, match);
01297 seaudit_filter_set_strict(state->cur_filter, strict);
01298 }
01299 }
01300 free(filter_name);
01301 } else if (xmlStrcmp(name, (xmlChar *) "criteria") == 0) {
01302 for (i = 0; attrs[i] != NULL && attrs[i + 1] != NULL; i += 2) {
01303 if (xmlStrcmp(attrs[i], (xmlChar *) "type") == 0) {
01304 state->cur_filter_read = filter_get_read_func(attrs[i + 1]);
01305 }
01306 }
01307 }
01308 free(state->cur_string);
01309 state->cur_string = NULL;
01310 }
01311
01312 static void filter_parse_end_element(void *user_data, const xmlChar * name)
01313 {
01314 struct filter_parse_state *state = user_data;
01315 char *s;
01316 if (!filter_parse_is_valid_tag(name)) {
01317 state->warnings = 1;
01318 return;
01319 }
01320 if (xmlStrcmp(name, (xmlChar *) "desc") == 0) {
01321 if (state->cur_filter == NULL) {
01322 state->warnings = 1;
01323 } else {
01324 s = xmlURIUnescapeString((const char *)state->cur_string, 0, NULL);
01325 seaudit_filter_set_description(state->cur_filter, s);
01326 free(s);
01327 }
01328 } else if (xmlStrcmp(name, (xmlChar *) "item") == 0) {
01329 if (state->cur_filter == NULL || state->cur_filter_read == NULL) {
01330 state->warnings = 1;
01331 } else {
01332 state->cur_filter_read(state->cur_filter, state->cur_string);
01333 }
01334 } else if (xmlStrcmp(name, (xmlChar *) "filter") == 0) {
01335 state->cur_filter = NULL;
01336 } else if (xmlStrcmp(name, (xmlChar *) "criteria") == 0) {
01337 state->cur_filter_read = NULL;
01338 }
01339 free(state->cur_string);
01340 state->cur_string = NULL;
01341 }
01342
01343 static void filter_parse_characters(void *user_data, const xmlChar * ch, int len)
01344 {
01345 struct filter_parse_state *state = user_data;
01346 free(state->cur_string);
01347 state->cur_string = xmlStrndup(ch, len);
01348 }
01349
01350 int filter_parse_xml(struct filter_parse_state *state, const char *filename)
01351 {
01352 xmlSAXHandler handler;
01353 int err;
01354
01355 memset(&handler, 0, sizeof(xmlSAXHandler));
01356 handler.startElement = filter_parse_start_element;
01357 handler.endElement = filter_parse_end_element;
01358 handler.characters = filter_parse_characters;
01359 err = xmlSAXUserParseFile(&handler, state, filename);
01360 free(state->cur_string);
01361 state->cur_string = NULL;
01362 if (err) {
01363 errno = EIO;
01364 return -1;
01365 }
01366 if (state->warnings) {
01367 return 1;
01368 }
01369 return 0;
01370 }
01371
01372 void filter_append_to_file(const seaudit_filter_t * filter, FILE * file, int tabs)
01373 {
01374 xmlChar *escaped;
01375 xmlChar *str_xml;
01376 int i;
01377 size_t j;
01378
01379 if (filter == NULL || file == NULL) {
01380 errno = EINVAL;
01381 return;
01382 }
01383
01384 if (filter->name == NULL) {
01385 str_xml = xmlCharStrdup("Unnamed");
01386 } else {
01387 str_xml = xmlCharStrdup(filter->name);
01388 }
01389 escaped = xmlURIEscapeStr(str_xml, NULL);
01390 for (i = 0; i < tabs; i++)
01391 fprintf(file, "\t");
01392 fprintf(file, "<filter name=\"%s\" match=\"%s\" strict=\"%s\">\n", escaped,
01393 filter->match == SEAUDIT_FILTER_MATCH_ALL ? "all" : "any", filter->strict ? "true" : "false");
01394 free(escaped);
01395 free(str_xml);
01396
01397 if (filter->desc != NULL) {
01398 str_xml = xmlCharStrdup(filter->desc);
01399 escaped = xmlURIEscapeStr(str_xml, NULL);
01400 for (i = 0; i < tabs + 1; i++)
01401 fprintf(file, "\t");
01402 fprintf(file, "<desc>%s</desc>\n", escaped);
01403 free(escaped);
01404 free(str_xml);
01405 }
01406 for (j = 0; j < sizeof(filter_criteria) / sizeof(filter_criteria[0]); j++) {
01407 filter_criteria[j].print(filter, filter_criteria[j].name, file, tabs + 1);
01408 }
01409 for (i = 0; i < tabs; i++)
01410 fprintf(file, "\t");
01411 fprintf(file, "</filter>\n");
01412 }