8b27c73c3e292b1f7f7083af6f2cb9a062e313f1
[strongswan.git] / src / libstrongswan / plugins / plugin_feature.c
1 /*
2 * Copyright (C) 2011 Martin Willi
3 * Copyright (C) 2011 revosec AG
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 #define _GNU_SOURCE
17 #include <stdio.h>
18
19 #include "plugin_feature.h"
20
21 #include <debug.h>
22
23 ENUM(plugin_feature_names, FEATURE_NONE, FEATURE_CUSTOM,
24 "NONE",
25 "CRYPTER",
26 "AEAD",
27 "SIGNER",
28 "HASHER",
29 "PRF",
30 "DH",
31 "RNG",
32 "PRIVKEY",
33 "PRIVKEY_GEN",
34 "PRIVKEY_SIGN",
35 "PRIVKEY_DECRYPT",
36 "PUBKEY",
37 "PUBKEY_VERIFY",
38 "PUBKEY_ENCRYPT",
39 "CERT_DECODE",
40 "CERT_ENCODE",
41 "EAP_SERVER",
42 "EAP_CLIENT",
43 "DATABASE",
44 "FETCHER",
45 "CUSTOM",
46 );
47
48 /**
49 * See header.
50 */
51 bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b)
52 {
53 if (a->type == b->type)
54 {
55 switch (a->type)
56 {
57 case FEATURE_NONE:
58 return FALSE;
59 case FEATURE_CRYPTER:
60 return a->arg.crypter.alg == b->arg.crypter.alg &&
61 a->arg.crypter.key_size == b->arg.crypter.key_size;
62 case FEATURE_AEAD:
63 return a->arg.aead.alg == b->arg.aead.alg &&
64 a->arg.aead.key_size == b->arg.aead.key_size;
65 case FEATURE_SIGNER:
66 return a->arg.signer == b->arg.signer;
67 case FEATURE_HASHER:
68 return a->arg.hasher == b->arg.hasher;
69 case FEATURE_PRF:
70 return a->arg.prf == b->arg.prf;
71 case FEATURE_DH:
72 return a->arg.dh_group == b->arg.dh_group;
73 case FEATURE_RNG:
74 return a->arg.rng_quality <= b->arg.rng_quality;
75 case FEATURE_PRIVKEY:
76 case FEATURE_PRIVKEY_GEN:
77 case FEATURE_PUBKEY:
78 return a->arg.privkey == b->arg.privkey;
79 case FEATURE_PRIVKEY_SIGN:
80 case FEATURE_PUBKEY_VERIFY:
81 return a->arg.privkey_sign == b->arg.privkey_sign;
82 case FEATURE_PRIVKEY_DECRYPT:
83 case FEATURE_PUBKEY_ENCRYPT:
84 return a->arg.privkey_decrypt == b->arg.privkey_decrypt;
85 case FEATURE_CERT_DECODE:
86 case FEATURE_CERT_ENCODE:
87 return a->arg.cert == b->arg.cert;
88 case FEATURE_EAP_SERVER:
89 case FEATURE_EAP_PEER:
90 return a->arg.eap == b->arg.eap;
91 case FEATURE_DATABASE:
92 return a->arg.database == DB_ANY ||
93 a->arg.database == b->arg.database;
94 case FEATURE_FETCHER:
95 return a->arg.fetcher == NULL ||
96 streq(a->arg.fetcher, b->arg.fetcher);
97 case FEATURE_CUSTOM:
98 return streq(a->arg.custom, b->arg.custom);
99 case FEATURE_XAUTH_SERVER:
100 case FEATURE_XAUTH_PEER:
101 return streq(a->arg.xauth == b->arg.xauth);
102 }
103 }
104 return FALSE;
105 }
106
107 /**
108 * See header.
109 */
110 char* plugin_feature_get_string(plugin_feature_t *feature)
111 {
112 char *str = NULL;
113
114 if (feature->kind == FEATURE_REGISTER)
115 {
116 return strdup("(register function)");
117 }
118 switch (feature->type)
119 {
120 case FEATURE_NONE:
121 return strdup("NONE");
122 case FEATURE_CRYPTER:
123 if (asprintf(&str, "%N:%N-%d", plugin_feature_names, feature->type,
124 encryption_algorithm_names, feature->arg.crypter.alg,
125 feature->arg.crypter.key_size) > 0)
126 {
127 return str;
128 }
129 break;
130 case FEATURE_AEAD:
131 if (asprintf(&str, "%N:%N-%d", plugin_feature_names, feature->type,
132 encryption_algorithm_names, feature->arg.aead.alg,
133 feature->arg.aead.key_size) > 0)
134 {
135 return str;
136 }
137 break;
138 case FEATURE_SIGNER:
139 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
140 integrity_algorithm_names, feature->arg.signer) > 0)
141 {
142 return str;
143 }
144 break;
145 case FEATURE_HASHER:
146 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
147 hash_algorithm_names, feature->arg.hasher) > 0)
148 {
149 return str;
150 }
151 break;
152 case FEATURE_PRF:
153 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
154 pseudo_random_function_names, feature->arg.prf) > 0)
155 {
156 return str;
157 }
158 break;
159 case FEATURE_DH:
160 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
161 diffie_hellman_group_names, feature->arg.dh_group) > 0)
162 {
163 return str;
164 }
165 break;
166 case FEATURE_RNG:
167 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
168 rng_quality_names, feature->arg.rng_quality) > 0)
169 {
170 return str;
171 }
172 break;
173 case FEATURE_PRIVKEY:
174 case FEATURE_PRIVKEY_GEN:
175 case FEATURE_PUBKEY:
176 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
177 key_type_names, feature->arg.privkey) > 0)
178 {
179 return str;
180 }
181 break;
182 case FEATURE_PRIVKEY_SIGN:
183 case FEATURE_PUBKEY_VERIFY:
184 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
185 signature_scheme_names, feature->arg.privkey_sign) > 0)
186 {
187 return str;
188 }
189 break;
190 case FEATURE_PRIVKEY_DECRYPT:
191 case FEATURE_PUBKEY_ENCRYPT:
192 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
193 encryption_scheme_names, feature->arg.privkey_decrypt) > 0)
194 {
195 return str;
196 }
197 break;
198 case FEATURE_CERT_DECODE:
199 case FEATURE_CERT_ENCODE:
200 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
201 certificate_type_names, feature->arg.cert) > 0)
202 {
203 return str;
204 }
205 break;
206 case FEATURE_EAP_SERVER:
207 case FEATURE_EAP_PEER:
208 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
209 eap_type_short_names, feature->arg.eap) > 0)
210 {
211 return str;
212 }
213 break;
214 case FEATURE_DATABASE:
215 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
216 db_driver_names, feature->arg.database) > 0)
217 {
218 return str;
219 }
220 break;
221 case FEATURE_FETCHER:
222 if (asprintf(&str, "%N:%s", plugin_feature_names, feature->type,
223 feature->arg.fetcher) > 0)
224 {
225 return str;
226 }
227 break;
228 case FEATURE_CUSTOM:
229 if (asprintf(&str, "%N:%s", plugin_feature_names, feature->type,
230 feature->arg.custom) > 0)
231 {
232 return str;
233 }
234 break;
235 case FEATURE_XAUTH_SERVER:
236 case FEATURE_XAUTH_PEER:
237 if (asprintf(&str, "%N:%s", plugin_feature_names, feature->type,
238 feature->arg.xauth) > 0)
239 {
240 return str;
241 }
242 break;
243 }
244 if (!str)
245 {
246 str = strdup("(invalid)");
247 }
248 return str;
249 }
250
251 /**
252 * See header.
253 */
254 bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature,
255 plugin_feature_t *reg)
256 {
257 char *name;
258
259 if (!reg)
260 { /* noting to do for this feature */
261 return TRUE;
262 }
263 if (reg->kind == FEATURE_CALLBACK)
264 {
265 if (reg->arg.cb.f(plugin, feature, TRUE, reg->arg.cb.data))
266 {
267 return TRUE;
268 }
269 return FALSE;
270 }
271 name = plugin->get_name(plugin);
272 switch (feature->type)
273 {
274 case FEATURE_CRYPTER:
275 lib->crypto->add_crypter(lib->crypto, feature->arg.crypter.alg,
276 name, reg->arg.reg.f);
277 break;
278 case FEATURE_AEAD:
279 lib->crypto->add_aead(lib->crypto, feature->arg.aead.alg,
280 name, reg->arg.reg.f);
281 break;
282 case FEATURE_SIGNER:
283 lib->crypto->add_signer(lib->crypto, feature->arg.signer,
284 name, reg->arg.reg.f);
285 break;
286 case FEATURE_HASHER:
287 lib->crypto->add_hasher(lib->crypto, feature->arg.hasher,
288 name, reg->arg.reg.f);
289 break;
290 case FEATURE_PRF:
291 lib->crypto->add_prf(lib->crypto, feature->arg.prf,
292 name, reg->arg.reg.f);
293 break;
294 case FEATURE_DH:
295 lib->crypto->add_dh(lib->crypto, feature->arg.dh_group,
296 name, reg->arg.reg.f);
297 break;
298 case FEATURE_RNG:
299 lib->crypto->add_rng(lib->crypto, feature->arg.rng_quality,
300 name, reg->arg.reg.f);
301 break;
302 case FEATURE_PRIVKEY:
303 case FEATURE_PRIVKEY_GEN:
304 lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY,
305 feature->arg.privkey, reg->arg.reg.final,
306 reg->arg.reg.f);
307 break;
308 case FEATURE_PUBKEY:
309 lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY,
310 feature->arg.pubkey, reg->arg.reg.final,
311 reg->arg.reg.f);
312 break;
313 case FEATURE_CERT_DECODE:
314 case FEATURE_CERT_ENCODE:
315 lib->creds->add_builder(lib->creds, CRED_CERTIFICATE,
316 feature->arg.cert, reg->arg.reg.final,
317 reg->arg.reg.f);
318 break;
319 case FEATURE_DATABASE:
320 lib->db->add_database(lib->db, reg->arg.reg.f);
321 break;
322 case FEATURE_FETCHER:
323 lib->fetcher->add_fetcher(lib->fetcher, reg->arg.reg.f,
324 feature->arg.fetcher);
325 break;
326 default:
327 break;
328 }
329 return TRUE;
330 }
331
332 /**
333 * See header.
334 */
335 bool plugin_feature_unload(plugin_t *plugin, plugin_feature_t *feature,
336 plugin_feature_t *reg)
337 {
338 if (!reg)
339 { /* noting to do for this feature */
340 return TRUE;
341 }
342 if (reg->kind == FEATURE_CALLBACK)
343 {
344 if (reg->arg.cb.f(plugin, feature, FALSE, reg->arg.cb.data))
345 {
346 return TRUE;
347 }
348 return FALSE;
349 }
350 switch (feature->type)
351 {
352 case FEATURE_CRYPTER:
353 lib->crypto->remove_crypter(lib->crypto, reg->arg.reg.f);
354 break;
355 case FEATURE_AEAD:
356 lib->crypto->remove_aead(lib->crypto, reg->arg.reg.f);
357 break;
358 case FEATURE_SIGNER:
359 lib->crypto->remove_signer(lib->crypto, reg->arg.reg.f);
360 break;
361 case FEATURE_HASHER:
362 lib->crypto->remove_hasher(lib->crypto, reg->arg.reg.f);
363 break;
364 case FEATURE_PRF:
365 lib->crypto->remove_prf(lib->crypto, reg->arg.reg.f);
366 break;
367 case FEATURE_DH:
368 lib->crypto->remove_dh(lib->crypto, reg->arg.reg.f);
369 break;
370 case FEATURE_RNG:
371 lib->crypto->remove_rng(lib->crypto, reg->arg.reg.f);
372 break;
373 case FEATURE_PRIVKEY:
374 case FEATURE_PRIVKEY_GEN:
375 lib->creds->remove_builder(lib->creds, reg->arg.reg.f);
376 break;
377 case FEATURE_PUBKEY:
378 lib->creds->remove_builder(lib->creds, reg->arg.reg.f);
379 break;
380 case FEATURE_CERT_DECODE:
381 case FEATURE_CERT_ENCODE:
382 lib->creds->remove_builder(lib->creds, reg->arg.reg.f);
383 break;
384 case FEATURE_DATABASE:
385 lib->db->remove_database(lib->db, reg->arg.reg.f);
386 break;
387 case FEATURE_FETCHER:
388 lib->fetcher->remove_fetcher(lib->fetcher, reg->arg.reg.f);
389 break;
390 default:
391 break;
392 }
393 return TRUE;
394 }