diff options
-rw-r--r-- | bin/systrace/filter.c | 78 | ||||
-rw-r--r-- | bin/systrace/policy.c | 155 | ||||
-rw-r--r-- | bin/systrace/systrace.c | 6 | ||||
-rw-r--r-- | bin/systrace/systrace.h | 20 |
4 files changed, 249 insertions, 10 deletions
diff --git a/bin/systrace/filter.c b/bin/systrace/filter.c index 5760feb0090..485275ebc18 100644 --- a/bin/systrace/filter.c +++ b/bin/systrace/filter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: filter.c,v 1.16 2002/08/08 21:18:20 provos Exp $ */ +/* $OpenBSD: filter.c,v 1.17 2002/09/23 04:41:02 itojun Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * All rights reserved. @@ -54,6 +54,8 @@ extern char cwd[]; static void logic_free(struct logic *); static int filter_match(struct intercept_tlq *, struct logic *); static void filter_review(struct filterq *); +static void filter_templates(const char *); +static int filter_template(int, struct policy *, int); static void filter_policyrecord(struct policy *, struct filter *, const char *, const char *, char *); static void filter_replace(char *, size_t, char *, char *); @@ -174,6 +176,59 @@ filter_review(struct filterq *fls) } static void +filter_templates(const char *emulation) +{ + extern struct tmplqueue templates; + struct template *template; + int i = 0; + + printf("Available Templates:\n"); + + TAILQ_FOREACH(template, &templates, next) { + if (strcmp(template->emulation, emulation)) + continue; + + i++; + printf("%d. %s - %s\n", i, + template->name, template->description); + } +} + +/* Inserts a policy from a template */ + +static int +filter_template(int fd, struct policy *policy, int count) +{ + extern struct tmplqueue templates; + struct template *template; + int i = 0; + + TAILQ_FOREACH(template, &templates, next) { + if (strcmp(template->emulation, policy->emulation)) + continue; + + i++; + if (i == count) + break; + } + + if (i != count) + return (-1); + + template = systrace_readtemplate(template->filename, policy, template); + if (template == NULL) + return (-1); + + if (filter_prepolicy(fd, policy) == -1) + return (-1); + + /* We inserted new statements into the policy */ + policy->flags |= POLICY_CHANGED; + + return (0); +} + +static void filter_policyrecord(struct policy *policy, struct filter *filter, const char *emulation, const char *name, char *rule) { @@ -338,7 +393,7 @@ filter_prepolicy(int fd, struct policy *policy) } short -filter_ask(struct intercept_tlq *tls, struct filterq *fls, +filter_ask(int fd, struct intercept_tlq *tls, struct filterq *fls, int policynr, const char *emulation, const char *name, char *output, short *pfuture, int *pflags) { @@ -435,6 +490,25 @@ filter_ask(struct intercept_tlq *tls, struct filterq *fls, } else if (!strcasecmp(line, "review") && fls != NULL) { filter_review(fls); continue; + } else if (!strcasecmp(line, "templates")) { + filter_templates(emulation); + continue; + } else if (!strncasecmp(line, "template ", 9)) { + int count = atoi(line + 9); + + if (count == 0 || + filter_template(fd, policy, count) == -1) { + printf("Syntax error.\n"); + continue; + } + + action = filter_evaluate(tls, fls, pflags); + if (action == ICPOLICY_ASK) { + printf("Filter unmatched.\n"); + continue; + } + + goto out; } if (filter_parse_simple(line, &action, pfuture) != -1) { diff --git a/bin/systrace/policy.c b/bin/systrace/policy.c index 8fb71897fed..e799d785b52 100644 --- a/bin/systrace/policy.c +++ b/bin/systrace/policy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: policy.c,v 1.19 2002/09/17 05:10:58 itojun Exp $ */ +/* $OpenBSD: policy.c,v 1.20 2002/09/23 04:41:02 itojun Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * All rights reserved. @@ -33,6 +33,7 @@ #include <sys/param.h> #include <sys/stat.h> #include <sys/tree.h> +#include <dirent.h> #include <limits.h> #include <stdlib.h> #include <string.h> @@ -103,6 +104,8 @@ static char policydir[MAXPATHLEN]; static char *groupnames[NGROUPS_MAX]; static int ngroups; +struct tmplqueue templates; + void systrace_setupdir(char *path) { @@ -159,8 +162,10 @@ systrace_initpolicy(char *file, char *path) } } - if (userpolicy) + if (userpolicy) { systrace_setupdir(path); + systrace_templatedir(); + } if (file != NULL) return (systrace_readpolicy(file)); @@ -323,6 +328,152 @@ systrace_addpolicy(const char *name) return (systrace_readpolicy(file)); } +/* + * Reads policy templates from the template directory. + * These policies can be inserted during interactive policy + * generation. + */ + +int +systrace_templatedir(void) +{ + char filename[MAXPATHLEN]; + DIR *dir = NULL; + struct stat sb; + struct dirent *dp; + struct template *template; + int off; + + TAILQ_INIT(&templates); + + if (userpolicy) { + if (strlcpy(filename, policydir, sizeof(filename)) >= + sizeof(filename)) + goto error; + if (strlcat(filename, "/templates", sizeof(filename)) >= + sizeof(filename)) + goto error; + + /* Check if template directory exists */ + if (stat(filename, &sb) != -1 && (sb.st_mode & S_IFDIR)) + dir = opendir(filename); + } + + /* Read global policy */ + if (dir == NULL) { + strlcpy(filename, POLICY_PATH, sizeof(filename)); + strlcat(filename, "/templates", sizeof(filename)); + if (stat(filename, &sb) != -1 && (sb.st_mode & S_IFDIR)) + dir = opendir(filename); + if (dir == NULL) + return (-1); + } + + if (strlcat(filename, "/", sizeof(filename)) >= sizeof(filename)) + goto error; + off = strlen(filename); + + while ((dp = readdir(dir)) != NULL) { + filename[off] = '\0'; + if (strlcat(filename, dp->d_name, sizeof(filename)) >= + sizeof(filename)) + goto error; + + if (stat(filename, &sb) == -1 || !(sb.st_mode & S_IFREG)) + continue; + + template = systrace_readtemplate(filename, NULL, NULL); + if (template == NULL) + continue; + + TAILQ_INSERT_TAIL(&templates, template, next); + } + closedir(dir); + + return (0); + + error: + errx(1, "%s: template name too long", __func__); +} + +struct template * +systrace_readtemplate(char *filename, struct policy *policy, + struct template *template) +{ + FILE *fp; + char line[_POSIX2_LINE_MAX], *p; + char *emulation, *name, *description; + int linenumber = 0; + + if ((fp = fopen(filename, "r")) == NULL) + return (NULL); + + while (fgets(line, sizeof(line), fp)) { + linenumber++; + + if ((p = systrace_policyline(line)) == NULL) { + fprintf(stderr, "%s:%d: input line too long.\n", + filename, linenumber); + template = NULL; + goto out; + } + + if (strlen(p) == 0) + continue; + + if (!strncasecmp(p, "Template: ", 10)) { + p += 10; + name = strsep(&p, ","); + if (p == NULL) + goto error; + if (strncasecmp(p, " Emulation: ", 12)) + goto error; + p += 12; + emulation = strsep(&p, ", "); + if (p == NULL) + goto error; + if (strncasecmp(p, " Description: ", 14)) + goto error; + p += 14; + description = p; + + if (template != NULL) + continue; + + template = calloc(1, sizeof(struct template)); + if (template == NULL) + err(1, "calloc"); + + template->filename = strdup(filename); + template->name = strdup(name); + template->emulation = strdup(emulation); + template->description = strdup(description); + + if (template->filename == NULL || + template->name == NULL || + template->emulation == NULL || + template->description == NULL) + err(1, "strdup"); + + continue; + } + + if (policy == NULL) + return (template); + + if (systrace_policyprocess(policy, p) == -1) + goto error; + } + + out: + fclose(fp); + return (template); + + error: + fprintf(stderr, "%s:%d: syntax error.\n", filename, linenumber); + goto out; +} + int systrace_predicatematch(char *p) { diff --git a/bin/systrace/systrace.c b/bin/systrace/systrace.c index a4ac10eaa11..b94c8c0c5d0 100644 --- a/bin/systrace/systrace.c +++ b/bin/systrace/systrace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: systrace.c,v 1.34 2002/09/17 04:57:53 itojun Exp $ */ +/* $OpenBSD: systrace.c,v 1.35 2002/09/23 04:41:02 itojun Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * All rights reserved. @@ -192,7 +192,7 @@ trans_cb(int fd, pid_t pid, int policynr, goto out; } - action = filter_ask(tls, pflq, policynr, emulation, name, + action = filter_ask(fd, tls, pflq, policynr, emulation, name, output, &future, &ipid->uflags); if (future != ICPOLICY_ASK) filter_modifypolicy(fd, policynr, emulation, name, future); @@ -261,7 +261,7 @@ gen_cb(int fd, pid_t pid, int policynr, const char *name, int code, goto out; } - action = filter_ask(NULL, NULL, policynr, emulation, name, + action = filter_ask(fd, NULL, NULL, policynr, emulation, name, output, &future, &ipid->uflags); if (future != ICPOLICY_ASK) systrace_modifypolicy(fd, policynr, name, future); diff --git a/bin/systrace/systrace.h b/bin/systrace/systrace.h index 13c7593621e..556797da4a8 100644 --- a/bin/systrace/systrace.h +++ b/bin/systrace/systrace.h @@ -1,4 +1,4 @@ -/* $OpenBSD: systrace.h,v 1.14 2002/08/05 23:27:53 provos Exp $ */ +/* $OpenBSD: systrace.h,v 1.15 2002/09/23 04:41:02 itojun Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * All rights reserved. @@ -90,6 +90,18 @@ struct policy { struct filterq prefilters; }; +struct template { + TAILQ_ENTRY(template) next; + + char *filename; + char *name; + char *description; + + char *emulation; +}; + +TAILQ_HEAD(tmplqueue, template); + #define POLICY_PATH "/etc/systrace" #define POLICY_UNSUPERVISED 0x01 /* Auto-Pilot */ @@ -102,6 +114,8 @@ struct policy { int systrace_initpolicy(char *, char *); void systrace_setupdir(char *); +struct template *systrace_readtemplate(char *, struct policy *, + struct template *); void systrace_initcb(void); struct policy *systrace_newpolicy(const char *, const char *); int systrace_newpolicynr(int, struct policy *); @@ -153,8 +167,8 @@ struct systrace_revalias *systrace_reverse(const char *, const char *); struct systrace_revalias *systrace_find_reverse(const char *, const char *); short filter_evaluate(struct intercept_tlq *, struct filterq *, int *); -short filter_ask(struct intercept_tlq *, struct filterq *, int, const char *, - const char *, char *, short *, int *); +short filter_ask(int, struct intercept_tlq *, struct filterq *, int, + const char *, const char *, char *, short *, int *); void filter_free(struct filter *); void filter_modifypolicy(int, int, const char *, const char *, short); |