blob: bf38d1af3cfd7945b8bb61a2c1acda4047cdf744 [file] [log] [blame]
Roberto Sassuadf53a72013-06-07 12:16:29 +02001/*
2 * Copyright (C) 2013 Politecnico di Torino, Italy
3 * TORSEC group -- http://security.polito.it
4 *
5 * Author: Roberto Sassu <roberto.sassu@polito.it>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2 of the
10 * License.
11 *
12 * File: ima_template.c
13 * Helpers to manage template descriptors.
14 */
15#include "ima.h"
Roberto Sassu3ce1217d2013-06-07 12:16:30 +020016#include "ima_template_lib.h"
Roberto Sassuadf53a72013-06-07 12:16:29 +020017
18static struct ima_template_desc defined_templates[] = {
Roberto Sassu4d7aeee72013-06-07 12:16:32 +020019 {.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT},
20 {.name = "ima-ng",.fmt = "d-ng|n-ng"},
Roberto Sassuadf53a72013-06-07 12:16:29 +020021};
22
23static struct ima_template_field supported_fields[] = {
Roberto Sassu3ce1217d2013-06-07 12:16:30 +020024 {.field_id = "d",.field_init = ima_eventdigest_init,
25 .field_show = ima_show_template_digest},
26 {.field_id = "n",.field_init = ima_eventname_init,
27 .field_show = ima_show_template_string},
Roberto Sassu4d7aeee72013-06-07 12:16:32 +020028 {.field_id = "d-ng",.field_init = ima_eventdigest_ng_init,
29 .field_show = ima_show_template_digest_ng},
30 {.field_id = "n-ng",.field_init = ima_eventname_ng_init,
31 .field_show = ima_show_template_string},
Roberto Sassuadf53a72013-06-07 12:16:29 +020032};
33
Roberto Sassu3ce1217d2013-06-07 12:16:30 +020034static struct ima_template_field *lookup_template_field(const char *field_id)
Roberto Sassuadf53a72013-06-07 12:16:29 +020035{
36 int i;
37
38 for (i = 0; i < ARRAY_SIZE(supported_fields); i++)
39 if (strncmp(supported_fields[i].field_id, field_id,
40 IMA_TEMPLATE_FIELD_ID_MAX_LEN) == 0)
41 return &supported_fields[i];
42 return NULL;
43}
44
Roberto Sassu3ce1217d2013-06-07 12:16:30 +020045static int template_fmt_size(char *template_fmt)
Roberto Sassuadf53a72013-06-07 12:16:29 +020046{
47 char c;
48 int template_fmt_len = strlen(template_fmt);
49 int i = 0, j = 0;
50
51 while (i < template_fmt_len) {
52 c = template_fmt[i];
53 if (c == '|')
54 j++;
55 i++;
56 }
57
58 return j + 1;
59}
60
61static int template_desc_init_fields(char *template_fmt,
62 struct ima_template_field ***fields,
63 int *num_fields)
64{
65 char *c, *template_fmt_ptr = template_fmt;
Roberto Sassu3ce1217d2013-06-07 12:16:30 +020066 int template_num_fields = template_fmt_size(template_fmt);
Roberto Sassuadf53a72013-06-07 12:16:29 +020067 int i, result = 0;
68
69 if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX)
70 return -EINVAL;
71
72 *fields = kzalloc(template_num_fields * sizeof(*fields), GFP_KERNEL);
73 if (*fields == NULL) {
74 result = -ENOMEM;
75 goto out;
76 }
77 for (i = 0; (c = strsep(&template_fmt_ptr, "|")) != NULL &&
78 i < template_num_fields; i++) {
Roberto Sassu3ce1217d2013-06-07 12:16:30 +020079 struct ima_template_field *f = lookup_template_field(c);
Roberto Sassuadf53a72013-06-07 12:16:29 +020080
81 if (!f) {
82 result = -ENOENT;
83 goto out;
84 }
85 (*fields)[i] = f;
86 }
87 *num_fields = i;
88 return 0;
89out:
90 kfree(*fields);
91 *fields = NULL;
92 return result;
93}
94
95static int init_defined_templates(void)
96{
97 int i = 0;
98 int result = 0;
99
100 /* Init defined templates. */
101 for (i = 0; i < ARRAY_SIZE(defined_templates); i++) {
102 struct ima_template_desc *template = &defined_templates[i];
103
104 result = template_desc_init_fields(template->fmt,
105 &(template->fields),
106 &(template->num_fields));
107 if (result < 0)
108 return result;
109 }
110 return result;
111}
112
113int ima_init_template(void)
114{
115 int result;
116
117 result = init_defined_templates();
118 if (result < 0)
119 return result;
120
121 return 0;
122}