294e5066bc9f80a13ce5428f5e8d02e16aae7818
[strongswan.git] / src / libcharon / plugins / stroke / stroke_list.c
1 /*
2 * Copyright (C) 2008 Martin Willi
3 * 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 "stroke_list.h"
17
18 #include <inttypes.h>
19 #include <time.h>
20
21 #ifdef HAVE_MALLINFO
22 #include <malloc.h>
23 #endif /* HAVE_MALLINFO */
24
25 #include <hydra.h>
26 #include <daemon.h>
27 #include <utils/linked_list.h>
28 #include <plugins/plugin.h>
29 #include <credentials/certificates/x509.h>
30 #include <credentials/certificates/ac.h>
31 #include <credentials/certificates/crl.h>
32 #include <credentials/certificates/pgp_certificate.h>
33 #include <credentials/ietf_attributes/ietf_attributes.h>
34 #include <config/peer_cfg.h>
35
36 /* warning intervals for list functions */
37 #define CERT_WARNING_INTERVAL 30 /* days */
38 #define CRL_WARNING_INTERVAL 7 /* days */
39 #define AC_WARNING_INTERVAL 1 /* day */
40
41 typedef struct private_stroke_list_t private_stroke_list_t;
42
43 /**
44 * private data of stroke_list
45 */
46 struct private_stroke_list_t {
47
48 /**
49 * public functions
50 */
51 stroke_list_t public;
52
53 /**
54 * Kind of *swan we run
55 */
56 char *swan;
57
58 /**
59 * timestamp of daemon start
60 */
61 time_t uptime;
62
63 /**
64 * strokes attribute provider
65 */
66 stroke_attribute_t *attribute;
67 };
68
69 /**
70 * Log tasks of a specific queue to out
71 */
72 static void log_task_q(FILE *out, ike_sa_t *ike_sa, task_queue_t q, char *name)
73 {
74 enumerator_t *enumerator;
75 bool has = FALSE;
76 task_t *task;
77
78 enumerator = ike_sa->create_task_enumerator(ike_sa, q);
79 while (enumerator->enumerate(enumerator, &task))
80 {
81 if (!has)
82 {
83 fprintf(out, "%12s[%d]: Tasks %s: ", ike_sa->get_name(ike_sa),
84 ike_sa->get_unique_id(ike_sa), name);
85 has = TRUE;
86 }
87 fprintf(out, "%N ", task_type_names, task->get_type(task));
88 }
89 enumerator->destroy(enumerator);
90 if (has)
91 {
92 fprintf(out, "\n");
93 }
94 }
95
96 /**
97 * log an IKE_SA to out
98 */
99 static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
100 {
101 ike_sa_id_t *id = ike_sa->get_id(ike_sa);
102 time_t now = time_monotonic(NULL);
103
104 fprintf(out, "%12s[%d]: %N",
105 ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
106 ike_sa_state_names, ike_sa->get_state(ike_sa));
107
108 if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED)
109 {
110 time_t established;
111
112 established = ike_sa->get_statistic(ike_sa, STAT_ESTABLISHED);
113 fprintf(out, " %V ago", &now, &established);
114 }
115
116 fprintf(out, ", %H[%Y]...%H[%Y]\n",
117 ike_sa->get_my_host(ike_sa), ike_sa->get_my_id(ike_sa),
118 ike_sa->get_other_host(ike_sa), ike_sa->get_other_id(ike_sa));
119
120 if (all)
121 {
122 proposal_t *ike_proposal;
123 identification_t *eap_id;
124
125 eap_id = ike_sa->get_other_eap_id(ike_sa);
126
127 if (!eap_id->equals(eap_id, ike_sa->get_other_id(ike_sa)))
128 {
129 fprintf(out, "%12s[%d]: Remote %s identity: %Y\n",
130 ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
131 ike_sa->get_version(ike_sa) == IKEV1 ? "XAuth" : "EAP",
132 eap_id);
133 }
134
135 ike_proposal = ike_sa->get_proposal(ike_sa);
136
137 fprintf(out, "%12s[%d]: %N SPIs: %.16"PRIx64"_i%s %.16"PRIx64"_r%s",
138 ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
139 ike_version_names, ike_sa->get_version(ike_sa),
140 id->get_initiator_spi(id), id->is_initiator(id) ? "*" : "",
141 id->get_responder_spi(id), id->is_initiator(id) ? "" : "*");
142
143
144 if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED)
145 {
146 time_t rekey, reauth;
147 peer_cfg_t *peer_cfg;
148
149 rekey = ike_sa->get_statistic(ike_sa, STAT_REKEY);
150 reauth = ike_sa->get_statistic(ike_sa, STAT_REAUTH);
151 peer_cfg = ike_sa->get_peer_cfg(ike_sa);
152
153 if (rekey)
154 {
155 fprintf(out, ", rekeying in %V", &rekey, &now);
156 }
157 if (reauth)
158 {
159 bool first = TRUE;
160 enumerator_t *enumerator;
161 auth_cfg_t *auth;
162
163 fprintf(out, ", ");
164 enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, TRUE);
165 while (enumerator->enumerate(enumerator, &auth))
166 {
167 if (!first)
168 {
169 fprintf(out, "+");
170 }
171 first = FALSE;
172 fprintf(out, "%N", auth_class_names,
173 auth->get(auth, AUTH_RULE_AUTH_CLASS));
174 }
175 enumerator->destroy(enumerator);
176 fprintf(out, " reauthentication in %V", &reauth, &now);
177 }
178 if (!rekey && !reauth)
179 {
180 fprintf(out, ", rekeying disabled");
181 }
182 }
183 fprintf(out, "\n");
184
185 if (ike_proposal)
186 {
187 char buf[BUF_LEN];
188
189 snprintf(buf, BUF_LEN, "%P", ike_proposal);
190 fprintf(out, "%12s[%d]: IKE proposal: %s\n",
191 ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
192 buf+4);
193 }
194
195 log_task_q(out, ike_sa, TASK_QUEUE_QUEUED, "queued");
196 log_task_q(out, ike_sa, TASK_QUEUE_ACTIVE, "active");
197 log_task_q(out, ike_sa, TASK_QUEUE_PASSIVE, "passive");
198 }
199 }
200
201 /**
202 * log an CHILD_SA to out
203 */
204 static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
205 {
206 time_t use_in, use_out, rekey, now;
207 u_int64_t bytes_in, bytes_out;
208 proposal_t *proposal;
209 child_cfg_t *config = child_sa->get_config(child_sa);
210
211 now = time_monotonic(NULL);
212
213 fprintf(out, "%12s{%d}: %N, %N%s",
214 child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
215 child_sa_state_names, child_sa->get_state(child_sa),
216 ipsec_mode_names, child_sa->get_mode(child_sa),
217 config->use_proxy_mode(config) ? "_PROXY" : "");
218
219 if (child_sa->get_state(child_sa) == CHILD_INSTALLED)
220 {
221 fprintf(out, ", %N%s SPIs: %.8x_i %.8x_o",
222 protocol_id_names, child_sa->get_protocol(child_sa),
223 child_sa->has_encap(child_sa) ? " in UDP" : "",
224 ntohl(child_sa->get_spi(child_sa, TRUE)),
225 ntohl(child_sa->get_spi(child_sa, FALSE)));
226
227 if (child_sa->get_ipcomp(child_sa) != IPCOMP_NONE)
228 {
229 fprintf(out, ", IPCOMP CPIs: %.4x_i %.4x_o",
230 ntohs(child_sa->get_cpi(child_sa, TRUE)),
231 ntohs(child_sa->get_cpi(child_sa, FALSE)));
232 }
233
234 if (all)
235 {
236 fprintf(out, "\n%12s{%d}: ", child_sa->get_name(child_sa),
237 child_sa->get_reqid(child_sa));
238
239 proposal = child_sa->get_proposal(child_sa);
240 if (proposal)
241 {
242 u_int16_t encr_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED;
243 u_int16_t encr_size = 0, int_size = 0;
244 u_int16_t esn = NO_EXT_SEQ_NUMBERS;
245
246 proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM,
247 &encr_alg, &encr_size);
248 proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM,
249 &int_alg, &int_size);
250 proposal->get_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS,
251 &esn, NULL);
252
253 if (encr_alg != ENCR_UNDEFINED)
254 {
255 fprintf(out, "%N", encryption_algorithm_names, encr_alg);
256 if (encr_size)
257 {
258 fprintf(out, "_%u", encr_size);
259 }
260 }
261 if (int_alg != AUTH_UNDEFINED)
262 {
263 fprintf(out, "/%N", integrity_algorithm_names, int_alg);
264 if (int_size)
265 {
266 fprintf(out, "_%u", int_size);
267 }
268 }
269 if (esn == EXT_SEQ_NUMBERS)
270 {
271 fprintf(out, "/ESN");
272 }
273 }
274
275 child_sa->get_usestats(child_sa, TRUE, &use_in, &bytes_in);
276 fprintf(out, ", %" PRIu64 " bytes_i", bytes_in);
277 if (use_in)
278 {
279 fprintf(out, " (%" PRIu64 "s ago)", (u_int64_t)(now - use_in));
280 }
281
282 child_sa->get_usestats(child_sa, FALSE, &use_out, &bytes_out);
283 fprintf(out, ", %" PRIu64 " bytes_o", bytes_out);
284 if (use_out)
285 {
286 fprintf(out, " (%" PRIu64 "s ago)", (u_int64_t)(now - use_out));
287 }
288 fprintf(out, ", rekeying ");
289
290 rekey = child_sa->get_lifetime(child_sa, FALSE);
291 if (rekey)
292 {
293 if (now > rekey)
294 {
295 fprintf(out, "active");
296 }
297 else
298 {
299 fprintf(out, "in %V", &now, &rekey);
300 }
301 }
302 else
303 {
304 fprintf(out, "disabled");
305 }
306
307 }
308 }
309 else if (child_sa->get_state(child_sa) == CHILD_REKEYING)
310 {
311 rekey = child_sa->get_lifetime(child_sa, TRUE);
312 fprintf(out, ", expires in %V", &now, &rekey);
313 }
314
315 fprintf(out, "\n%12s{%d}: %#R=== %#R\n",
316 child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
317 child_sa->get_traffic_selectors(child_sa, TRUE),
318 child_sa->get_traffic_selectors(child_sa, FALSE));
319 }
320
321 /**
322 * Log a configs local or remote authentication config to out
323 */
324 static void log_auth_cfgs(FILE *out, peer_cfg_t *peer_cfg, bool local)
325 {
326 enumerator_t *enumerator, *rules;
327 auth_rule_t rule;
328 auth_cfg_t *auth;
329 auth_class_t auth_class;
330 identification_t *id;
331 certificate_t *cert;
332 cert_validation_t valid;
333 char *name;
334
335 name = peer_cfg->get_name(peer_cfg);
336
337 enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, local);
338 while (enumerator->enumerate(enumerator, &auth))
339 {
340 fprintf(out, "%12s: %s [%Y] uses ", name, local ? "local: " : "remote:",
341 auth->get(auth, AUTH_RULE_IDENTITY));
342
343 auth_class = (uintptr_t)auth->get(auth, AUTH_RULE_AUTH_CLASS);
344 if (auth_class == AUTH_CLASS_EAP)
345 {
346 if ((uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE) == EAP_NAK)
347 {
348 fprintf(out, "EAP authentication");
349 }
350 else
351 {
352 if ((uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR))
353 {
354 fprintf(out, "EAP_%" PRIuPTR "-%" PRIuPTR " authentication",
355 (uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE),
356 (uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR));
357 }
358 else
359 {
360 fprintf(out, "%N authentication", eap_type_names,
361 (uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE));
362 }
363 }
364 id = auth->get(auth, AUTH_RULE_EAP_IDENTITY);
365 if (id)
366 {
367 fprintf(out, " with EAP identity '%Y'", id);
368 }
369 fprintf(out, "\n");
370 }
371 else if (auth_class == AUTH_CLASS_XAUTH)
372 {
373 fprintf(out, "%N authentication: %s", auth_class_names, auth_class,
374 auth->get(auth, AUTH_RULE_XAUTH_BACKEND) ?: "any");
375 id = auth->get(auth, AUTH_RULE_XAUTH_IDENTITY);
376 if (id)
377 {
378 fprintf(out, " with XAuth identity '%Y'", id);
379 }
380 fprintf(out, "\n");
381 }
382 else
383 {
384 fprintf(out, "%N authentication\n", auth_class_names, auth_class);
385 }
386
387 cert = auth->get(auth, AUTH_RULE_CA_CERT);
388 if (cert)
389 {
390 fprintf(out, "%12s: ca: \"%Y\"\n", name, cert->get_subject(cert));
391 }
392
393 cert = auth->get(auth, AUTH_RULE_IM_CERT);
394 if (cert)
395 {
396 fprintf(out, "%12s: im-ca: \"%Y\"\n", name, cert->get_subject(cert));
397 }
398
399 cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
400 if (cert)
401 {
402 fprintf(out, "%12s: cert: \"%Y\"\n", name,
403 cert->get_subject(cert));
404 }
405
406 valid = (uintptr_t)auth->get(auth, AUTH_RULE_OCSP_VALIDATION);
407 if (valid != VALIDATION_FAILED)
408 {
409 fprintf(out, "%12s: ocsp: status must be GOOD%s\n", name,
410 (valid == VALIDATION_SKIPPED) ? " or SKIPPED" : "");
411 }
412
413 valid = (uintptr_t)auth->get(auth, AUTH_RULE_CRL_VALIDATION);
414 if (valid != VALIDATION_FAILED)
415 {
416 fprintf(out, "%12s: crl: status must be GOOD%s\n", name,
417 (valid == VALIDATION_SKIPPED) ? " or SKIPPED" : "");
418 }
419
420 rules = auth->create_enumerator(auth);
421 while (rules->enumerate(rules, &rule, &id))
422 {
423 if (rule == AUTH_RULE_GROUP)
424 {
425 fprintf(out, "%12s: group: %Y\n", name, id);
426 }
427 }
428 rules->destroy(rules);
429 }
430 enumerator->destroy(enumerator);
431 }
432
433 METHOD(stroke_list_t, status, void,
434 private_stroke_list_t *this, stroke_msg_t *msg, FILE *out,
435 bool all, bool wait)
436 {
437 enumerator_t *enumerator, *children;
438 ike_cfg_t *ike_cfg;
439 child_cfg_t *child_cfg;
440 child_sa_t *child_sa;
441 ike_sa_t *ike_sa;
442 linked_list_t *my_ts, *other_ts;
443 bool first, found = FALSE;
444 char *name = msg->status.name;
445 u_int half_open;
446
447 if (all)
448 {
449 peer_cfg_t *peer_cfg;
450 ike_version_t ike_version;
451 char *pool;
452 host_t *host;
453 u_int32_t dpd;
454 time_t since, now;
455 u_int size, online, offline, i;
456 now = time_monotonic(NULL);
457 since = time(NULL) - (now - this->uptime);
458
459 fprintf(out, "Status of IKE charon daemon (%sSwan "VERSION"):\n",
460 this->swan);
461 fprintf(out, " uptime: %V, since %T\n", &now, &this->uptime, &since,
462 FALSE);
463 #ifdef HAVE_MALLINFO
464 {
465 struct mallinfo mi = mallinfo();
466
467 fprintf(out, " malloc: sbrk %d, mmap %d, used %d, free %d\n",
468 mi.arena, mi.hblkhd, mi.uordblks, mi.fordblks);
469 }
470 #endif /* HAVE_MALLINFO */
471 fprintf(out, " worker threads: %d of %d idle, ",
472 lib->processor->get_idle_threads(lib->processor),
473 lib->processor->get_total_threads(lib->processor));
474 for (i = 0; i < JOB_PRIO_MAX; i++)
475 {
476 fprintf(out, "%s%d", i == 0 ? "" : "/",
477 lib->processor->get_working_threads(lib->processor, i));
478 }
479 fprintf(out, " working, job queue: ");
480 for (i = 0; i < JOB_PRIO_MAX; i++)
481 {
482 fprintf(out, "%s%d", i == 0 ? "" : "/",
483 lib->processor->get_job_load(lib->processor, i));
484 }
485 fprintf(out, ", scheduled: %d\n",
486 lib->scheduler->get_job_load(lib->scheduler));
487 fprintf(out, " loaded plugins: %s\n",
488 lib->plugins->loaded_plugins(lib->plugins));
489
490 first = TRUE;
491 enumerator = this->attribute->create_pool_enumerator(this->attribute);
492 while (enumerator->enumerate(enumerator, &pool, &size, &online, &offline))
493 {
494 if (name && !streq(name, pool))
495 {
496 continue;
497 }
498 if (first)
499 {
500 first = FALSE;
501 fprintf(out, "Virtual IP pools (size/online/offline):\n");
502 }
503 fprintf(out, " %s: %u/%u/%u\n", pool, size, online, offline);
504 }
505 enumerator->destroy(enumerator);
506
507 enumerator = hydra->kernel_interface->create_address_enumerator(
508 hydra->kernel_interface, FALSE, FALSE);
509 fprintf(out, "Listening IP addresses:\n");
510 while (enumerator->enumerate(enumerator, (void**)&host))
511 {
512 fprintf(out, " %H\n", host);
513 }
514 enumerator->destroy(enumerator);
515
516 fprintf(out, "Connections:\n");
517 enumerator = charon->backends->create_peer_cfg_enumerator(
518 charon->backends, NULL, NULL, NULL, NULL, IKE_ANY);
519 while (enumerator->enumerate(enumerator, &peer_cfg))
520 {
521 char *my_addr, *other_addr;
522 bool my_allow_any, other_allow_any;
523
524 if (name && !streq(name, peer_cfg->get_name(peer_cfg)))
525 {
526 continue;
527 }
528
529 ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
530 ike_version = peer_cfg->get_ike_version(peer_cfg);
531 my_addr = ike_cfg->get_my_addr(ike_cfg, &my_allow_any);
532 other_addr = ike_cfg->get_other_addr(ike_cfg, &other_allow_any);
533 fprintf(out, "%12s: %s%s...%s%s %N", peer_cfg->get_name(peer_cfg),
534 my_allow_any ? "%":"", my_addr,
535 other_allow_any ? "%":"", other_addr,
536 ike_version_names, ike_version);
537
538 if (ike_version == IKEV1 && peer_cfg->use_aggressive(peer_cfg))
539 {
540 fprintf(out, " Aggressive");
541 }
542
543 dpd = peer_cfg->get_dpd(peer_cfg);
544 if (dpd)
545 {
546 fprintf(out, ", dpddelay=%us", dpd);
547 }
548 fprintf(out, "\n");
549
550 log_auth_cfgs(out, peer_cfg, TRUE);
551 log_auth_cfgs(out, peer_cfg, FALSE);
552
553 children = peer_cfg->create_child_cfg_enumerator(peer_cfg);
554 while (children->enumerate(children, &child_cfg))
555 {
556 my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL);
557 other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL);
558 fprintf(out, "%12s: child: %#R=== %#R%N",
559 child_cfg->get_name(child_cfg), my_ts, other_ts,
560 ipsec_mode_names, child_cfg->get_mode(child_cfg));
561 my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
562 other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
563
564 if (dpd)
565 {
566 fprintf(out, ", dpdaction=%N", action_names,
567 child_cfg->get_dpd_action(child_cfg));
568 }
569 fprintf(out, "\n");
570 }
571 children->destroy(children);
572 }
573 enumerator->destroy(enumerator);
574 }
575
576 /* Enumerate shunt policies */
577 first = TRUE;
578 enumerator = charon->shunts->create_enumerator(charon->shunts);
579 while (enumerator->enumerate(enumerator, &child_cfg))
580 {
581 if (name && !streq(name, child_cfg->get_name(child_cfg)))
582 {
583 continue;
584 }
585 if (first)
586 {
587 fprintf(out, "Shunted Connections:\n");
588 first = FALSE;
589 }
590 my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL);
591 other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL);
592 fprintf(out, "%12s: %#R=== %#R%N\n",
593 child_cfg->get_name(child_cfg), my_ts, other_ts,
594 ipsec_mode_names, child_cfg->get_mode(child_cfg));
595 my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
596 other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
597 }
598 enumerator->destroy(enumerator);
599
600 /* Enumerate traps */
601 first = TRUE;
602 enumerator = charon->traps->create_enumerator(charon->traps);
603 while (enumerator->enumerate(enumerator, NULL, &child_sa))
604 {
605 if (name && !streq(name, child_sa->get_name(child_sa)))
606 {
607 continue;
608 }
609 if (first)
610 {
611 fprintf(out, "Routed Connections:\n");
612 first = FALSE;
613 }
614 log_child_sa(out, child_sa, all);
615 }
616 enumerator->destroy(enumerator);
617
618 half_open = charon->ike_sa_manager->get_half_open_count(
619 charon->ike_sa_manager, NULL);
620 fprintf(out, "Security Associations (%u up, %u connecting):\n",
621 charon->ike_sa_manager->get_count(charon->ike_sa_manager) - half_open,
622 half_open);
623 enumerator = charon->controller->create_ike_sa_enumerator(
624 charon->controller, wait);
625 while (enumerator->enumerate(enumerator, &ike_sa))
626 {
627 bool ike_printed = FALSE;
628 enumerator_t *children = ike_sa->create_child_sa_enumerator(ike_sa);
629
630 if (name == NULL || streq(name, ike_sa->get_name(ike_sa)))
631 {
632 log_ike_sa(out, ike_sa, all);
633 found = TRUE;
634 ike_printed = TRUE;
635 }
636
637 while (children->enumerate(children, (void**)&child_sa))
638 {
639 if (name == NULL || streq(name, child_sa->get_name(child_sa)))
640 {
641 if (!ike_printed)
642 {
643 log_ike_sa(out, ike_sa, all);
644 found = TRUE;
645 ike_printed = TRUE;
646 }
647 log_child_sa(out, child_sa, all);
648 }
649 }
650 children->destroy(children);
651 }
652 enumerator->destroy(enumerator);
653
654 if (!found)
655 {
656 if (name)
657 {
658 fprintf(out, " no match\n");
659 }
660 else
661 {
662 fprintf(out, " none\n");
663 }
664 }
665 }
666
667 /**
668 * create a unique certificate list without duplicates
669 * certicates having the same issuer are grouped together.
670 */
671 static linked_list_t* create_unique_cert_list(certificate_type_t type)
672 {
673 linked_list_t *list = linked_list_create();
674 enumerator_t *enumerator = lib->credmgr->create_cert_enumerator(
675 lib->credmgr, type, KEY_ANY, NULL, FALSE);
676 certificate_t *cert;
677
678 while (enumerator->enumerate(enumerator, (void**)&cert))
679 {
680 enumerator_t *added = list->create_enumerator(list);
681 identification_t *issuer = cert->get_issuer(cert);
682 bool previous_same, same = FALSE, found = FALSE;
683 certificate_t *list_cert;
684
685 while (added->enumerate(added, (void**)&list_cert))
686 {
687 if (list_cert->equals(list_cert, cert))
688 { /* stop if we found a duplicate*/
689 found = TRUE;
690 break;
691 }
692 previous_same = same;
693 same = list_cert->has_issuer(list_cert, issuer);
694 if (previous_same && !same)
695 { /* group certificates with same issuer */
696 break;
697 }
698 }
699 if (!found)
700 {
701 list->insert_before(list, added, cert->get_ref(cert));
702 }
703 added->destroy(added);
704 }
705 enumerator->destroy(enumerator);
706 return list;
707 }
708
709 /**
710 * Print a single public key.
711 */
712 static void list_public_key(public_key_t *public, FILE *out)
713 {
714 private_key_t *private = NULL;
715 chunk_t keyid;
716 identification_t *id;
717
718 if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &keyid))
719 {
720 id = identification_create_from_encoding(ID_KEY_ID, keyid);
721 private = lib->credmgr->get_private(lib->credmgr,
722 public->get_type(public), id, NULL);
723 id->destroy(id);
724 }
725
726 fprintf(out, " pubkey: %N %d bits%s\n",
727 key_type_names, public->get_type(public),
728 public->get_keysize(public),
729 private ? ", has private key" : "");
730 if (public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &keyid))
731 {
732 fprintf(out, " keyid: %#B\n", &keyid);
733 }
734 if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &keyid))
735 {
736 fprintf(out, " subjkey: %#B\n", &keyid);
737 }
738 DESTROY_IF(private);
739 }
740
741 /**
742 * list all raw public keys
743 */
744 static void stroke_list_pubkeys(linked_list_t *list, bool utc, FILE *out)
745 {
746 bool first = TRUE;
747 time_t now = time(NULL), notBefore, notAfter;
748 enumerator_t *enumerator;
749 certificate_t *cert;
750
751 enumerator = list->create_enumerator(list);
752 while (enumerator->enumerate(enumerator, (void**)&cert))
753 {
754 identification_t *subject = cert->get_subject(cert);
755 public_key_t *public = cert->get_public_key(cert);
756
757 if (public)
758 {
759 if (first)
760 {
761 fprintf(out, "\n");
762 fprintf(out, "List of Raw Public Keys:\n");
763 first = FALSE;
764 }
765 fprintf(out, "\n");
766
767 /* list subject if available */
768 if (subject->get_type(subject) != ID_KEY_ID)
769 {
770 fprintf(out, " subject: %#Y\n", subject);
771 }
772
773 /* list validity if available*/
774 cert->get_validity(cert, &now, &notBefore, &notAfter);
775 if (notBefore != UNDEFINED_TIME && notAfter != UNDEFINED_TIME)
776 {
777 fprintf(out, " validity: not before %T, ", &notBefore, utc);
778 if (now < notBefore)
779 {
780 fprintf(out, "not valid yet (valid in %V)\n", &now, &notBefore);
781 }
782 else
783 {
784 fprintf(out, "ok\n");
785 }
786 fprintf(out, " not after %T, ", &notAfter, utc);
787 if (now > notAfter)
788 {
789 fprintf(out, "expired (%V ago)\n", &now, &notAfter);
790 }
791 else
792 {
793 fprintf(out, "ok");
794 if (now > notAfter - CERT_WARNING_INTERVAL * 60 * 60 * 24)
795 {
796 fprintf(out, " (expires in %V)", &now, &notAfter);
797 }
798 fprintf(out, " \n");
799 }
800 }
801
802 list_public_key(public, out);
803 public->destroy(public);
804 }
805 }
806 enumerator->destroy(enumerator);
807 }
808
809 /**
810 * list OpenPGP certificates
811 */
812 static void stroke_list_pgp(linked_list_t *list,bool utc, FILE *out)
813 {
814 bool first = TRUE;
815 time_t now = time(NULL);
816 enumerator_t *enumerator = list->create_enumerator(list);
817 certificate_t *cert;
818
819 while (enumerator->enumerate(enumerator, (void**)&cert))
820 {
821 time_t created, until;
822 public_key_t *public;
823 pgp_certificate_t *pgp_cert = (pgp_certificate_t*)cert;
824 chunk_t fingerprint = pgp_cert->get_fingerprint(pgp_cert);
825
826 if (first)
827 {
828
829 fprintf(out, "\n");
830 fprintf(out, "List of PGP End Entity Certificates:\n");
831 first = FALSE;
832 }
833 fprintf(out, "\n");
834 fprintf(out, " userid: '%Y'\n", cert->get_subject(cert));
835
836 fprintf(out, " digest: %#B\n", &fingerprint);
837
838 /* list validity */
839 cert->get_validity(cert, &now, &created, &until);
840 fprintf(out, " created: %T\n", &created, utc);
841 fprintf(out, " until: %T%s\n", &until, utc,
842 (until == TIME_32_BIT_SIGNED_MAX) ? " (expires never)":"");
843
844 public = cert->get_public_key(cert);
845 if (public)
846 {
847 list_public_key(public, out);
848 public->destroy(public);
849 }
850 }
851 enumerator->destroy(enumerator);
852 }
853
854 /**
855 * list all X.509 certificates matching the flags
856 */
857 static void stroke_list_certs(linked_list_t *list, char *label,
858 x509_flag_t flags, bool utc, FILE *out)
859 {
860 bool first = TRUE;
861 time_t now = time(NULL);
862 enumerator_t *enumerator;
863 certificate_t *cert;
864 x509_flag_t flag_mask;
865
866 /* mask all auxiliary flags */
867 flag_mask = ~(X509_SERVER_AUTH | X509_CLIENT_AUTH | X509_IKE_INTERMEDIATE |
868 X509_SELF_SIGNED | X509_IP_ADDR_BLOCKS);
869
870 enumerator = list->create_enumerator(list);
871 while (enumerator->enumerate(enumerator, (void**)&cert))
872 {
873 x509_t *x509 = (x509_t*)cert;
874 x509_flag_t x509_flags = x509->get_flags(x509) & flag_mask;
875
876 /* list only if flag is set or flag == 0 */
877 if ((x509_flags & flags) || (x509_flags == flags))
878 {
879 enumerator_t *enumerator;
880 identification_t *altName;
881 bool first_altName = TRUE;
882 u_int pathlen;
883 chunk_t serial, authkey;
884 time_t notBefore, notAfter;
885 public_key_t *public;
886
887 if (first)
888 {
889 fprintf(out, "\n");
890 fprintf(out, "List of %s:\n", label);
891 first = FALSE;
892 }
893 fprintf(out, "\n");
894
895 /* list subjectAltNames */
896 enumerator = x509->create_subjectAltName_enumerator(x509);
897 while (enumerator->enumerate(enumerator, (void**)&altName))
898 {
899 if (first_altName)
900 {
901 fprintf(out, " altNames: ");
902 first_altName = FALSE;
903 }
904 else
905 {
906 fprintf(out, ", ");
907 }
908 fprintf(out, "%Y", altName);
909 }
910 if (!first_altName)
911 {
912 fprintf(out, "\n");
913 }
914 enumerator->destroy(enumerator);
915
916 fprintf(out, " subject: \"%Y\"\n", cert->get_subject(cert));
917 fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert));
918 serial = chunk_skip_zero(x509->get_serial(x509));
919 fprintf(out, " serial: %#B\n", &serial);
920
921 /* list validity */
922 cert->get_validity(cert, &now, &notBefore, &notAfter);
923 fprintf(out, " validity: not before %T, ", &notBefore, utc);
924 if (now < notBefore)
925 {
926 fprintf(out, "not valid yet (valid in %V)\n", &now, &notBefore);
927 }
928 else
929 {
930 fprintf(out, "ok\n");
931 }
932 fprintf(out, " not after %T, ", &notAfter, utc);
933 if (now > notAfter)
934 {
935 fprintf(out, "expired (%V ago)\n", &now, &notAfter);
936 }
937 else
938 {
939 fprintf(out, "ok");
940 if (now > notAfter - CERT_WARNING_INTERVAL * 60 * 60 * 24)
941 {
942 fprintf(out, " (expires in %V)", &now, &notAfter);
943 }
944 fprintf(out, " \n");
945 }
946
947 public = cert->get_public_key(cert);
948 if (public)
949 {
950 list_public_key(public, out);
951 public->destroy(public);
952 }
953
954 /* list optional authorityKeyIdentifier */
955 authkey = x509->get_authKeyIdentifier(x509);
956 if (authkey.ptr)
957 {
958 fprintf(out, " authkey: %#B\n", &authkey);
959 }
960
961 /* list optional pathLenConstraint */
962 pathlen = x509->get_constraint(x509, X509_PATH_LEN);
963 if (pathlen != X509_NO_CONSTRAINT)
964 {
965 fprintf(out, " pathlen: %u\n", pathlen);
966 }
967
968 /* list optional ipAddrBlocks */
969 if (x509->get_flags(x509) & X509_IP_ADDR_BLOCKS)
970 {
971 traffic_selector_t *ipAddrBlock;
972 bool first_ipAddrBlock = TRUE;
973
974 fprintf(out, " addresses: ");
975 enumerator = x509->create_ipAddrBlock_enumerator(x509);
976 while (enumerator->enumerate(enumerator, &ipAddrBlock))
977 {
978 if (first_ipAddrBlock)
979 {
980 first_ipAddrBlock = FALSE;
981 }
982 else
983 {
984 fprintf(out, ", ");
985 }
986 fprintf(out, "%R", ipAddrBlock);
987 }
988 enumerator->destroy(enumerator);
989 fprintf(out, "\n");
990 }
991 }
992 }
993 enumerator->destroy(enumerator);
994 }
995
996 /**
997 * list all X.509 attribute certificates
998 */
999 static void stroke_list_acerts(linked_list_t *list, bool utc, FILE *out)
1000 {
1001 bool first = TRUE;
1002 time_t thisUpdate, nextUpdate, now = time(NULL);
1003 enumerator_t *enumerator = list->create_enumerator(list);
1004 certificate_t *cert;
1005
1006 while (enumerator->enumerate(enumerator, (void**)&cert))
1007 {
1008 ac_t *ac = (ac_t*)cert;
1009 identification_t *id;
1010 ietf_attributes_t *groups;
1011 chunk_t chunk;
1012
1013 if (first)
1014 {
1015 fprintf(out, "\n");
1016 fprintf(out, "List of X.509 Attribute Certificates:\n");
1017 first = FALSE;
1018 }
1019 fprintf(out, "\n");
1020
1021 id = cert->get_subject(cert);
1022 if (id)
1023 {
1024 fprintf(out, " holder: \"%Y\"\n", id);
1025 }
1026 id = ac->get_holderIssuer(ac);
1027 if (id)
1028 {
1029 fprintf(out, " hissuer: \"%Y\"\n", id);
1030 }
1031 chunk = chunk_skip_zero(ac->get_holderSerial(ac));
1032 if (chunk.ptr)
1033 {
1034 fprintf(out, " hserial: %#B\n", &chunk);
1035 }
1036 groups = ac->get_groups(ac);
1037 if (groups)
1038 {
1039 fprintf(out, " groups: %s\n", groups->get_string(groups));
1040 groups->destroy(groups);
1041 }
1042 fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert));
1043 chunk = chunk_skip_zero(ac->get_serial(ac));
1044 fprintf(out, " serial: %#B\n", &chunk);
1045
1046 /* list validity */
1047 cert->get_validity(cert, &now, &thisUpdate, &nextUpdate);
1048 fprintf(out, " updates: this %T\n", &thisUpdate, utc);
1049 fprintf(out, " next %T, ", &nextUpdate, utc);
1050 if (now > nextUpdate)
1051 {
1052 fprintf(out, "expired (%V ago)\n", &now, &nextUpdate);
1053 }
1054 else
1055 {
1056 fprintf(out, "ok");
1057 if (now > nextUpdate - AC_WARNING_INTERVAL * 60 * 60 * 24)
1058 {
1059 fprintf(out, " (expires in %V)", &now, &nextUpdate);
1060 }
1061 fprintf(out, " \n");
1062 }
1063
1064 /* list optional authorityKeyIdentifier */
1065 chunk = ac->get_authKeyIdentifier(ac);
1066 if (chunk.ptr)
1067 {
1068 fprintf(out, " authkey: %#B\n", &chunk);
1069 }
1070 }
1071 enumerator->destroy(enumerator);
1072 }
1073
1074 /**
1075 * list all X.509 CRLs
1076 */
1077 static void stroke_list_crls(linked_list_t *list, bool utc, FILE *out)
1078 {
1079 bool first = TRUE;
1080 time_t thisUpdate, nextUpdate, now = time(NULL);
1081 enumerator_t *enumerator = list->create_enumerator(list);
1082 certificate_t *cert;
1083
1084 while (enumerator->enumerate(enumerator, (void**)&cert))
1085 {
1086 crl_t *crl = (crl_t*)cert;
1087 chunk_t chunk;
1088
1089 if (first)
1090 {
1091 fprintf(out, "\n");
1092 fprintf(out, "List of X.509 CRLs:\n");
1093 first = FALSE;
1094 }
1095 fprintf(out, "\n");
1096
1097 fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert));
1098
1099 /* list optional crlNumber */
1100 chunk = chunk_skip_zero(crl->get_serial(crl));
1101 if (chunk.ptr)
1102 {
1103 fprintf(out, " serial: %#B\n", &chunk);
1104 }
1105 if (crl->is_delta_crl(crl, &chunk))
1106 {
1107 chunk = chunk_skip_zero(chunk);
1108 fprintf(out, " delta for: %#B\n", &chunk);
1109 }
1110
1111 /* count the number of revoked certificates */
1112 {
1113 int count = 0;
1114 enumerator_t *enumerator = crl->create_enumerator(crl);
1115
1116 while (enumerator->enumerate(enumerator, NULL, NULL, NULL))
1117 {
1118 count++;
1119 }
1120 fprintf(out, " revoked: %d certificate%s\n", count,
1121 (count == 1)? "" : "s");
1122 enumerator->destroy(enumerator);
1123 }
1124
1125 /* list validity */
1126 cert->get_validity(cert, &now, &thisUpdate, &nextUpdate);
1127 fprintf(out, " updates: this %T\n", &thisUpdate, utc);
1128 fprintf(out, " next %T, ", &nextUpdate, utc);
1129 if (now > nextUpdate)
1130 {
1131 fprintf(out, "expired (%V ago)\n", &now, &nextUpdate);
1132 }
1133 else
1134 {
1135 fprintf(out, "ok");
1136 if (now > nextUpdate - CRL_WARNING_INTERVAL * 60 * 60 * 24)
1137 {
1138 fprintf(out, " (expires in %V)", &now, &nextUpdate);
1139 }
1140 fprintf(out, " \n");
1141 }
1142
1143 /* list optional authorityKeyIdentifier */
1144 chunk = crl->get_authKeyIdentifier(crl);
1145 if (chunk.ptr)
1146 {
1147 fprintf(out, " authkey: %#B\n", &chunk);
1148 }
1149 }
1150 enumerator->destroy(enumerator);
1151 }
1152
1153 /**
1154 * list all OCSP responses
1155 */
1156 static void stroke_list_ocsp(linked_list_t* list, bool utc, FILE *out)
1157 {
1158 bool first = TRUE, ok;
1159 enumerator_t *enumerator = list->create_enumerator(list);
1160 certificate_t *cert;
1161 time_t produced, usable, now = time(NULL);
1162
1163 while (enumerator->enumerate(enumerator, (void**)&cert))
1164 {
1165 if (first)
1166 {
1167 fprintf(out, "\n");
1168 fprintf(out, "List of OCSP responses:\n");
1169 fprintf(out, "\n");
1170 first = FALSE;
1171 }
1172 fprintf(out, " signer: \"%Y\"\n", cert->get_issuer(cert));
1173
1174 /* check validity */
1175 ok = cert->get_validity(cert, &now, &produced, &usable);
1176 fprintf(out, " validity: produced at %T\n", &produced, utc);
1177 fprintf(out, " usable till %T, ", &usable, utc);
1178 if (ok)
1179 {
1180 fprintf(out, "ok\n");
1181 }
1182 else
1183 {
1184 fprintf(out, "expired (%V ago)\n", &now, &usable);
1185 }
1186 }
1187 enumerator->destroy(enumerator);
1188 }
1189
1190 /**
1191 * Print the name of an algorithm plus the name of the plugin that registered it
1192 */
1193 static void print_alg(FILE *out, int *len, enum_name_t *alg_names, int alg_type,
1194 const char *plugin_name)
1195 {
1196 char alg_name[BUF_LEN];
1197 int alg_name_len;
1198
1199 if (alg_names)
1200 {
1201 alg_name_len = sprintf(alg_name, " %N[%s]", alg_names, alg_type,
1202 plugin_name);
1203 }
1204 else
1205 {
1206 alg_name_len = sprintf(alg_name, " [%s]", plugin_name);
1207 }
1208 if (*len + alg_name_len > CRYPTO_MAX_ALG_LINE)
1209 {
1210 fprintf(out, "\n ");
1211 *len = 13;
1212 }
1213 fprintf(out, "%s", alg_name);
1214 *len += alg_name_len;
1215 }
1216
1217 /**
1218 * List of registered cryptographical algorithms
1219 */
1220 static void list_algs(FILE *out)
1221 {
1222 enumerator_t *enumerator;
1223 encryption_algorithm_t encryption;
1224 integrity_algorithm_t integrity;
1225 hash_algorithm_t hash;
1226 pseudo_random_function_t prf;
1227 diffie_hellman_group_t group;
1228 rng_quality_t quality;
1229 const char *plugin_name;
1230 int len;
1231
1232 fprintf(out, "\n");
1233 fprintf(out, "List of registered IKEv2 Algorithms:\n");
1234 fprintf(out, "\n encryption:");
1235 len = 13;
1236 enumerator = lib->crypto->create_crypter_enumerator(lib->crypto);
1237 while (enumerator->enumerate(enumerator, &encryption, &plugin_name))
1238 {
1239 print_alg(out, &len, encryption_algorithm_names, encryption, plugin_name);
1240 }
1241 enumerator->destroy(enumerator);
1242 fprintf(out, "\n integrity: ");
1243 len = 13;
1244 enumerator = lib->crypto->create_signer_enumerator(lib->crypto);
1245 while (enumerator->enumerate(enumerator, &integrity, &plugin_name))
1246 {
1247 print_alg(out, &len, integrity_algorithm_names, integrity, plugin_name);
1248 }
1249 enumerator->destroy(enumerator);
1250 fprintf(out, "\n aead: ");
1251 len = 13;
1252 enumerator = lib->crypto->create_aead_enumerator(lib->crypto);
1253 while (enumerator->enumerate(enumerator, &encryption, &plugin_name))
1254 {
1255 print_alg(out, &len, encryption_algorithm_names, encryption, plugin_name);
1256 }
1257 enumerator->destroy(enumerator);
1258 fprintf(out, "\n hasher: ");
1259 len = 13;
1260 enumerator = lib->crypto->create_hasher_enumerator(lib->crypto);
1261 while (enumerator->enumerate(enumerator, &hash, &plugin_name))
1262 {
1263 print_alg(out, &len, hash_algorithm_names, hash, plugin_name);
1264 }
1265 enumerator->destroy(enumerator);
1266 fprintf(out, "\n prf: ");
1267 len = 13;
1268 enumerator = lib->crypto->create_prf_enumerator(lib->crypto);
1269 while (enumerator->enumerate(enumerator, &prf, &plugin_name))
1270 {
1271 print_alg(out, &len, pseudo_random_function_names, prf, plugin_name);
1272 }
1273 enumerator->destroy(enumerator);
1274 fprintf(out, "\n dh-group: ");
1275 len = 13;
1276 enumerator = lib->crypto->create_dh_enumerator(lib->crypto);
1277 while (enumerator->enumerate(enumerator, &group, &plugin_name))
1278 {
1279 print_alg(out, &len, diffie_hellman_group_names, group, plugin_name);
1280 }
1281 enumerator->destroy(enumerator);
1282 fprintf(out, "\n random-gen:");
1283 len = 13;
1284 enumerator = lib->crypto->create_rng_enumerator(lib->crypto);
1285 while (enumerator->enumerate(enumerator, &quality, &plugin_name))
1286 {
1287 print_alg(out, &len, rng_quality_names, quality, plugin_name);
1288 }
1289 enumerator->destroy(enumerator);
1290 fprintf(out, "\n nonce-gen: ");
1291 len = 13;
1292 enumerator = lib->crypto->create_nonce_gen_enumerator(lib->crypto);
1293 while (enumerator->enumerate(enumerator, &plugin_name))
1294 {
1295 print_alg(out, &len, NULL, 0, plugin_name);
1296 }
1297 enumerator->destroy(enumerator);
1298 fprintf(out, "\n");
1299 }
1300
1301 /**
1302 * List loaded plugin information
1303 */
1304 static void list_plugins(FILE *out)
1305 {
1306 plugin_feature_t *features, *fp;
1307 enumerator_t *enumerator;
1308 linked_list_t *list;
1309 plugin_t *plugin;
1310 int count, i;
1311 bool loaded;
1312 char *str;
1313
1314 fprintf(out, "\n");
1315 fprintf(out, "List of loaded Plugins:\n");
1316 fprintf(out, "\n");
1317
1318 enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
1319 while (enumerator->enumerate(enumerator, &plugin, &list))
1320 {
1321 fprintf(out, "%s:\n", plugin->get_name(plugin));
1322 if (plugin->get_features)
1323 {
1324 count = plugin->get_features(plugin, &features);
1325 for (i = 0; i < count; i++)
1326 {
1327 str = plugin_feature_get_string(&features[i]);
1328 switch (features[i].kind)
1329 {
1330 case FEATURE_PROVIDE:
1331 fp = &features[i];
1332 loaded = list->find_first(list, NULL,
1333 (void**)&fp) == SUCCESS;
1334 fprintf(out, " %s%s\n",
1335 str, loaded ? "" : " (not loaded)");
1336 break;
1337 case FEATURE_DEPENDS:
1338 fprintf(out, " %s\n", str);
1339 break;
1340 case FEATURE_SDEPEND:
1341 fprintf(out, " %s (soft)\n", str);
1342 break;
1343 default:
1344 break;
1345 }
1346 free(str);
1347 }
1348 }
1349 }
1350 enumerator->destroy(enumerator);
1351 }
1352
1353 METHOD(stroke_list_t, list, void,
1354 private_stroke_list_t *this, stroke_msg_t *msg, FILE *out)
1355 {
1356 linked_list_t *cert_list = NULL;
1357
1358 if (msg->list.flags & LIST_PUBKEYS)
1359 {
1360 linked_list_t *pubkey_list = create_unique_cert_list(CERT_TRUSTED_PUBKEY);
1361
1362 stroke_list_pubkeys(pubkey_list, msg->list.utc, out);
1363 pubkey_list->destroy_offset(pubkey_list, offsetof(certificate_t, destroy));
1364 }
1365 if (msg->list.flags & LIST_CERTS)
1366 {
1367 linked_list_t *pgp_list = create_unique_cert_list(CERT_GPG);
1368
1369 stroke_list_pgp(pgp_list, msg->list.utc, out);
1370 pgp_list->destroy_offset(pgp_list, offsetof(certificate_t, destroy));
1371 }
1372 if (msg->list.flags & (LIST_CERTS | LIST_CACERTS | LIST_OCSPCERTS | LIST_AACERTS))
1373 {
1374 cert_list = create_unique_cert_list(CERT_X509);
1375 }
1376 if (msg->list.flags & LIST_CERTS)
1377 {
1378 stroke_list_certs(cert_list, "X.509 End Entity Certificates",
1379 X509_NONE, msg->list.utc, out);
1380 }
1381 if (msg->list.flags & LIST_CACERTS)
1382 {
1383 stroke_list_certs(cert_list, "X.509 CA Certificates",
1384 X509_CA, msg->list.utc, out);
1385 }
1386 if (msg->list.flags & LIST_OCSPCERTS)
1387 {
1388 stroke_list_certs(cert_list, "X.509 OCSP Signer Certificates",
1389 X509_OCSP_SIGNER, msg->list.utc, out);
1390 }
1391 if (msg->list.flags & LIST_AACERTS)
1392 {
1393 stroke_list_certs(cert_list, "X.509 AA Certificates",
1394 X509_AA, msg->list.utc, out);
1395 }
1396 DESTROY_OFFSET_IF(cert_list, offsetof(certificate_t, destroy));
1397
1398 if (msg->list.flags & LIST_ACERTS)
1399 {
1400 linked_list_t *ac_list = create_unique_cert_list(CERT_X509_AC);
1401
1402 stroke_list_acerts(ac_list, msg->list.utc, out);
1403 ac_list->destroy_offset(ac_list, offsetof(certificate_t, destroy));
1404 }
1405 if (msg->list.flags & LIST_CRLS)
1406 {
1407 linked_list_t *crl_list = create_unique_cert_list(CERT_X509_CRL);
1408
1409 stroke_list_crls(crl_list, msg->list.utc, out);
1410 crl_list->destroy_offset(crl_list, offsetof(certificate_t, destroy));
1411 }
1412 if (msg->list.flags & LIST_OCSP)
1413 {
1414 linked_list_t *ocsp_list = create_unique_cert_list(CERT_X509_OCSP_RESPONSE);
1415
1416 stroke_list_ocsp(ocsp_list, msg->list.utc, out);
1417
1418 ocsp_list->destroy_offset(ocsp_list, offsetof(certificate_t, destroy));
1419 }
1420 if (msg->list.flags & LIST_ALGS)
1421 {
1422 list_algs(out);
1423 }
1424 if (msg->list.flags & LIST_PLUGINS)
1425 {
1426 list_plugins(out);
1427 }
1428 }
1429
1430 /**
1431 * Print leases of a single pool
1432 */
1433 static void pool_leases(private_stroke_list_t *this, FILE *out, char *pool,
1434 host_t *address, u_int size, u_int online, u_int offline)
1435 {
1436 enumerator_t *enumerator;
1437 identification_t *id;
1438 host_t *lease;
1439 bool on;
1440 int found = 0;
1441
1442 fprintf(out, "Leases in pool '%s', usage: %u/%u, %u online\n",
1443 pool, online + offline, size, online);
1444 enumerator = this->attribute->create_lease_enumerator(this->attribute, pool);
1445 while (enumerator && enumerator->enumerate(enumerator, &id, &lease, &on))
1446 {
1447 if (!address || address->ip_equals(address, lease))
1448 {
1449 fprintf(out, " %15H %s '%Y'\n",
1450 lease, on ? "online" : "offline", id);
1451 found++;
1452 }
1453 }
1454 enumerator->destroy(enumerator);
1455 if (!found)
1456 {
1457 fprintf(out, " no matching leases found\n");
1458 }
1459 }
1460
1461 METHOD(stroke_list_t, leases, void,
1462 private_stroke_list_t *this, stroke_msg_t *msg, FILE *out)
1463 {
1464 enumerator_t *enumerator;
1465 u_int size, offline, online;
1466 host_t *address = NULL;
1467 char *pool;
1468 int found = 0;
1469
1470 if (msg->leases.address)
1471 {
1472 address = host_create_from_string(msg->leases.address, 0);
1473 }
1474
1475 enumerator = this->attribute->create_pool_enumerator(this->attribute);
1476 while (enumerator->enumerate(enumerator, &pool, &size, &online, &offline))
1477 {
1478 if (!msg->leases.pool || streq(msg->leases.pool, pool))
1479 {
1480 pool_leases(this, out, pool, address, size, online, offline);
1481 found++;
1482 }
1483 }
1484 enumerator->destroy(enumerator);
1485 if (!found)
1486 {
1487 if (msg->leases.pool)
1488 {
1489 fprintf(out, "pool '%s' not found\n", msg->leases.pool);
1490 }
1491 else
1492 {
1493 fprintf(out, "no pools found\n");
1494 }
1495 }
1496 DESTROY_IF(address);
1497 }
1498
1499 METHOD(stroke_list_t, destroy, void,
1500 private_stroke_list_t *this)
1501 {
1502 free(this);
1503 }
1504
1505 /*
1506 * see header file
1507 */
1508 stroke_list_t *stroke_list_create(stroke_attribute_t *attribute)
1509 {
1510 private_stroke_list_t *this;
1511
1512 INIT(this,
1513 .public = {
1514 .list = _list,
1515 .status = _status,
1516 .leases = _leases,
1517 .destroy = _destroy,
1518 },
1519 .uptime = time_monotonic(NULL),
1520 .swan = "strong",
1521 .attribute = attribute,
1522 );
1523
1524 if (lib->settings->get_bool(lib->settings,
1525 "charon.i_dont_care_about_security_and_use_aggressive_mode_psk", FALSE))
1526 {
1527 this->swan = "weak";
1528 }
1529
1530 return &this->public;
1531 }
1532