diff options
Diffstat (limited to 'src/charon/plugins/stroke/stroke_list.c')
-rw-r--r-- | src/charon/plugins/stroke/stroke_list.c | 293 |
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)); } |