bd4156c19e8b211282c1f37b20f33a158aa88a04
[strongswan.git] / src / libimcv / imcv.c
1 /*
2 * Copyright (C) 2011 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 */
14
15 #include "imcv.h"
16 #include "ietf/ietf_attr.h"
17 #include "ita/ita_attr.h"
18 #include "tcg/tcg_attr.h"
19 #include "pts/components/pts_component.h"
20 #include "pts/components/pts_component_manager.h"
21 #include "pts/components/tcg/tcg_comp_func_name.h"
22 #include "pts/components/ita/ita_comp_func_name.h"
23 #include "pts/components/ita/ita_comp_ima.h"
24 #include "pts/components/ita/ita_comp_tboot.h"
25 #include "pts/components/ita/ita_comp_tgrub.h"
26
27 #include <utils/debug.h>
28 #include <utils/utils.h>
29 #include <pen/pen.h>
30
31 #ifdef HAVE_SYSLOG
32 #include <syslog.h>
33 #endif
34
35 #ifndef IPSEC_SCRIPT
36 #define IPSEC_SCRIPT "ipsec"
37 #endif
38
39 #define IMCV_DEBUG_LEVEL 1
40 #define IMCV_DEFAULT_POLICY_SCRIPT IPSEC_SCRIPT " _imv_policy"
41
42
43 /**
44 * PA-TNC attribute manager
45 */
46 pa_tnc_attr_manager_t *imcv_pa_tnc_attributes;
47
48 /**
49 * Global list of IMV sessions
50 */
51 imv_session_manager_t *imcv_sessions;
52
53 /**
54 * Global IMV database
55 */
56 imv_database_t *imcv_db;
57
58 /**
59 * PTS Functional Component manager
60 */
61 pts_component_manager_t *imcv_pts_components;
62
63 /**
64 * Reference count for libimcv
65 */
66 static refcount_t libimcv_ref = 0;
67
68 /**
69 * Reference count for libstrongswan
70 */
71 static refcount_t libstrongswan_ref = 0;
72
73 /**
74 * Global configuration of imcv dbg function
75 */
76 static int imcv_debug_level;
77 static bool imcv_stderr_quiet;
78
79 /**
80 * imvc dbg function
81 */
82 static void imcv_dbg(debug_t group, level_t level, char *fmt, ...)
83 {
84 va_list args;
85
86 if (level <= imcv_debug_level)
87 {
88 if (!imcv_stderr_quiet)
89 {
90 va_start(args, fmt);
91 fprintf(stderr, "[HSR] ");
92 vfprintf(stderr, fmt, args);
93 fprintf(stderr, "\n");
94 va_end(args);
95 }
96
97 #ifdef HAVE_SYSLOG
98 {
99 int priority = LOG_INFO;
100 char buffer[8192];
101 char *current = buffer, *next;
102
103 /* write in memory buffer first */
104 va_start(args, fmt);
105 vsnprintf(buffer, sizeof(buffer), fmt, args);
106 va_end(args);
107
108 /* do a syslog with every line */
109 while (current)
110 {
111 next = strchr(current, '\n');
112 if (next)
113 {
114 *(next++) = '\0';
115 }
116 syslog(priority, "[HSR] %s\n", current);
117 current = next;
118 }
119 }
120 #endif /* HAVE_SYSLOG */
121 }
122 }
123
124 /**
125 * Described in header.
126 */
127 bool libimcv_init(bool is_imv)
128 {
129 /* initialize libstrongswan library only once */
130 if (lib)
131 {
132 /* did main program initialize libstrongswan? */
133 if (libstrongswan_ref == 0)
134 {
135 ref_get(&libstrongswan_ref);
136 }
137 }
138 else
139 {
140 /* we are the first to initialize libstrongswan */
141 if (!library_init(NULL, "libimcv"))
142 {
143 return FALSE;
144 }
145
146 /* set the debug level and stderr output */
147 imcv_debug_level = lib->settings->get_int(lib->settings,
148 "libimcv.debug_level", IMCV_DEBUG_LEVEL);
149 imcv_stderr_quiet = lib->settings->get_int(lib->settings,
150 "libimcv.stderr_quiet", FALSE);
151
152 /* activate the imcv debugging hook */
153 dbg = imcv_dbg;
154 #ifdef HAVE_SYSLOG
155 openlog("imcv", 0, LOG_DAEMON);
156 #endif
157
158 if (!lib->plugins->load(lib->plugins,
159 lib->settings->get_str(lib->settings, "libimcv.load",
160 "random nonce gmp pubkey x509")))
161 {
162 library_deinit();
163 return FALSE;
164 }
165 }
166 ref_get(&libstrongswan_ref);
167
168 lib->settings->add_fallback(lib->settings, "%s.imcv", "libimcv", lib->ns);
169 lib->settings->add_fallback(lib->settings, "%s.plugins", "libimcv.plugins",
170 lib->ns);
171
172 if (libimcv_ref == 0)
173 {
174 char *uri, *script;
175
176 /* initialize the PA-TNC attribute manager */
177 imcv_pa_tnc_attributes = pa_tnc_attr_manager_create();
178 imcv_pa_tnc_attributes->add_vendor(imcv_pa_tnc_attributes, PEN_IETF,
179 ietf_attr_create_from_data, ietf_attr_names);
180 imcv_pa_tnc_attributes->add_vendor(imcv_pa_tnc_attributes, PEN_ITA,
181 ita_attr_create_from_data, ita_attr_names);
182 imcv_pa_tnc_attributes->add_vendor(imcv_pa_tnc_attributes, PEN_TCG,
183 tcg_attr_create_from_data, tcg_attr_names);
184
185 imcv_pts_components = pts_component_manager_create();
186 imcv_pts_components->add_vendor(imcv_pts_components, PEN_TCG,
187 pts_tcg_comp_func_names, PTS_TCG_QUALIFIER_TYPE_SIZE,
188 pts_tcg_qualifier_flag_names, pts_tcg_qualifier_type_names);
189 imcv_pts_components->add_vendor(imcv_pts_components, PEN_ITA,
190 pts_ita_comp_func_names, PTS_ITA_QUALIFIER_TYPE_SIZE,
191 pts_ita_qualifier_flag_names, pts_ita_qualifier_type_names);
192
193 imcv_pts_components->add_component(imcv_pts_components, PEN_ITA,
194 PTS_ITA_COMP_FUNC_NAME_TGRUB,
195 pts_ita_comp_tgrub_create);
196 imcv_pts_components->add_component(imcv_pts_components, PEN_ITA,
197 PTS_ITA_COMP_FUNC_NAME_TBOOT,
198 pts_ita_comp_tboot_create);
199 imcv_pts_components->add_component(imcv_pts_components, PEN_ITA,
200 PTS_ITA_COMP_FUNC_NAME_IMA,
201 pts_ita_comp_ima_create);
202 if (is_imv)
203 {
204 /* instantiate global IMV session manager */
205 imcv_sessions = imv_session_manager_create();
206
207 /* instantiate and attach global IMV database if URI is valid */
208 uri = lib->settings->get_str(lib->settings,
209 "%s.imcv.database", NULL, lib->ns);
210 script = lib->settings->get_str(lib->settings,
211 "%s.imcv.policy_script", IMCV_DEFAULT_POLICY_SCRIPT,
212 lib->ns);
213 if (uri)
214 {
215 imcv_db = imv_database_create(uri, script);
216 }
217 }
218 DBG1(DBG_LIB, "libimcv initialized");
219 }
220 ref_get(&libimcv_ref);
221
222 return TRUE;
223 }
224
225 /**
226 * Described in header.
227 */
228 void libimcv_deinit(void)
229 {
230 if (ref_put(&libimcv_ref))
231 {
232 imcv_pts_components->remove_vendor(imcv_pts_components, PEN_TCG);
233 imcv_pts_components->remove_vendor(imcv_pts_components, PEN_ITA);
234 imcv_pts_components->destroy(imcv_pts_components);
235
236 imcv_pa_tnc_attributes->remove_vendor(imcv_pa_tnc_attributes, PEN_IETF);
237 imcv_pa_tnc_attributes->remove_vendor(imcv_pa_tnc_attributes, PEN_ITA);
238 imcv_pa_tnc_attributes->remove_vendor(imcv_pa_tnc_attributes, PEN_TCG);
239 DESTROY_IF(imcv_pa_tnc_attributes);
240 imcv_pa_tnc_attributes = NULL;
241 DESTROY_IF(imcv_db);
242 DESTROY_IF(imcv_sessions);
243 DBG1(DBG_LIB, "libimcv terminated");
244 }
245 if (ref_put(&libstrongswan_ref))
246 {
247 library_deinit();
248 }
249 }