moved imc_manager to libtnccs
[strongswan.git] / src / libcharon / plugins / tnc_imc / tnc_imc_plugin.c
1 /*
2 * Copyright (C) 2010 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "tnc_imc_plugin.h"
17 #include "tnc_imc_manager.h"
18 #include "tnc_imc.h"
19
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <sys/mman.h>
23 #include <unistd.h>
24 #include <errno.h>
25 #include <fcntl.h>
26
27 #include <utils/lexparser.h>
28 #include <debug.h>
29
30 typedef struct private_tnc_imc_plugin_t private_tnc_imc_plugin_t;
31
32 /**
33 * Private data of a tnc_imc_plugin_t object.
34 */
35 struct private_tnc_imc_plugin_t {
36
37 /**
38 * Public interface.
39 */
40 tnc_imc_plugin_t public;
41
42 /**
43 * TNC IMC manager controlling Integrity Measurement Collectors
44 */
45 imc_manager_t *imcs;
46 };
47
48 /**
49 * load IMCs from a configuration file
50 */
51 static bool load_imcs(private_tnc_imc_plugin_t *this, char *filename)
52 {
53 int fd, line_nr = 0;
54 chunk_t src, line;
55 struct stat sb;
56 void *addr;
57
58 DBG1(DBG_TNC, "loading IMCs from '%s'", filename);
59 fd = open(filename, O_RDONLY);
60 if (fd == -1)
61 {
62 DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename,
63 strerror(errno));
64 return FALSE;
65 }
66 if (fstat(fd, &sb) == -1)
67 {
68 DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename,
69 strerror(errno));
70 close(fd);
71 return FALSE;
72 }
73 addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
74 if (addr == MAP_FAILED)
75 {
76 DBG1(DBG_LIB, "mapping '%s' failed: %s", filename, strerror(errno));
77 close(fd);
78 return FALSE;
79 }
80 src = chunk_create(addr, sb.st_size);
81
82 while (fetchline(&src, &line))
83 {
84 char *name, *path;
85 chunk_t token;
86 imc_t *imc;
87
88 line_nr++;
89
90 /* skip comments or empty lines */
91 if (*line.ptr == '#' || !eat_whitespace(&line))
92 {
93 continue;
94 }
95
96 /* determine keyword */
97 if (!extract_token(&token, ' ', &line))
98 {
99 DBG1(DBG_TNC, "line %d: keyword must be followed by a space",
100 line_nr);
101 return FALSE;
102 }
103
104 /* only interested in IMCs */
105 if (!match("IMC", &token))
106 {
107 continue;
108 }
109
110 /* advance to the IMC name and extract it */
111 if (!extract_token(&token, '"', &line) ||
112 !extract_token(&token, '"', &line))
113 {
114 DBG1(DBG_TNC, "line %d: IMC name must be set in double quotes",
115 line_nr);
116 return FALSE;
117 }
118
119 /* copy the IMC name */
120 name = malloc(token.len + 1);
121 memcpy(name, token.ptr, token.len);
122 name[token.len] = '\0';
123
124 /* advance to the IMC path and extract it */
125 if (!eat_whitespace(&line))
126 {
127 DBG1(DBG_TNC, "line %d: IMC path is missing", line_nr);
128 free(name);
129 return FALSE;
130 }
131 if (!extract_token(&token, ' ', &line))
132 {
133 token = line;
134 }
135
136 /* copy the IMC path */
137 path = malloc(token.len + 1);
138 memcpy(path, token.ptr, token.len);
139 path[token.len] = '\0';
140
141 /* load and register IMC instance */
142 imc = tnc_imc_create(name, path);
143 if (!imc)
144 {
145 free(name);
146 free(path);
147 return FALSE;
148 }
149 if (!this->imcs->add(this->imcs, imc))
150 {
151 if (imc->terminate &&
152 imc->terminate(imc->get_id(imc)) != TNC_RESULT_SUCCESS)
153 {
154 DBG1(DBG_TNC, "IMC \"%s\" not terminated successfully",
155 imc->get_name(imc));
156 }
157 imc->destroy(imc);
158 return FALSE;
159 }
160 DBG1(DBG_TNC, "IMC %u \"%s\" loaded from '%s'", imc->get_id(imc),
161 name, path);
162 }
163 munmap(addr, sb.st_size);
164 close(fd);
165 return TRUE;
166 }
167
168 METHOD(plugin_t, get_name, char*,
169 private_tnc_imc_plugin_t *this)
170 {
171 return "tnc-imc";
172 }
173
174 METHOD(plugin_t, get_features, int,
175 private_tnc_imc_plugin_t *this, plugin_feature_t *features[])
176 {
177 static plugin_feature_t f[] = {
178 PLUGIN_PROVIDE(CUSTOM, "imc-manager"),
179 };
180 *features = f;
181 return countof(f);
182 }
183
184 METHOD(plugin_t, destroy, void,
185 private_tnc_imc_plugin_t *this)
186 {
187 lib->set(lib, "imc-manager", NULL);
188 this->imcs->destroy(this->imcs);
189 free(this);
190 }
191
192 /*
193 * see header file
194 */
195 plugin_t *tnc_imc_plugin_create(void)
196 {
197 private_tnc_imc_plugin_t *this;
198 char *tnc_config;
199
200 INIT(this,
201 .public = {
202 .plugin = {
203 .get_name = _get_name,
204 .get_features = _get_features,
205 .destroy = _destroy,
206 },
207 },
208 .imcs = tnc_imc_manager_create(),
209 );
210
211 lib->set(lib, "imc-manager", this->imcs);
212
213 /* Load IMCs and abort if not all instances initalize successfully */
214 tnc_config = lib->settings->get_str(lib->settings,
215 "charon.plugins.tnc-imc.tnc_config", "/etc/tnc_config");
216 if (!load_imcs(this, tnc_config))
217 {
218 destroy(this);
219 return NULL;
220 }
221
222 return &this->public.plugin;
223 }
224