2 * Copyright (C) 2008 Martin Willi
3 * Hochschule fuer Technik Rapperswil
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>.
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
16 #include "stroke_list.h"
23 #endif /* HAVE_MALLINFO */
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>
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 */
41 typedef struct private_stroke_list_t private_stroke_list_t
;
44 * private data of stroke_list
46 struct private_stroke_list_t
{
54 * timestamp of daemon start
59 * strokes attribute provider
61 stroke_attribute_t
*attribute
;
65 * Log tasks of a specific queue to out
67 static void log_task_q(FILE *out
, ike_sa_t
*ike_sa
, task_queue_t q
, char *name
)
69 enumerator_t
*enumerator
;
73 enumerator
= ike_sa
->create_task_enumerator(ike_sa
, q
);
74 while (enumerator
->enumerate(enumerator
, &task
))
78 fprintf(out
, "%12s[%d]: Tasks %s: ", ike_sa
->get_name(ike_sa
),
79 ike_sa
->get_unique_id(ike_sa
), name
);
82 fprintf(out
, "%N ", task_type_names
, task
->get_type(task
));
84 enumerator
->destroy(enumerator
);
92 * log an IKE_SA to out
94 static void log_ike_sa(FILE *out
, ike_sa_t
*ike_sa
, bool all
)
96 ike_sa_id_t
*id
= ike_sa
->get_id(ike_sa
);
97 time_t now
= time_monotonic(NULL
);
99 fprintf(out
, "%12s[%d]: %N",
100 ike_sa
->get_name(ike_sa
), ike_sa
->get_unique_id(ike_sa
),
101 ike_sa_state_names
, ike_sa
->get_state(ike_sa
));
103 if (ike_sa
->get_state(ike_sa
) == IKE_ESTABLISHED
)
107 established
= ike_sa
->get_statistic(ike_sa
, STAT_ESTABLISHED
);
108 fprintf(out
, " %V ago", &now
, &established
);
111 fprintf(out
, ", %H[%Y]...%H[%Y]\n",
112 ike_sa
->get_my_host(ike_sa
), ike_sa
->get_my_id(ike_sa
),
113 ike_sa
->get_other_host(ike_sa
), ike_sa
->get_other_id(ike_sa
));
117 proposal_t
*ike_proposal
;
119 ike_proposal
= ike_sa
->get_proposal(ike_sa
);
121 fprintf(out
, "%12s[%d]: IKE SPIs: %.16"PRIx64
"_i%s %.16"PRIx64
"_r%s",
122 ike_sa
->get_name(ike_sa
), ike_sa
->get_unique_id(ike_sa
),
123 id
->get_initiator_spi(id
), id
->is_initiator(id
) ?
"*" : "",
124 id
->get_responder_spi(id
), id
->is_initiator(id
) ?
"" : "*");
127 if (ike_sa
->get_state(ike_sa
) == IKE_ESTABLISHED
)
129 time_t rekey
, reauth
;
130 peer_cfg_t
*peer_cfg
;
132 rekey
= ike_sa
->get_statistic(ike_sa
, STAT_REKEY
);
133 reauth
= ike_sa
->get_statistic(ike_sa
, STAT_REAUTH
);
134 peer_cfg
= ike_sa
->get_peer_cfg(ike_sa
);
138 fprintf(out
, ", rekeying in %V", &rekey
, &now
);
143 enumerator_t
*enumerator
;
147 enumerator
= peer_cfg
->create_auth_cfg_enumerator(peer_cfg
, TRUE
);
148 while (enumerator
->enumerate(enumerator
, &auth
))
155 fprintf(out
, "%N", auth_class_names
,
156 auth
->get(auth
, AUTH_RULE_AUTH_CLASS
));
158 enumerator
->destroy(enumerator
);
159 fprintf(out
, " reauthentication in %V", &reauth
, &now
);
161 if (!rekey
&& !reauth
)
163 fprintf(out
, ", rekeying disabled");
172 snprintf(buf
, BUF_LEN
, "%P", ike_proposal
);
173 fprintf(out
, "%12s[%d]: IKE proposal: %s\n",
174 ike_sa
->get_name(ike_sa
), ike_sa
->get_unique_id(ike_sa
),
178 log_task_q(out
, ike_sa
, TASK_QUEUE_QUEUED
, "queued");
179 log_task_q(out
, ike_sa
, TASK_QUEUE_ACTIVE
, "active");
180 log_task_q(out
, ike_sa
, TASK_QUEUE_PASSIVE
, "passive");
185 * log an CHILD_SA to out
187 static void log_child_sa(FILE *out
, child_sa_t
*child_sa
, bool all
)
189 time_t use_in
, use_out
, rekey
, now
;
190 u_int64_t bytes_in
, bytes_out
;
191 proposal_t
*proposal
;
192 child_cfg_t
*config
= child_sa
->get_config(child_sa
);
195 fprintf(out
, "%12s{%d}: %N, %N%s",
196 child_sa
->get_name(child_sa
), child_sa
->get_reqid(child_sa
),
197 child_sa_state_names
, child_sa
->get_state(child_sa
),
198 ipsec_mode_names
, child_sa
->get_mode(child_sa
),
199 config
->use_proxy_mode(config
) ?
"_PROXY" : "");
201 if (child_sa
->get_state(child_sa
) == CHILD_INSTALLED
)
203 fprintf(out
, ", %N%s SPIs: %.8x_i %.8x_o",
204 protocol_id_names
, child_sa
->get_protocol(child_sa
),
205 child_sa
->has_encap(child_sa
) ?
" in UDP" : "",
206 ntohl(child_sa
->get_spi(child_sa
, TRUE
)),
207 ntohl(child_sa
->get_spi(child_sa
, FALSE
)));
209 if (child_sa
->get_ipcomp(child_sa
) != IPCOMP_NONE
)
211 fprintf(out
, ", IPCOMP CPIs: %.4x_i %.4x_o",
212 ntohs(child_sa
->get_cpi(child_sa
, TRUE
)),
213 ntohs(child_sa
->get_cpi(child_sa
, FALSE
)));
218 fprintf(out
, "\n%12s{%d}: ", child_sa
->get_name(child_sa
),
219 child_sa
->get_reqid(child_sa
));
221 proposal
= child_sa
->get_proposal(child_sa
);
224 u_int16_t encr_alg
= ENCR_UNDEFINED
, int_alg
= AUTH_UNDEFINED
;
225 u_int16_t encr_size
= 0, int_size
= 0;
226 u_int16_t esn
= NO_EXT_SEQ_NUMBERS
;
228 proposal
->get_algorithm(proposal
, ENCRYPTION_ALGORITHM
,
229 &encr_alg
, &encr_size
);
230 proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
,
231 &int_alg
, &int_size
);
232 proposal
->get_algorithm(proposal
, EXTENDED_SEQUENCE_NUMBERS
,
235 if (encr_alg
!= ENCR_UNDEFINED
)
237 fprintf(out
, "%N", encryption_algorithm_names
, encr_alg
);
240 fprintf(out
, "_%u", encr_size
);
243 if (int_alg
!= AUTH_UNDEFINED
)
245 fprintf(out
, "/%N", integrity_algorithm_names
, int_alg
);
248 fprintf(out
, "_%u", int_size
);
251 if (esn
== EXT_SEQ_NUMBERS
)
253 fprintf(out
, "/ESN");
257 now
= time_monotonic(NULL
);
258 child_sa
->get_usestats(child_sa
, TRUE
, &use_in
, &bytes_in
);
259 fprintf(out
, ", %" PRIu64
" bytes_i", bytes_in
);
262 fprintf(out
, " (%" PRIu64
"s ago)", (u_int64_t
)(now
- use_in
));
265 child_sa
->get_usestats(child_sa
, FALSE
, &use_out
, &bytes_out
);
266 fprintf(out
, ", %" PRIu64
" bytes_o", bytes_out
);
269 fprintf(out
, " (%" PRIu64
"s ago)", (u_int64_t
)(now
- use_out
));
271 fprintf(out
, ", rekeying ");
273 rekey
= child_sa
->get_lifetime(child_sa
, FALSE
);
278 fprintf(out
, "active");
282 fprintf(out
, "in %V", &now
, &rekey
);
287 fprintf(out
, "disabled");
293 fprintf(out
, "\n%12s{%d}: %#R=== %#R\n",
294 child_sa
->get_name(child_sa
), child_sa
->get_reqid(child_sa
),
295 child_sa
->get_traffic_selectors(child_sa
, TRUE
),
296 child_sa
->get_traffic_selectors(child_sa
, FALSE
));
300 * Log a configs local or remote authentication config to out
302 static void log_auth_cfgs(FILE *out
, peer_cfg_t
*peer_cfg
, bool local
)
304 enumerator_t
*enumerator
, *rules
;
307 auth_class_t auth_class
;
308 identification_t
*id
;
310 cert_validation_t valid
;
313 name
= peer_cfg
->get_name(peer_cfg
);
315 enumerator
= peer_cfg
->create_auth_cfg_enumerator(peer_cfg
, local
);
316 while (enumerator
->enumerate(enumerator
, &auth
))
318 fprintf(out
, "%12s: %s [%Y] uses ", name
, local ?
"local: " : "remote:",
319 auth
->get(auth
, AUTH_RULE_IDENTITY
));
321 auth_class
= (uintptr_t)auth
->get(auth
, AUTH_RULE_AUTH_CLASS
);
322 if (auth_class
!= AUTH_CLASS_EAP
)
324 fprintf(out
, "%N authentication\n", auth_class_names
, auth_class
);
328 if ((uintptr_t)auth
->get(auth
, AUTH_RULE_EAP_TYPE
) == EAP_NAK
)
330 fprintf(out
, "EAP authentication");
334 if ((uintptr_t)auth
->get(auth
, AUTH_RULE_EAP_VENDOR
))
336 fprintf(out
, "EAP_%" PRIuPTR
"-%" PRIuPTR
" authentication",
337 (uintptr_t)auth
->get(auth
, AUTH_RULE_EAP_TYPE
),
338 (uintptr_t)auth
->get(auth
, AUTH_RULE_EAP_VENDOR
));
342 fprintf(out
, "%N authentication", eap_type_names
,
343 (uintptr_t)auth
->get(auth
, AUTH_RULE_EAP_TYPE
));
346 id
= auth
->get(auth
, AUTH_RULE_EAP_IDENTITY
);
349 fprintf(out
, " with EAP identity '%Y'", id
);
354 cert
= auth
->get(auth
, AUTH_RULE_CA_CERT
);
357 fprintf(out
, "%12s: ca: \"%Y\"\n", name
, cert
->get_subject(cert
));
360 cert
= auth
->get(auth
, AUTH_RULE_IM_CERT
);
363 fprintf(out
, "%12s: im-ca: \"%Y\"\n", name
, cert
->get_subject(cert
));
366 cert
= auth
->get(auth
, AUTH_RULE_SUBJECT_CERT
);
369 fprintf(out
, "%12s: cert: \"%Y\"\n", name
,
370 cert
->get_subject(cert
));
373 valid
= (uintptr_t)auth
->get(auth
, AUTH_RULE_OCSP_VALIDATION
);
374 if (valid
!= VALIDATION_FAILED
)
376 fprintf(out
, "%12s: ocsp: status must be GOOD%s\n", name
,
377 (valid
== VALIDATION_SKIPPED
) ?
" or SKIPPED" : "");
380 valid
= (uintptr_t)auth
->get(auth
, AUTH_RULE_CRL_VALIDATION
);
381 if (valid
!= VALIDATION_FAILED
)
383 fprintf(out
, "%12s: crl: status must be GOOD%s\n", name
,
384 (valid
== VALIDATION_SKIPPED
) ?
" or SKIPPED" : "");
387 rules
= auth
->create_enumerator(auth
);
388 while (rules
->enumerate(rules
, &rule
, &id
))
390 if (rule
== AUTH_RULE_GROUP
)
392 fprintf(out
, "%12s: group: %Y\n", name
, id
);
395 rules
->destroy(rules
);
397 enumerator
->destroy(enumerator
);
400 METHOD(stroke_list_t
, status
, void,
401 private_stroke_list_t
*this, stroke_msg_t
*msg
, FILE *out
,
404 enumerator_t
*enumerator
, *children
;
406 child_cfg_t
*child_cfg
;
407 child_sa_t
*child_sa
;
409 linked_list_t
*my_ts
, *other_ts
;
410 bool first
, found
= FALSE
;
411 char *name
= msg
->status
.name
;
416 peer_cfg_t
*peer_cfg
;
421 u_int size
, online
, offline
, i
;
422 now
= time_monotonic(NULL
);
423 since
= time(NULL
) - (now
- this->uptime
);
425 fprintf(out
, "Status of IKEv2 charon daemon (strongSwan "VERSION
"):\n");
426 fprintf(out
, " uptime: %V, since %T\n", &now
, &this->uptime
, &since
, FALSE
);
429 struct mallinfo mi
= mallinfo();
431 fprintf(out
, " malloc: sbrk %d, mmap %d, used %d, free %d\n",
432 mi
.arena
, mi
.hblkhd
, mi
.uordblks
, mi
.fordblks
);
434 #endif /* HAVE_MALLINFO */
435 fprintf(out
, " worker threads: %d of %d idle, ",
436 lib
->processor
->get_idle_threads(lib
->processor
),
437 lib
->processor
->get_total_threads(lib
->processor
));
438 for (i
= 0; i
< JOB_PRIO_MAX
; i
++)
440 fprintf(out
, "%s%d", i
== 0 ?
"" : "/",
441 lib
->processor
->get_working_threads(lib
->processor
, i
));
443 fprintf(out
, " working, job queue: ");
444 for (i
= 0; i
< JOB_PRIO_MAX
; i
++)
446 fprintf(out
, "%s%d", i
== 0 ?
"" : "/",
447 lib
->processor
->get_job_load(lib
->processor
, i
));
449 fprintf(out
, ", scheduled: %d\n",
450 lib
->scheduler
->get_job_load(lib
->scheduler
));
451 fprintf(out
, " loaded plugins: %s\n",
452 lib
->plugins
->loaded_plugins(lib
->plugins
));
455 enumerator
= this->attribute
->create_pool_enumerator(this->attribute
);
456 while (enumerator
->enumerate(enumerator
, &pool
, &size
, &online
, &offline
))
458 if (name
&& !streq(name
, pool
))
465 fprintf(out
, "Virtual IP pools (size/online/offline):\n");
467 fprintf(out
, " %s: %u/%u/%u\n", pool
, size
, online
, offline
);
469 enumerator
->destroy(enumerator
);
471 enumerator
= hydra
->kernel_interface
->create_address_enumerator(
472 hydra
->kernel_interface
, FALSE
, FALSE
);
473 fprintf(out
, "Listening IP addresses:\n");
474 while (enumerator
->enumerate(enumerator
, (void**)&host
))
476 fprintf(out
, " %H\n", host
);
478 enumerator
->destroy(enumerator
);
480 fprintf(out
, "Connections:\n");
481 enumerator
= charon
->backends
->create_peer_cfg_enumerator(
482 charon
->backends
, NULL
, NULL
, NULL
, NULL
);
483 while (enumerator
->enumerate(enumerator
, &peer_cfg
))
485 if (peer_cfg
->get_ike_version(peer_cfg
) != 2 ||
486 (name
&& !streq(name
, peer_cfg
->get_name(peer_cfg
))))
491 ike_cfg
= peer_cfg
->get_ike_cfg(peer_cfg
);
492 fprintf(out
, "%12s: %s...%s", peer_cfg
->get_name(peer_cfg
),
493 ike_cfg
->get_my_addr(ike_cfg
), ike_cfg
->get_other_addr(ike_cfg
));
495 dpd
= peer_cfg
->get_dpd(peer_cfg
);
498 fprintf(out
, ", dpddelay=%us", dpd
);
502 log_auth_cfgs(out
, peer_cfg
, TRUE
);
503 log_auth_cfgs(out
, peer_cfg
, FALSE
);
505 children
= peer_cfg
->create_child_cfg_enumerator(peer_cfg
);
506 while (children
->enumerate(children
, &child_cfg
))
508 my_ts
= child_cfg
->get_traffic_selectors(child_cfg
, TRUE
, NULL
, NULL
);
509 other_ts
= child_cfg
->get_traffic_selectors(child_cfg
, FALSE
, NULL
, NULL
);
510 fprintf(out
, "%12s: child: %#R=== %#R%N",
511 child_cfg
->get_name(child_cfg
), my_ts
, other_ts
,
512 ipsec_mode_names
, child_cfg
->get_mode(child_cfg
));
513 my_ts
->destroy_offset(my_ts
, offsetof(traffic_selector_t
, destroy
));
514 other_ts
->destroy_offset(other_ts
, offsetof(traffic_selector_t
, destroy
));
518 fprintf(out
, ", dpdaction=%N", action_names
,
519 child_cfg
->get_dpd_action(child_cfg
));
523 children
->destroy(children
);
525 enumerator
->destroy(enumerator
);
528 /* Enumerate shunt policies */
530 enumerator
= charon
->shunts
->create_enumerator(charon
->shunts
);
531 while (enumerator
->enumerate(enumerator
, &child_cfg
))
533 if (name
&& !streq(name
, child_cfg
->get_name(child_cfg
)))
539 fprintf(out
, "Shunted Connections:\n");
542 my_ts
= child_cfg
->get_traffic_selectors(child_cfg
, TRUE
, NULL
, NULL
);
543 other_ts
= child_cfg
->get_traffic_selectors(child_cfg
, FALSE
, NULL
, NULL
);
544 fprintf(out
, "%12s: %#R=== %#R%N\n",
545 child_cfg
->get_name(child_cfg
), my_ts
, other_ts
,
546 ipsec_mode_names
, child_cfg
->get_mode(child_cfg
));
547 my_ts
->destroy_offset(my_ts
, offsetof(traffic_selector_t
, destroy
));
548 other_ts
->destroy_offset(other_ts
, offsetof(traffic_selector_t
, destroy
));
550 enumerator
->destroy(enumerator
);
552 /* Enumerate traps */
554 enumerator
= charon
->traps
->create_enumerator(charon
->traps
);
555 while (enumerator
->enumerate(enumerator
, NULL
, &child_sa
))
557 if (name
&& !streq(name
, child_sa
->get_name(child_sa
)))
563 fprintf(out
, "Routed Connections:\n");
566 log_child_sa(out
, child_sa
, all
);
568 enumerator
->destroy(enumerator
);
570 half_open
= charon
->ike_sa_manager
->get_half_open_count(
571 charon
->ike_sa_manager
, NULL
);
572 fprintf(out
, "Security Associations (%u up, %u connecting):\n",
573 charon
->ike_sa_manager
->get_count(charon
->ike_sa_manager
) - half_open
,
575 enumerator
= charon
->controller
->create_ike_sa_enumerator(
576 charon
->controller
, wait
);
577 while (enumerator
->enumerate(enumerator
, &ike_sa
))
579 bool ike_printed
= FALSE
;
580 enumerator_t
*children
= ike_sa
->create_child_sa_enumerator(ike_sa
);
582 if (name
== NULL
|| streq(name
, ike_sa
->get_name(ike_sa
)))
584 log_ike_sa(out
, ike_sa
, all
);
589 while (children
->enumerate(children
, (void**)&child_sa
))
591 if (name
== NULL
|| streq(name
, child_sa
->get_name(child_sa
)))
595 log_ike_sa(out
, ike_sa
, all
);
599 log_child_sa(out
, child_sa
, all
);
602 children
->destroy(children
);
604 enumerator
->destroy(enumerator
);
610 fprintf(out
, " no match\n");
614 fprintf(out
, " none\n");
620 * create a unique certificate list without duplicates
621 * certicates having the same issuer are grouped together.
623 static linked_list_t
* create_unique_cert_list(certificate_type_t type
)
625 linked_list_t
*list
= linked_list_create();
626 enumerator_t
*enumerator
= lib
->credmgr
->create_cert_enumerator(
627 lib
->credmgr
, type
, KEY_ANY
, NULL
, FALSE
);
630 while (enumerator
->enumerate(enumerator
, (void**)&cert
))
632 enumerator_t
*added
= list
->create_enumerator(list
);
633 identification_t
*issuer
= cert
->get_issuer(cert
);
634 bool previous_same
, same
= FALSE
, found
= FALSE
;
635 certificate_t
*list_cert
;
637 while (added
->enumerate(added
, (void**)&list_cert
))
639 if (list_cert
->equals(list_cert
, cert
))
640 { /* stop if we found a duplicate*/
644 previous_same
= same
;
645 same
= list_cert
->has_issuer(list_cert
, issuer
);
646 if (previous_same
&& !same
)
647 { /* group certificates with same issuer */
653 list
->insert_before(list
, added
, cert
->get_ref(cert
));
655 added
->destroy(added
);
657 enumerator
->destroy(enumerator
);
662 * Print a single public key.
664 static void list_public_key(public_key_t
*public, FILE *out
)
666 private_key_t
*private = NULL
;
668 identification_t
*id
;
671 if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1
, &keyid
))
673 id
= identification_create_from_encoding(ID_KEY_ID
, keyid
);
674 auth
= auth_cfg_create();
675 private = lib
->credmgr
->get_private(lib
->credmgr
,
676 public->get_type(public), id
, auth
);
681 fprintf(out
, " pubkey: %N %d bits%s\n",
682 key_type_names
, public->get_type(public),
683 public->get_keysize(public),
684 private ?
", has private key" : "");
685 if (public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1
, &keyid
))
687 fprintf(out
, " keyid: %#B\n", &keyid
);
689 if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1
, &keyid
))
691 fprintf(out
, " subjkey: %#B\n", &keyid
);
697 * list all raw public keys
699 static void stroke_list_pubkeys(linked_list_t
*list
, bool utc
, FILE *out
)
702 time_t now
= time(NULL
), notBefore
, notAfter
;
703 enumerator_t
*enumerator
;
706 enumerator
= list
->create_enumerator(list
);
707 while (enumerator
->enumerate(enumerator
, (void**)&cert
))
709 identification_t
*subject
= cert
->get_subject(cert
);
710 public_key_t
*public = cert
->get_public_key(cert
);
717 fprintf(out
, "List of Raw Public Keys:\n");
722 /* list subject if available */
723 if (subject
->get_type(subject
) != ID_KEY_ID
)
725 fprintf(out
, " subject: %#Y\n", subject
);
728 /* list validity if available*/
729 cert
->get_validity(cert
, &now
, ¬Before
, ¬After
);
730 if (notBefore
!= UNDEFINED_TIME
&& notAfter
!= UNDEFINED_TIME
)
732 fprintf(out
, " validity: not before %T, ", ¬Before
, utc
);
735 fprintf(out
, "not valid yet (valid in %V)\n", &now
, ¬Before
);
739 fprintf(out
, "ok\n");
741 fprintf(out
, " not after %T, ", ¬After
, utc
);
744 fprintf(out
, "expired (%V ago)\n", &now
, ¬After
);
749 if (now
> notAfter
- CERT_WARNING_INTERVAL
* 60 * 60 * 24)
751 fprintf(out
, " (expires in %V)", &now
, ¬After
);
757 list_public_key(public, out
);
758 public->destroy(public);
761 enumerator
->destroy(enumerator
);
765 * list OpenPGP certificates
767 static void stroke_list_pgp(linked_list_t
*list
,bool utc
, FILE *out
)
770 time_t now
= time(NULL
);
771 enumerator_t
*enumerator
= list
->create_enumerator(list
);
774 while (enumerator
->enumerate(enumerator
, (void**)&cert
))
776 time_t created
, until
;
777 public_key_t
*public;
778 pgp_certificate_t
*pgp_cert
= (pgp_certificate_t
*)cert
;
779 chunk_t fingerprint
= pgp_cert
->get_fingerprint(pgp_cert
);
785 fprintf(out
, "List of PGP End Entity Certificates:\n");
789 fprintf(out
, " userid: '%Y'\n", cert
->get_subject(cert
));
791 fprintf(out
, " digest: %#B\n", &fingerprint
);
794 cert
->get_validity(cert
, &now
, &created
, &until
);
795 fprintf(out
, " created: %T\n", &created
, utc
);
796 fprintf(out
, " until: %T%s\n", &until
, utc
,
797 (until
== TIME_32_BIT_SIGNED_MAX
) ?
" (expires never)":"");
799 public = cert
->get_public_key(cert
);
802 list_public_key(public, out
);
803 public->destroy(public);
806 enumerator
->destroy(enumerator
);
810 * list all X.509 certificates matching the flags
812 static void stroke_list_certs(linked_list_t
*list
, char *label
,
813 x509_flag_t flags
, bool utc
, FILE *out
)
816 time_t now
= time(NULL
);
817 enumerator_t
*enumerator
;
819 x509_flag_t flag_mask
;
821 /* mask all auxiliary flags */
822 flag_mask
= ~(X509_SERVER_AUTH
| X509_CLIENT_AUTH
|
823 X509_SELF_SIGNED
| X509_IP_ADDR_BLOCKS
);
825 enumerator
= list
->create_enumerator(list
);
826 while (enumerator
->enumerate(enumerator
, (void**)&cert
))
828 x509_t
*x509
= (x509_t
*)cert
;
829 x509_flag_t x509_flags
= x509
->get_flags(x509
) & flag_mask
;
831 /* list only if flag is set or flag == 0 */
832 if ((x509_flags
& flags
) || (x509_flags
== flags
))
834 enumerator_t
*enumerator
;
835 identification_t
*altName
;
836 bool first_altName
= TRUE
;
838 chunk_t serial
, authkey
;
839 time_t notBefore
, notAfter
;
840 public_key_t
*public;
845 fprintf(out
, "List of %s:\n", label
);
850 /* list subjectAltNames */
851 enumerator
= x509
->create_subjectAltName_enumerator(x509
);
852 while (enumerator
->enumerate(enumerator
, (void**)&altName
))
856 fprintf(out
, " altNames: ");
857 first_altName
= FALSE
;
863 fprintf(out
, "%Y", altName
);
869 enumerator
->destroy(enumerator
);
871 fprintf(out
, " subject: \"%Y\"\n", cert
->get_subject(cert
));
872 fprintf(out
, " issuer: \"%Y\"\n", cert
->get_issuer(cert
));
873 serial
= chunk_skip_zero(x509
->get_serial(x509
));
874 fprintf(out
, " serial: %#B\n", &serial
);
877 cert
->get_validity(cert
, &now
, ¬Before
, ¬After
);
878 fprintf(out
, " validity: not before %T, ", ¬Before
, utc
);
881 fprintf(out
, "not valid yet (valid in %V)\n", &now
, ¬Before
);
885 fprintf(out
, "ok\n");
887 fprintf(out
, " not after %T, ", ¬After
, utc
);
890 fprintf(out
, "expired (%V ago)\n", &now
, ¬After
);
895 if (now
> notAfter
- CERT_WARNING_INTERVAL
* 60 * 60 * 24)
897 fprintf(out
, " (expires in %V)", &now
, ¬After
);
902 public = cert
->get_public_key(cert
);
905 list_public_key(public, out
);
906 public->destroy(public);
909 /* list optional authorityKeyIdentifier */
910 authkey
= x509
->get_authKeyIdentifier(x509
);
913 fprintf(out
, " authkey: %#B\n", &authkey
);
916 /* list optional pathLenConstraint */
917 pathlen
= x509
->get_constraint(x509
, X509_PATH_LEN
);
918 if (pathlen
!= X509_NO_CONSTRAINT
)
920 fprintf(out
, " pathlen: %u\n", pathlen
);
923 /* list optional ipAddrBlocks */
924 if (x509
->get_flags(x509
) & X509_IP_ADDR_BLOCKS
)
926 traffic_selector_t
*ipAddrBlock
;
927 bool first_ipAddrBlock
= TRUE
;
929 fprintf(out
, " addresses: ");
930 enumerator
= x509
->create_ipAddrBlock_enumerator(x509
);
931 while (enumerator
->enumerate(enumerator
, &ipAddrBlock
))
933 if (first_ipAddrBlock
)
935 first_ipAddrBlock
= FALSE
;
941 fprintf(out
, "%R", ipAddrBlock
);
943 enumerator
->destroy(enumerator
);
948 enumerator
->destroy(enumerator
);
952 * list all X.509 attribute certificates
954 static void stroke_list_acerts(linked_list_t
*list
, bool utc
, FILE *out
)
957 time_t thisUpdate
, nextUpdate
, now
= time(NULL
);
958 enumerator_t
*enumerator
= list
->create_enumerator(list
);
961 while (enumerator
->enumerate(enumerator
, (void**)&cert
))
963 ac_t
*ac
= (ac_t
*)cert
;
964 identification_t
*id
;
965 ietf_attributes_t
*groups
;
971 fprintf(out
, "List of X.509 Attribute Certificates:\n");
976 id
= cert
->get_subject(cert
);
979 fprintf(out
, " holder: \"%Y\"\n", id
);
981 id
= ac
->get_holderIssuer(ac
);
984 fprintf(out
, " hissuer: \"%Y\"\n", id
);
986 chunk
= chunk_skip_zero(ac
->get_holderSerial(ac
));
989 fprintf(out
, " hserial: %#B\n", &chunk
);
991 groups
= ac
->get_groups(ac
);
994 fprintf(out
, " groups: %s\n", groups
->get_string(groups
));
995 groups
->destroy(groups
);
997 fprintf(out
, " issuer: \"%Y\"\n", cert
->get_issuer(cert
));
998 chunk
= chunk_skip_zero(ac
->get_serial(ac
));
999 fprintf(out
, " serial: %#B\n", &chunk
);
1002 cert
->get_validity(cert
, &now
, &thisUpdate
, &nextUpdate
);
1003 fprintf(out
, " updates: this %T\n", &thisUpdate
, utc
);
1004 fprintf(out
, " next %T, ", &nextUpdate
, utc
);
1005 if (now
> nextUpdate
)
1007 fprintf(out
, "expired (%V ago)\n", &now
, &nextUpdate
);
1012 if (now
> nextUpdate
- AC_WARNING_INTERVAL
* 60 * 60 * 24)
1014 fprintf(out
, " (expires in %V)", &now
, &nextUpdate
);
1016 fprintf(out
, " \n");
1019 /* list optional authorityKeyIdentifier */
1020 chunk
= ac
->get_authKeyIdentifier(ac
);
1023 fprintf(out
, " authkey: %#B\n", &chunk
);
1026 enumerator
->destroy(enumerator
);
1030 * list all X.509 CRLs
1032 static void stroke_list_crls(linked_list_t
*list
, bool utc
, FILE *out
)
1035 time_t thisUpdate
, nextUpdate
, now
= time(NULL
);
1036 enumerator_t
*enumerator
= list
->create_enumerator(list
);
1037 certificate_t
*cert
;
1039 while (enumerator
->enumerate(enumerator
, (void**)&cert
))
1041 crl_t
*crl
= (crl_t
*)cert
;
1047 fprintf(out
, "List of X.509 CRLs:\n");
1052 fprintf(out
, " issuer: \"%Y\"\n", cert
->get_issuer(cert
));
1054 /* list optional crlNumber */
1055 chunk
= chunk_skip_zero(crl
->get_serial(crl
));
1058 fprintf(out
, " serial: %#B\n", &chunk
);
1060 if (crl
->is_delta_crl(crl
, &chunk
))
1062 chunk
= chunk_skip_zero(chunk
);
1063 fprintf(out
, " delta for: %#B\n", &chunk
);
1066 /* count the number of revoked certificates */
1069 enumerator_t
*enumerator
= crl
->create_enumerator(crl
);
1071 while (enumerator
->enumerate(enumerator
, NULL
, NULL
, NULL
))
1075 fprintf(out
, " revoked: %d certificate%s\n", count
,
1076 (count
== 1)?
"" : "s");
1077 enumerator
->destroy(enumerator
);
1081 cert
->get_validity(cert
, &now
, &thisUpdate
, &nextUpdate
);
1082 fprintf(out
, " updates: this %T\n", &thisUpdate
, utc
);
1083 fprintf(out
, " next %T, ", &nextUpdate
, utc
);
1084 if (now
> nextUpdate
)
1086 fprintf(out
, "expired (%V ago)\n", &now
, &nextUpdate
);
1091 if (now
> nextUpdate
- CRL_WARNING_INTERVAL
* 60 * 60 * 24)
1093 fprintf(out
, " (expires in %V)", &now
, &nextUpdate
);
1095 fprintf(out
, " \n");
1098 /* list optional authorityKeyIdentifier */
1099 chunk
= crl
->get_authKeyIdentifier(crl
);
1102 fprintf(out
, " authkey: %#B\n", &chunk
);
1105 enumerator
->destroy(enumerator
);
1109 * list all OCSP responses
1111 static void stroke_list_ocsp(linked_list_t
* list
, bool utc
, FILE *out
)
1113 bool first
= TRUE
, ok
;
1114 enumerator_t
*enumerator
= list
->create_enumerator(list
);
1115 certificate_t
*cert
;
1116 time_t produced
, usable
, now
= time(NULL
);
1118 while (enumerator
->enumerate(enumerator
, (void**)&cert
))
1123 fprintf(out
, "List of OCSP responses:\n");
1127 fprintf(out
, " signer: \"%Y\"\n", cert
->get_issuer(cert
));
1129 /* check validity */
1130 ok
= cert
->get_validity(cert
, &now
, &produced
, &usable
);
1131 fprintf(out
, " validity: produced at %T\n", &produced
, utc
);
1132 fprintf(out
, " usable till %T, ", &usable
, utc
);
1135 fprintf(out
, "ok\n");
1139 fprintf(out
, "expired (%V ago)\n", &now
, &usable
);
1142 enumerator
->destroy(enumerator
);
1146 * Print the name of an algorithm plus the name of the plugin that registered it
1148 static void print_alg(FILE *out
, int *len
, enum_name_t
*alg_names
, int alg_type
,
1149 const char *plugin_name
)
1151 char alg_name
[BUF_LEN
];
1154 alg_name_len
= sprintf(alg_name
, " %N[%s]", alg_names
, alg_type
, plugin_name
);
1155 if (*len
+ alg_name_len
> CRYPTO_MAX_ALG_LINE
)
1157 fprintf(out
, "\n ");
1160 fprintf(out
, "%s", alg_name
);
1161 *len
+= alg_name_len
;
1165 * List of registered cryptographical algorithms
1167 static void list_algs(FILE *out
)
1169 enumerator_t
*enumerator
;
1170 encryption_algorithm_t encryption
;
1171 integrity_algorithm_t integrity
;
1172 hash_algorithm_t hash
;
1173 pseudo_random_function_t prf
;
1174 diffie_hellman_group_t group
;
1175 rng_quality_t quality
;
1176 const char *plugin_name
;
1180 fprintf(out
, "List of registered IKEv2 Algorithms:\n");
1181 fprintf(out
, "\n encryption:");
1183 enumerator
= lib
->crypto
->create_crypter_enumerator(lib
->crypto
);
1184 while (enumerator
->enumerate(enumerator
, &encryption
, &plugin_name
))
1186 print_alg(out
, &len
, encryption_algorithm_names
, encryption
, plugin_name
);
1188 enumerator
->destroy(enumerator
);
1189 fprintf(out
, "\n integrity: ");
1191 enumerator
= lib
->crypto
->create_signer_enumerator(lib
->crypto
);
1192 while (enumerator
->enumerate(enumerator
, &integrity
, &plugin_name
))
1194 print_alg(out
, &len
, integrity_algorithm_names
, integrity
, plugin_name
);
1196 enumerator
->destroy(enumerator
);
1197 fprintf(out
, "\n aead: ");
1199 enumerator
= lib
->crypto
->create_aead_enumerator(lib
->crypto
);
1200 while (enumerator
->enumerate(enumerator
, &encryption
, &plugin_name
))
1202 print_alg(out
, &len
, encryption_algorithm_names
, encryption
, plugin_name
);
1204 enumerator
->destroy(enumerator
);
1205 fprintf(out
, "\n hasher: ");
1207 enumerator
= lib
->crypto
->create_hasher_enumerator(lib
->crypto
);
1208 while (enumerator
->enumerate(enumerator
, &hash
, &plugin_name
))
1210 print_alg(out
, &len
, hash_algorithm_names
, hash
, plugin_name
);
1212 enumerator
->destroy(enumerator
);
1213 fprintf(out
, "\n prf: ");
1215 enumerator
= lib
->crypto
->create_prf_enumerator(lib
->crypto
);
1216 while (enumerator
->enumerate(enumerator
, &prf
, &plugin_name
))
1218 print_alg(out
, &len
, pseudo_random_function_names
, prf
, plugin_name
);
1220 enumerator
->destroy(enumerator
);
1221 fprintf(out
, "\n dh-group: ");
1223 enumerator
= lib
->crypto
->create_dh_enumerator(lib
->crypto
);
1224 while (enumerator
->enumerate(enumerator
, &group
, &plugin_name
))
1226 print_alg(out
, &len
, diffie_hellman_group_names
, group
, plugin_name
);
1228 enumerator
->destroy(enumerator
);
1229 fprintf(out
, "\n random-gen:");
1231 enumerator
= lib
->crypto
->create_rng_enumerator(lib
->crypto
);
1232 while (enumerator
->enumerate(enumerator
, &quality
, &plugin_name
))
1234 print_alg(out
, &len
, rng_quality_names
, quality
, plugin_name
);
1236 enumerator
->destroy(enumerator
);
1241 * List loaded plugin information
1243 static void list_plugins(FILE *out
)
1245 plugin_feature_t
*features
, *fp
;
1246 enumerator_t
*enumerator
;
1247 linked_list_t
*list
;
1254 fprintf(out
, "List of loaded Plugins:\n");
1257 enumerator
= lib
->plugins
->create_plugin_enumerator(lib
->plugins
);
1258 while (enumerator
->enumerate(enumerator
, &plugin
, &list
))
1260 fprintf(out
, "%s:\n", plugin
->get_name(plugin
));
1261 if (plugin
->get_features
)
1263 count
= plugin
->get_features(plugin
, &features
);
1264 for (i
= 0; i
< count
; i
++)
1266 str
= plugin_feature_get_string(&features
[i
]);
1267 switch (features
[i
].kind
)
1269 case FEATURE_PROVIDE
:
1271 loaded
= list
->find_first(list
, NULL
,
1272 (void**)&fp
) == SUCCESS
;
1273 fprintf(out
, " %s%s\n",
1274 str
, loaded ?
"" : " (not loaded)");
1276 case FEATURE_DEPENDS
:
1277 fprintf(out
, " %s\n", str
);
1279 case FEATURE_SDEPEND
:
1280 fprintf(out
, " %s(soft)\n", str
);
1289 enumerator
->destroy(enumerator
);
1292 METHOD(stroke_list_t
, list
, void,
1293 private_stroke_list_t
*this, stroke_msg_t
*msg
, FILE *out
)
1295 linked_list_t
*cert_list
= NULL
;
1297 if (msg
->list
.flags
& LIST_PUBKEYS
)
1299 linked_list_t
*pubkey_list
= create_unique_cert_list(CERT_TRUSTED_PUBKEY
);
1301 stroke_list_pubkeys(pubkey_list
, msg
->list
.utc
, out
);
1302 pubkey_list
->destroy_offset(pubkey_list
, offsetof(certificate_t
, destroy
));
1304 if (msg
->list
.flags
& LIST_CERTS
)
1306 linked_list_t
*pgp_list
= create_unique_cert_list(CERT_GPG
);
1308 stroke_list_pgp(pgp_list
, msg
->list
.utc
, out
);
1309 pgp_list
->destroy_offset(pgp_list
, offsetof(certificate_t
, destroy
));
1311 if (msg
->list
.flags
& (LIST_CERTS
| LIST_CACERTS
| LIST_OCSPCERTS
| LIST_AACERTS
))
1313 cert_list
= create_unique_cert_list(CERT_X509
);
1315 if (msg
->list
.flags
& LIST_CERTS
)
1317 stroke_list_certs(cert_list
, "X.509 End Entity Certificates",
1318 X509_NONE
, msg
->list
.utc
, out
);
1320 if (msg
->list
.flags
& LIST_CACERTS
)
1322 stroke_list_certs(cert_list
, "X.509 CA Certificates",
1323 X509_CA
, msg
->list
.utc
, out
);
1325 if (msg
->list
.flags
& LIST_OCSPCERTS
)
1327 stroke_list_certs(cert_list
, "X.509 OCSP Signer Certificates",
1328 X509_OCSP_SIGNER
, msg
->list
.utc
, out
);
1330 if (msg
->list
.flags
& LIST_AACERTS
)
1332 stroke_list_certs(cert_list
, "X.509 AA Certificates",
1333 X509_AA
, msg
->list
.utc
, out
);
1335 DESTROY_OFFSET_IF(cert_list
, offsetof(certificate_t
, destroy
));
1337 if (msg
->list
.flags
& LIST_ACERTS
)
1339 linked_list_t
*ac_list
= create_unique_cert_list(CERT_X509_AC
);
1341 stroke_list_acerts(ac_list
, msg
->list
.utc
, out
);
1342 ac_list
->destroy_offset(ac_list
, offsetof(certificate_t
, destroy
));
1344 if (msg
->list
.flags
& LIST_CRLS
)
1346 linked_list_t
*crl_list
= create_unique_cert_list(CERT_X509_CRL
);
1348 stroke_list_crls(crl_list
, msg
->list
.utc
, out
);
1349 crl_list
->destroy_offset(crl_list
, offsetof(certificate_t
, destroy
));
1351 if (msg
->list
.flags
& LIST_OCSP
)
1353 linked_list_t
*ocsp_list
= create_unique_cert_list(CERT_X509_OCSP_RESPONSE
);
1355 stroke_list_ocsp(ocsp_list
, msg
->list
.utc
, out
);
1357 ocsp_list
->destroy_offset(ocsp_list
, offsetof(certificate_t
, destroy
));
1359 if (msg
->list
.flags
& LIST_ALGS
)
1363 if (msg
->list
.flags
& LIST_PLUGINS
)
1370 * Print leases of a single pool
1372 static void pool_leases(private_stroke_list_t
*this, FILE *out
, char *pool
,
1373 host_t
*address
, u_int size
, u_int online
, u_int offline
)
1375 enumerator_t
*enumerator
;
1376 identification_t
*id
;
1381 fprintf(out
, "Leases in pool '%s', usage: %u/%u, %u online\n",
1382 pool
, online
+ offline
, size
, online
);
1383 enumerator
= this->attribute
->create_lease_enumerator(this->attribute
, pool
);
1384 while (enumerator
&& enumerator
->enumerate(enumerator
, &id
, &lease
, &on
))
1386 if (!address
|| address
->ip_equals(address
, lease
))
1388 fprintf(out
, " %15H %s '%Y'\n",
1389 lease
, on ?
"online" : "offline", id
);
1393 enumerator
->destroy(enumerator
);
1396 fprintf(out
, " no matching leases found\n");
1400 METHOD(stroke_list_t
, leases
, void,
1401 private_stroke_list_t
*this, stroke_msg_t
*msg
, FILE *out
)
1403 enumerator_t
*enumerator
;
1404 u_int size
, offline
, online
;
1405 host_t
*address
= NULL
;
1409 if (msg
->leases
.address
)
1411 address
= host_create_from_string(msg
->leases
.address
, 0);
1414 enumerator
= this->attribute
->create_pool_enumerator(this->attribute
);
1415 while (enumerator
->enumerate(enumerator
, &pool
, &size
, &online
, &offline
))
1417 if (!msg
->leases
.pool
|| streq(msg
->leases
.pool
, pool
))
1419 pool_leases(this, out
, pool
, address
, size
, online
, offline
);
1423 enumerator
->destroy(enumerator
);
1426 if (msg
->leases
.pool
)
1428 fprintf(out
, "pool '%s' not found\n", msg
->leases
.pool
);
1432 fprintf(out
, "no pools found\n");
1435 DESTROY_IF(address
);
1438 METHOD(stroke_list_t
, destroy
, void,
1439 private_stroke_list_t
*this)
1447 stroke_list_t
*stroke_list_create(stroke_attribute_t
*attribute
)
1449 private_stroke_list_t
*this;
1457 .destroy
= _destroy
,
1459 .uptime
= time_monotonic(NULL
),
1460 .attribute
= attribute
,
1463 return &this->public;