2 * Copyright (C) 2012-2013 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
5 * Copyright (C) 2011 Martin Willi
6 * Copyright (C) 2011 revosec AG
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 #include "plugin_feature.h"
24 #include <utils/debug.h>
26 ENUM(plugin_feature_names
, FEATURE_NONE
, FEATURE_CUSTOM
,
60 u_int32_t
plugin_feature_hash(plugin_feature_t
*feature
)
64 switch (feature
->type
)
68 case FEATURE_NONCE_GEN
:
69 case FEATURE_DATABASE
:
71 case FEATURE_RESOLVER
:
72 /* put these special cases in their (type-specific) buckets */
76 data
= chunk_from_thing(feature
->arg
.crypter
);
79 data
= chunk_from_thing(feature
->arg
.aead
);
82 data
= chunk_from_thing(feature
->arg
.signer
);
85 data
= chunk_from_thing(feature
->arg
.hasher
);
88 data
= chunk_from_thing(feature
->arg
.prf
);
91 data
= chunk_from_thing(feature
->arg
.dh_group
);
94 data
= chunk_from_thing(feature
->arg
.privkey
);
96 case FEATURE_PRIVKEY_GEN
:
97 data
= chunk_from_thing(feature
->arg
.privkey_gen
);
100 data
= chunk_from_thing(feature
->arg
.pubkey
);
102 case FEATURE_PRIVKEY_SIGN
:
103 data
= chunk_from_thing(feature
->arg
.privkey_sign
);
105 case FEATURE_PUBKEY_VERIFY
:
106 data
= chunk_from_thing(feature
->arg
.pubkey_verify
);
108 case FEATURE_PRIVKEY_DECRYPT
:
109 data
= chunk_from_thing(feature
->arg
.privkey_decrypt
);
111 case FEATURE_PUBKEY_ENCRYPT
:
112 data
= chunk_from_thing(feature
->arg
.pubkey_encrypt
);
114 case FEATURE_CERT_DECODE
:
115 case FEATURE_CERT_ENCODE
:
116 data
= chunk_from_thing(feature
->arg
.cert
);
118 case FEATURE_CONTAINER_DECODE
:
119 case FEATURE_CONTAINER_ENCODE
:
120 data
= chunk_from_thing(feature
->arg
.container
);
122 case FEATURE_EAP_SERVER
:
123 case FEATURE_EAP_PEER
:
124 data
= chunk_from_thing(feature
->arg
.eap
);
127 data
= chunk_create(feature
->arg
.custom
,
128 strlen(feature
->arg
.custom
));
130 case FEATURE_XAUTH_SERVER
:
131 case FEATURE_XAUTH_PEER
:
132 data
= chunk_create(feature
->arg
.xauth
,
133 strlen(feature
->arg
.xauth
));
136 return chunk_hash_inc(chunk_from_thing(feature
->type
),
143 bool plugin_feature_matches(plugin_feature_t
*a
, plugin_feature_t
*b
)
145 if (a
->type
== b
->type
)
151 case FEATURE_CRYPTER
:
152 return a
->arg
.crypter
.alg
== b
->arg
.crypter
.alg
&&
153 a
->arg
.crypter
.key_size
== b
->arg
.crypter
.key_size
;
155 return a
->arg
.aead
.alg
== b
->arg
.aead
.alg
&&
156 a
->arg
.aead
.key_size
== b
->arg
.aead
.key_size
;
158 return a
->arg
.signer
== b
->arg
.signer
;
160 return a
->arg
.hasher
== b
->arg
.hasher
;
162 return a
->arg
.prf
== b
->arg
.prf
;
164 return a
->arg
.dh_group
== b
->arg
.dh_group
;
166 return a
->arg
.rng_quality
<= b
->arg
.rng_quality
;
167 case FEATURE_NONCE_GEN
:
168 case FEATURE_RESOLVER
:
170 case FEATURE_PRIVKEY
:
171 case FEATURE_PRIVKEY_GEN
:
173 return a
->arg
.privkey
== b
->arg
.privkey
;
174 case FEATURE_PRIVKEY_SIGN
:
175 case FEATURE_PUBKEY_VERIFY
:
176 return a
->arg
.privkey_sign
== b
->arg
.privkey_sign
;
177 case FEATURE_PRIVKEY_DECRYPT
:
178 case FEATURE_PUBKEY_ENCRYPT
:
179 return a
->arg
.privkey_decrypt
== b
->arg
.privkey_decrypt
;
180 case FEATURE_CERT_DECODE
:
181 case FEATURE_CERT_ENCODE
:
182 return a
->arg
.cert
== b
->arg
.cert
;
183 case FEATURE_CONTAINER_DECODE
:
184 case FEATURE_CONTAINER_ENCODE
:
185 return a
->arg
.container
== b
->arg
.container
;
186 case FEATURE_EAP_SERVER
:
187 case FEATURE_EAP_PEER
:
188 return a
->arg
.eap
== b
->arg
.eap
;
189 case FEATURE_DATABASE
:
190 return a
->arg
.database
== DB_ANY
||
191 a
->arg
.database
== b
->arg
.database
;
192 case FEATURE_FETCHER
:
193 return a
->arg
.fetcher
== NULL
||
194 streq(a
->arg
.fetcher
, b
->arg
.fetcher
);
196 return streq(a
->arg
.custom
, b
->arg
.custom
);
197 case FEATURE_XAUTH_SERVER
:
198 case FEATURE_XAUTH_PEER
:
199 return streq(a
->arg
.xauth
, b
->arg
.xauth
);
208 bool plugin_feature_equals(plugin_feature_t
*a
, plugin_feature_t
*b
)
210 if (a
->type
== b
->type
)
215 case FEATURE_CRYPTER
:
221 case FEATURE_NONCE_GEN
:
222 case FEATURE_RESOLVER
:
223 case FEATURE_PRIVKEY
:
224 case FEATURE_PRIVKEY_GEN
:
226 case FEATURE_PRIVKEY_SIGN
:
227 case FEATURE_PUBKEY_VERIFY
:
228 case FEATURE_PRIVKEY_DECRYPT
:
229 case FEATURE_PUBKEY_ENCRYPT
:
230 case FEATURE_CERT_DECODE
:
231 case FEATURE_CERT_ENCODE
:
232 case FEATURE_CONTAINER_DECODE
:
233 case FEATURE_CONTAINER_ENCODE
:
234 case FEATURE_EAP_SERVER
:
235 case FEATURE_EAP_PEER
:
237 case FEATURE_XAUTH_SERVER
:
238 case FEATURE_XAUTH_PEER
:
239 return plugin_feature_matches(a
, b
);
241 return a
->arg
.rng_quality
== b
->arg
.rng_quality
;
242 case FEATURE_DATABASE
:
243 return a
->arg
.database
== b
->arg
.database
;
244 case FEATURE_FETCHER
:
245 if (a
->arg
.fetcher
&& b
->arg
.fetcher
)
247 return streq(a
->arg
.fetcher
, b
->arg
.fetcher
);
249 return !a
->arg
.fetcher
&& !b
->arg
.fetcher
;
258 char* plugin_feature_get_string(plugin_feature_t
*feature
)
262 if (feature
->kind
== FEATURE_REGISTER
)
264 return strdup("(register function)");
266 switch (feature
->type
)
269 return strdup("NONE");
270 case FEATURE_CRYPTER
:
271 if (asprintf(&str
, "%N:%N-%d", plugin_feature_names
, feature
->type
,
272 encryption_algorithm_names
, feature
->arg
.crypter
.alg
,
273 feature
->arg
.crypter
.key_size
) > 0)
279 if (asprintf(&str
, "%N:%N-%d", plugin_feature_names
, feature
->type
,
280 encryption_algorithm_names
, feature
->arg
.aead
.alg
,
281 feature
->arg
.aead
.key_size
) > 0)
287 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
288 integrity_algorithm_names
, feature
->arg
.signer
) > 0)
294 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
295 hash_algorithm_names
, feature
->arg
.hasher
) > 0)
301 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
302 pseudo_random_function_names
, feature
->arg
.prf
) > 0)
308 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
309 diffie_hellman_group_names
, feature
->arg
.dh_group
) > 0)
315 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
316 rng_quality_names
, feature
->arg
.rng_quality
) > 0)
321 case FEATURE_NONCE_GEN
:
322 case FEATURE_RESOLVER
:
323 if (asprintf(&str
, "%N", plugin_feature_names
, feature
->type
) > 0)
328 case FEATURE_PRIVKEY
:
329 case FEATURE_PRIVKEY_GEN
:
331 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
332 key_type_names
, feature
->arg
.privkey
) > 0)
337 case FEATURE_PRIVKEY_SIGN
:
338 case FEATURE_PUBKEY_VERIFY
:
339 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
340 signature_scheme_names
, feature
->arg
.privkey_sign
) > 0)
345 case FEATURE_PRIVKEY_DECRYPT
:
346 case FEATURE_PUBKEY_ENCRYPT
:
347 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
348 encryption_scheme_names
, feature
->arg
.privkey_decrypt
) > 0)
353 case FEATURE_CERT_DECODE
:
354 case FEATURE_CERT_ENCODE
:
355 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
356 certificate_type_names
, feature
->arg
.cert
) > 0)
361 case FEATURE_CONTAINER_DECODE
:
362 case FEATURE_CONTAINER_ENCODE
:
363 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
364 container_type_names
, feature
->arg
.container
) > 0)
369 case FEATURE_EAP_SERVER
:
370 case FEATURE_EAP_PEER
:
371 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
372 eap_type_short_names
, feature
->arg
.eap
) > 0)
377 case FEATURE_DATABASE
:
378 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
379 db_driver_names
, feature
->arg
.database
) > 0)
384 case FEATURE_FETCHER
:
385 if (asprintf(&str
, "%N:%s", plugin_feature_names
, feature
->type
,
386 feature
->arg
.fetcher
) > 0)
392 if (asprintf(&str
, "%N:%s", plugin_feature_names
, feature
->type
,
393 feature
->arg
.custom
) > 0)
398 case FEATURE_XAUTH_SERVER
:
399 case FEATURE_XAUTH_PEER
:
400 if (asprintf(&str
, "%N:%s", plugin_feature_names
, feature
->type
,
401 feature
->arg
.xauth
) > 0)
409 str
= strdup("(invalid)");
417 bool plugin_feature_load(plugin_t
*plugin
, plugin_feature_t
*feature
,
418 plugin_feature_t
*reg
)
423 { /* noting to do for this feature */
426 if (reg
->kind
== FEATURE_CALLBACK
)
428 if (!reg
->arg
.cb
.f
||
429 reg
->arg
.cb
.f(plugin
, feature
, TRUE
, reg
->arg
.cb
.data
))
435 name
= plugin
->get_name(plugin
);
436 switch (feature
->type
)
438 case FEATURE_CRYPTER
:
439 lib
->crypto
->add_crypter(lib
->crypto
, feature
->arg
.crypter
.alg
,
440 name
, reg
->arg
.reg
.f
);
443 lib
->crypto
->add_aead(lib
->crypto
, feature
->arg
.aead
.alg
,
444 name
, reg
->arg
.reg
.f
);
447 lib
->crypto
->add_signer(lib
->crypto
, feature
->arg
.signer
,
448 name
, reg
->arg
.reg
.f
);
451 lib
->crypto
->add_hasher(lib
->crypto
, feature
->arg
.hasher
,
452 name
, reg
->arg
.reg
.f
);
455 lib
->crypto
->add_prf(lib
->crypto
, feature
->arg
.prf
,
456 name
, reg
->arg
.reg
.f
);
459 lib
->crypto
->add_dh(lib
->crypto
, feature
->arg
.dh_group
,
460 name
, reg
->arg
.reg
.f
);
463 lib
->crypto
->add_rng(lib
->crypto
, feature
->arg
.rng_quality
,
464 name
, reg
->arg
.reg
.f
);
466 case FEATURE_NONCE_GEN
:
467 lib
->crypto
->add_nonce_gen(lib
->crypto
,
468 name
, reg
->arg
.reg
.f
);
470 case FEATURE_PRIVKEY
:
471 case FEATURE_PRIVKEY_GEN
:
472 lib
->creds
->add_builder(lib
->creds
, CRED_PRIVATE_KEY
,
473 feature
->arg
.privkey
, reg
->arg
.reg
.final
,
477 lib
->creds
->add_builder(lib
->creds
, CRED_PUBLIC_KEY
,
478 feature
->arg
.pubkey
, reg
->arg
.reg
.final
,
481 case FEATURE_CERT_DECODE
:
482 case FEATURE_CERT_ENCODE
:
483 lib
->creds
->add_builder(lib
->creds
, CRED_CERTIFICATE
,
484 feature
->arg
.cert
, reg
->arg
.reg
.final
,
487 case FEATURE_CONTAINER_DECODE
:
488 case FEATURE_CONTAINER_ENCODE
:
489 lib
->creds
->add_builder(lib
->creds
, CRED_CONTAINER
,
490 feature
->arg
.container
, reg
->arg
.reg
.final
,
493 case FEATURE_DATABASE
:
494 lib
->db
->add_database(lib
->db
, reg
->arg
.reg
.f
);
496 case FEATURE_FETCHER
:
497 lib
->fetcher
->add_fetcher(lib
->fetcher
, reg
->arg
.reg
.f
,
498 feature
->arg
.fetcher
);
500 case FEATURE_RESOLVER
:
501 lib
->resolver
->add_resolver(lib
->resolver
, reg
->arg
.reg
.f
);
512 bool plugin_feature_unload(plugin_t
*plugin
, plugin_feature_t
*feature
,
513 plugin_feature_t
*reg
)
516 { /* noting to do for this feature */
519 if (reg
->kind
== FEATURE_CALLBACK
)
521 if (!reg
->arg
.cb
.f
||
522 reg
->arg
.cb
.f(plugin
, feature
, FALSE
, reg
->arg
.cb
.data
))
528 switch (feature
->type
)
530 case FEATURE_CRYPTER
:
531 lib
->crypto
->remove_crypter(lib
->crypto
, reg
->arg
.reg
.f
);
534 lib
->crypto
->remove_aead(lib
->crypto
, reg
->arg
.reg
.f
);
537 lib
->crypto
->remove_signer(lib
->crypto
, reg
->arg
.reg
.f
);
540 lib
->crypto
->remove_hasher(lib
->crypto
, reg
->arg
.reg
.f
);
543 lib
->crypto
->remove_prf(lib
->crypto
, reg
->arg
.reg
.f
);
546 lib
->crypto
->remove_dh(lib
->crypto
, reg
->arg
.reg
.f
);
549 lib
->crypto
->remove_rng(lib
->crypto
, reg
->arg
.reg
.f
);
551 case FEATURE_NONCE_GEN
:
552 lib
->crypto
->remove_nonce_gen(lib
->crypto
, reg
->arg
.reg
.f
);
554 case FEATURE_PRIVKEY
:
555 case FEATURE_PRIVKEY_GEN
:
556 lib
->creds
->remove_builder(lib
->creds
, reg
->arg
.reg
.f
);
559 lib
->creds
->remove_builder(lib
->creds
, reg
->arg
.reg
.f
);
561 case FEATURE_CERT_DECODE
:
562 case FEATURE_CERT_ENCODE
:
563 lib
->creds
->remove_builder(lib
->creds
, reg
->arg
.reg
.f
);
565 case FEATURE_CONTAINER_DECODE
:
566 case FEATURE_CONTAINER_ENCODE
:
567 lib
->creds
->remove_builder(lib
->creds
, reg
->arg
.reg
.f
);
569 case FEATURE_DATABASE
:
570 lib
->db
->remove_database(lib
->db
, reg
->arg
.reg
.f
);
572 case FEATURE_FETCHER
:
573 lib
->fetcher
->remove_fetcher(lib
->fetcher
, reg
->arg
.reg
.f
);
575 case FEATURE_RESOLVER
:
576 lib
->resolver
->remove_resolver(lib
->resolver
, reg
->arg
.reg
.f
);