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