summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2002-09-23 04:41:03 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2002-09-23 04:41:03 +0000
commit09c0b4866ae6fb7cf0377ed10f227a559c499513 (patch)
treeaabb035a58ca92d373ff168a92200e281a0b6b43 /bin
parentfc3f7ac53fdd251ee68c8bef6cb4ec19870fb7c3 (diff)
support for templates. they allow fast generation of new policies. an
appropriate template can be inserted during initial policy generation. from provos
Diffstat (limited to 'bin')
-rw-r--r--bin/systrace/filter.c78
-rw-r--r--bin/systrace/policy.c155
-rw-r--r--bin/systrace/systrace.c6
-rw-r--r--bin/systrace/systrace.h20
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);