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