summaryrefslogtreecommitdiff
path: root/src/charon/plugins/stroke/stroke_list.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/plugins/stroke/stroke_list.c')
-rw-r--r--src/charon/plugins/stroke/stroke_list.c293
1 files changed, 273 insertions, 20 deletions
diff --git a/src/charon/plugins/stroke/stroke_list.c b/src/charon/plugins/stroke/stroke_list.c
index 44699ba0a..d531dca47 100644
--- a/src/charon/plugins/stroke/stroke_list.c
+++ b/src/charon/plugins/stroke/stroke_list.c
@@ -22,6 +22,7 @@
#include <credentials/certificates/x509.h>
#include <credentials/certificates/ac.h>
#include <credentials/certificates/crl.h>
+#include <config/peer_cfg.h>
/* warning intervals for list functions */
#define CERT_WARNING_INTERVAL 30 /* days */
@@ -47,6 +48,23 @@ struct private_stroke_list_t {
};
/**
+ * get the authentication class of a config
+ */
+auth_class_t get_auth_class(peer_cfg_t *config)
+{
+ auth_class_t *class;
+ auth_info_t *auth_info;
+
+ auth_info = config->get_auth(config);
+ if (auth_info->get_item(auth_info, AUTHN_AUTH_CLASS, (void**)&class))
+ {
+ return *class;
+ }
+ /* fallback to pubkey authentication */
+ return AUTH_CLASS_PUBKEY;
+}
+
+/**
* log an IKE_SA to out
*/
static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
@@ -80,7 +98,8 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
}
if (reauth)
{
- fprintf(out, ", reauthentication in %V", &reauth);
+ fprintf(out, ", %N reauthentication in %V", auth_class_names,
+ get_auth_class(ike_sa->get_peer_cfg(ike_sa)), &reauth);
}
if (!rekey && !reauth)
{
@@ -108,7 +127,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
encryption_algorithm_t encr_alg;
integrity_algorithm_t int_alg;
size_t encr_len, int_len;
- mode_t mode;
+ ipsec_mode_t mode;
child_sa->get_stats(child_sa, &mode, &encr_alg, &encr_len,
&int_alg, &int_len, &rekey, &use_in, &use_out,
@@ -117,15 +136,25 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
fprintf(out, "%12s{%d}: %N, %N",
child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
child_sa_state_names, child_sa->get_state(child_sa),
- mode_names, mode);
+ ipsec_mode_names, mode);
if (child_sa->get_state(child_sa) == CHILD_INSTALLED)
{
+ u_int16_t my_cpi = child_sa->get_cpi(child_sa, TRUE);
+ u_int16_t other_cpi = child_sa->get_cpi(child_sa, FALSE);
+
fprintf(out, ", %N SPIs: %.8x_i %.8x_o",
protocol_id_names, child_sa->get_protocol(child_sa),
- htonl(child_sa->get_spi(child_sa, TRUE)),
- htonl(child_sa->get_spi(child_sa, FALSE)));
-
+ ntohl(child_sa->get_spi(child_sa, TRUE)),
+ ntohl(child_sa->get_spi(child_sa, FALSE)));
+
+ /* Is IPCOMP activated ? */
+ if (my_cpi && other_cpi)
+ {
+ fprintf(out, ", IPCOMP CPIs: %.4x_i %.4x_o",
+ ntohs(my_cpi), ntohs(other_cpi));
+ }
+
if (all)
{
fprintf(out, "\n%12s{%d}: ", child_sa->get_name(child_sa),
@@ -198,21 +227,20 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bool all)
{
enumerator_t *enumerator, *children;
- iterator_t *iterator;
- host_t *host;
- peer_cfg_t *peer_cfg;
ike_cfg_t *ike_cfg;
child_cfg_t *child_cfg;
ike_sa_t *ike_sa;
- char *name = NULL, *plugin;
bool found = FALSE;
- time_t uptime;
-
- name = msg->status.name;
+ char *name = msg->status.name;
if (all)
{
- uptime = time(NULL) - this->uptime;
+ peer_cfg_t *peer_cfg;
+ char *plugin;
+ host_t *host;
+ u_int32_t dpd;
+ time_t uptime = time(NULL) - this->uptime;
+
fprintf(out, "Performance:\n");
fprintf(out, " uptime: %V, since %#T\n", &uptime, &this->uptime, FALSE);
fprintf(out, " worker threads: %d idle of %d,",
@@ -231,40 +259,154 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
enumerator->destroy(enumerator);
fprintf(out, "\n");
- iterator = charon->kernel_interface->create_address_iterator(
- charon->kernel_interface);
+ enumerator = charon->kernel_interface->create_address_enumerator(
+ charon->kernel_interface, FALSE, FALSE);
fprintf(out, "Listening IP addresses:\n");
- while (iterator->iterate(iterator, (void**)&host))
+ while (enumerator->enumerate(enumerator, (void**)&host))
{
fprintf(out, " %H\n", host);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
fprintf(out, "Connections:\n");
enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends);
while (enumerator->enumerate(enumerator, (void**)&peer_cfg))
{
+ void *ptr;
+ certificate_t *cert;
+ auth_item_t item;
+ auth_info_t *auth;
+ enumerator_t *auth_enumerator;
+ identification_t *my_ca = NULL, *other_ca = NULL;
+ identification_t *eap_identity = NULL;
+ u_int32_t *eap_type = NULL;
+ bool ac_groups = FALSE;
+
if (peer_cfg->get_ike_version(peer_cfg) != 2 ||
(name && !streq(name, peer_cfg->get_name(peer_cfg))))
{
continue;
}
+ /* determine any required CAs, EAP type, EAP identity,
+ * and the presence of AC groups
+ */
+ auth = peer_cfg->get_auth(peer_cfg);
+ auth_enumerator = auth->create_item_enumerator(auth);
+ while (auth_enumerator->enumerate(auth_enumerator, &item, &ptr))
+ {
+ switch (item)
+ {
+ case AUTHN_EAP_TYPE:
+ eap_type = (u_int32_t *)ptr;
+ break;
+ case AUTHN_EAP_IDENTITY:
+ eap_identity = (identification_t *)ptr;
+ break;
+ case AUTHN_CA_CERT:
+ cert = (certificate_t *)ptr;
+ my_ca = cert->get_subject(cert);
+ break;
+ case AUTHN_CA_CERT_NAME:
+ my_ca = (identification_t *)ptr;
+ break;
+ case AUTHZ_CA_CERT:
+ cert = (certificate_t *)ptr;
+ other_ca = cert->get_subject(cert);
+ break;
+ case AUTHZ_CA_CERT_NAME:
+ other_ca = (identification_t *)ptr;
+ break;
+ case AUTHZ_AC_GROUP:
+ ac_groups = TRUE;
+ break;
+ default:
+ break;
+ }
+ }
+ auth_enumerator->destroy(auth_enumerator);
+
ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
fprintf(out, "%12s: %s[%D]...%s[%D]\n", peer_cfg->get_name(peer_cfg),
ike_cfg->get_my_addr(ike_cfg), peer_cfg->get_my_id(peer_cfg),
ike_cfg->get_other_addr(ike_cfg), peer_cfg->get_other_id(peer_cfg));
- /* TODO: list CAs and groups */
+ if (my_ca || other_ca)
+ {
+ fprintf(out, "%12s: CAs: ", peer_cfg->get_name(peer_cfg));
+ if (my_ca)
+ {
+ fprintf(out, "\"%D\"...", my_ca);
+ }
+ else
+ {
+ fprintf(out, "%%any...");
+ }
+ if (other_ca)
+ {
+ fprintf(out, "\"%D\"\n", other_ca);
+ }
+ else
+ {
+ fprintf(out, "%%any\n");
+ }
+ }
+
+ if (ac_groups)
+ {
+ bool first = TRUE;
+
+ fprintf(out, "%12s: groups: ", peer_cfg->get_name(peer_cfg));
+ auth_enumerator = auth->create_item_enumerator(auth);
+ while (auth_enumerator->enumerate(auth_enumerator, &item, &ptr))
+ {
+ if (item == AUTHZ_AC_GROUP)
+ {
+ identification_t *group = (identification_t *)ptr;
+
+ fprintf(out, "%s%D", first? "":", ", group);
+ first = FALSE;
+ }
+ }
+ auth_enumerator->destroy(auth_enumerator);
+ fprintf(out, "\n");
+ }
+
+ fprintf(out, "%12s: %N ", peer_cfg->get_name(peer_cfg),
+ auth_class_names, get_auth_class(peer_cfg));
+ if (eap_type)
+ {
+ fprintf(out, "and %N ", eap_type_names, *eap_type);
+ }
+ fprintf(out, "authentication");
+ if (eap_identity)
+ {
+ fprintf(out, ", EAP identity: '%D'", eap_identity);
+ }
+ dpd = peer_cfg->get_dpd(peer_cfg);
+ if (dpd)
+ {
+ fprintf(out, ", dpddelay=%us", dpd);
+ }
+ fprintf(out, "\n");
+
children = peer_cfg->create_child_cfg_enumerator(peer_cfg);
while (children->enumerate(children, &child_cfg))
{
linked_list_t *my_ts, *other_ts;
+
my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL);
other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL);
- fprintf(out, "%12s: %#R=== %#R\n", child_cfg->get_name(child_cfg),
+ fprintf(out, "%12s: %#R=== %#R", child_cfg->get_name(child_cfg),
my_ts, other_ts);
my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
+
+ if (dpd)
+ {
+ fprintf(out, ", dpdaction=%N", action_names,
+ child_cfg->get_dpd_action(child_cfg));
+ }
+ fprintf(out, "\n");
}
children->destroy(children);
}
@@ -365,6 +507,53 @@ static linked_list_t* create_unique_cert_list(certificate_type_t type)
}
/**
+ * list all raw public keys
+ */
+static void stroke_list_pubkeys(linked_list_t *list, bool utc, FILE *out)
+{
+ bool first = TRUE;
+
+ enumerator_t *enumerator = list->create_enumerator(list);
+ certificate_t *cert;
+
+ while (enumerator->enumerate(enumerator, (void**)&cert))
+ {
+ public_key_t *public = cert->get_public_key(cert);
+
+ if (public)
+ {
+ private_key_t *private = NULL;
+ identification_t *id, *keyid;
+
+ if (first)
+ {
+ fprintf(out, "\n");
+ fprintf(out, "List of Raw Public Keys:\n");
+ first = FALSE;
+ }
+ fprintf(out, "\n");
+
+ /* list public key information */
+ id = public->get_id(public, ID_PUBKEY_SHA1);
+ keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
+
+ private = charon->credentials->get_private(
+ charon->credentials,
+ public->get_type(public), keyid, NULL);
+ fprintf(out, " pubkey: %N %d bits%s\n",
+ key_type_names, public->get_type(public),
+ public->get_keysize(public) * 8,
+ private ? ", has private key" : "");
+ fprintf(out, " keyid: %D\n", keyid);
+ fprintf(out, " subjkey: %D\n", id);
+ DESTROY_IF(private);
+ public->destroy(public);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
* list all X.509 certificates matching the flags
*/
static void stroke_list_certs(linked_list_t *list, char *label,
@@ -649,12 +838,71 @@ static void stroke_list_ocsp(linked_list_t* list, bool utc, FILE *out)
}
/**
+ * List of registered cryptographical algorithms
+ */
+static void list_algs(FILE *out)
+{
+ enumerator_t *enumerator;
+ encryption_algorithm_t encryption;
+ integrity_algorithm_t integrity;
+ hash_algorithm_t hash;
+ pseudo_random_function_t prf;
+ diffie_hellman_group_t group;
+
+ fprintf(out, "\n");
+ fprintf(out, "List of registered IKEv2 Algorithms:\n");
+ fprintf(out, "\n encryption: ");
+ enumerator = lib->crypto->create_crypter_enumerator(lib->crypto);
+ while (enumerator->enumerate(enumerator, &encryption))
+ {
+ fprintf(out, "%N ", encryption_algorithm_names, encryption);
+ }
+ enumerator->destroy(enumerator);
+ fprintf(out, "\n integrity: ");
+ enumerator = lib->crypto->create_signer_enumerator(lib->crypto);
+ while (enumerator->enumerate(enumerator, &integrity))
+ {
+ fprintf(out, "%N ", integrity_algorithm_names, integrity);
+ }
+ enumerator->destroy(enumerator);
+ fprintf(out, "\n hasher: ");
+ enumerator = lib->crypto->create_hasher_enumerator(lib->crypto);
+ while (enumerator->enumerate(enumerator, &hash))
+ {
+ fprintf(out, "%N ", hash_algorithm_names, hash);
+ }
+ enumerator->destroy(enumerator);
+ fprintf(out, "\n prf: ");
+ enumerator = lib->crypto->create_prf_enumerator(lib->crypto);
+ while (enumerator->enumerate(enumerator, &prf))
+ {
+ fprintf(out, "%N ", pseudo_random_function_names, prf);
+ }
+ enumerator->destroy(enumerator);
+ fprintf(out, "\n dh-group: ");
+ enumerator = lib->crypto->create_dh_enumerator(lib->crypto);
+ while (enumerator->enumerate(enumerator, &group))
+ {
+ fprintf(out, "%N ", diffie_hellman_group_names, group);
+ }
+ enumerator->destroy(enumerator);
+ fprintf(out, "\n");
+}
+
+/**
* Implementation of stroke_list_t.list.
*/
static void list(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out)
{
linked_list_t *cert_list = NULL;
+ if (msg->list.flags & LIST_PUBKEYS)
+ {
+ linked_list_t *pubkey_list = create_unique_cert_list(CERT_TRUSTED_PUBKEY);
+
+ stroke_list_pubkeys(pubkey_list, msg->list.utc, out);
+ pubkey_list->destroy_offset(pubkey_list, offsetof(certificate_t, destroy));
+ }
if (msg->list.flags & (LIST_CERTS | LIST_CACERTS | LIST_OCSPCERTS | LIST_AACERTS))
{
cert_list = create_unique_cert_list(CERT_X509);
@@ -698,8 +946,13 @@ static void list(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out)
linked_list_t *ocsp_list = create_unique_cert_list(CERT_X509_OCSP_RESPONSE);
stroke_list_ocsp(ocsp_list, msg->list.utc, out);
+
ocsp_list->destroy_offset(ocsp_list, offsetof(certificate_t, destroy));
}
+ if (msg->list.flags & LIST_ALGS)
+ {
+ list_algs(out);
+ }
DESTROY_OFFSET_IF(cert_list, offsetof(certificate_t, destroy));
}