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