diff --git a/src/libcharon/config/child_cfg.c b/src/libcharon/config/child_cfg.c index 3e18a4af2..e1e2778a7 100644 --- a/src/libcharon/config/child_cfg.c +++ b/src/libcharon/config/child_cfg.c @@ -216,7 +216,7 @@ CALLBACK(match_proposal, bool, } METHOD(child_cfg_t, get_proposals, linked_list_t*, - private_child_cfg_t *this, bool strip_ke) + private_child_cfg_t *this, bool strip_ke, bool log) { enumerator_t *enumerator; proposal_t *current; @@ -241,8 +241,10 @@ METHOD(child_cfg_t, get_proposals, linked_list_t*, } enumerator->destroy(enumerator); - DBG2(DBG_CFG, "configured proposals: %#P", proposals); - + if (log) + { + DBG2(DBG_CFG, "configured proposals: %#P", proposals); + } return proposals; } diff --git a/src/libcharon/config/child_cfg.h b/src/libcharon/config/child_cfg.h index 258af040a..bdeebca4c 100644 --- a/src/libcharon/config/child_cfg.h +++ b/src/libcharon/config/child_cfg.h @@ -91,9 +91,10 @@ struct child_cfg_t { * Resulting list and all of its proposals must be freed after use. * * @param strip_ke TRUE strip out key exchange methods + * @param log whether to log the configured proposals * @return list of proposals */ - linked_list_t* (*get_proposals)(child_cfg_t *this, bool strip_ke); + linked_list_t* (*get_proposals)(child_cfg_t *this, bool strip_ke, bool log); /** * Select a proposal from a supplied list. diff --git a/src/libcharon/config/ike_cfg.c b/src/libcharon/config/ike_cfg.c index 5d73157b0..44bccd5f5 100644 --- a/src/libcharon/config/ike_cfg.c +++ b/src/libcharon/config/ike_cfg.c @@ -318,7 +318,7 @@ METHOD(ike_cfg_t, add_proposal, void, } METHOD(ike_cfg_t, get_proposals, linked_list_t*, - private_ike_cfg_t *this) + private_ike_cfg_t *this, bool log) { enumerator_t *enumerator; proposal_t *current; @@ -333,8 +333,10 @@ METHOD(ike_cfg_t, get_proposals, linked_list_t*, } enumerator->destroy(enumerator); - DBG2(DBG_CFG, "configured proposals: %#P", proposals); - + if (log) + { + DBG2(DBG_CFG, "configured proposals: %#P", proposals); + } return proposals; } diff --git a/src/libcharon/config/ike_cfg.h b/src/libcharon/config/ike_cfg.h index 9c1581576..200ee0729 100644 --- a/src/libcharon/config/ike_cfg.h +++ b/src/libcharon/config/ike_cfg.h @@ -178,9 +178,10 @@ struct ike_cfg_t { * * Returned list and its proposals must be destroyed after use. * + * @param log whether to log the configured proposals * @return list containing all the proposals */ - linked_list_t* (*get_proposals) (ike_cfg_t *this); + linked_list_t *(*get_proposals)(ike_cfg_t *this, bool log); /** * Select a proposal from a list of supplied proposals. diff --git a/src/libcharon/plugins/vici/README.md b/src/libcharon/plugins/vici/README.md index 01c3f858c..925aca24d 100644 --- a/src/libcharon/plugins/vici/README.md +++ b/src/libcharon/plugins/vici/README.md @@ -893,7 +893,18 @@ _list-conns_ command. version = reauth_time = rekey_time = - + proposals = { # numbered (zero-based) sub-sections for IKE proposal + = { # lists with NAME[_KEYSIZE] for each transform type in proposal + encr = [ ] + integ = [ ] + prf = [ ] + ke = [ ] + ake1 = [ ] + ... + ake7 = [ ] + sn = [ ] + } + } local*, remote* = { # multiple local and remote auth sections class = eap-type = @@ -921,6 +932,12 @@ _list-conns_ command. rekey_time = rekey_bytes = rekey_packets = + esp_proposals = { + + } + ah_proposals = { + + } local-ts = [ ] diff --git a/src/libcharon/plugins/vici/vici_query.c b/src/libcharon/plugins/vici/vici_query.c index 98a09fa4a..b5c84d4a9 100644 --- a/src/libcharon/plugins/vici/vici_query.c +++ b/src/libcharon/plugins/vici/vici_query.c @@ -208,6 +208,81 @@ static void list_label(vici_builder_t *b, child_sa_t *child, child_cfg_t *cfg) } } +/** + * Print all algorithms of the given type + */ +static void list_transforms(vici_builder_t *b, proposal_t *proposal, char *name, + transform_type_t type) +{ + enumerator_t *enumerator; + enum_name_t *names; + char buf[BUF_LEN]; + uint16_t alg, ks; + bool first = TRUE; + + names = transform_get_enum_names(type); + + enumerator = proposal->create_enumerator(proposal, type); + while (enumerator->enumerate(enumerator, &alg, &ks)) + { + if (first) + { + b->begin_list(b, name); + first = FALSE; + } + buf[0] = '\0'; + if (ks) + { + snprintf(buf, sizeof(buf), "_%u", ks); + } + b->add_li(b, "%N%s", names, alg, buf); + } + enumerator->destroy(enumerator); + + if (!first) + { + b->end_list(b); + } +} + +/** + * List proposals for a config + */ +static void list_proposals(vici_builder_t *b, linked_list_t *proposals, + char *label, protocol_id_t protocol) +{ + enumerator_t *enumerator; + proposal_t *proposal; + char buf[BUF_LEN]; + u_int num = 0; + + b->begin_section(b, label); + enumerator = proposals->create_enumerator(proposals); + while (enumerator->enumerate(enumerator, &proposal)) + { + if (proposal->get_protocol(proposal) == protocol) + { + snprintf(buf, sizeof(buf), "%u", num++); + b->begin_section(b, buf); + list_transforms(b, proposal, "encr", ENCRYPTION_ALGORITHM); + list_transforms(b, proposal, "integ", INTEGRITY_ALGORITHM); + list_transforms(b, proposal, "prf", PSEUDO_RANDOM_FUNCTION); + list_transforms(b, proposal, "ke", KEY_EXCHANGE_METHOD); + list_transforms(b, proposal, "ake1", ADDITIONAL_KEY_EXCHANGE_1); + list_transforms(b, proposal, "ake2", ADDITIONAL_KEY_EXCHANGE_2); + list_transforms(b, proposal, "ake3", ADDITIONAL_KEY_EXCHANGE_3); + list_transforms(b, proposal, "ake4", ADDITIONAL_KEY_EXCHANGE_4); + list_transforms(b, proposal, "ake5", ADDITIONAL_KEY_EXCHANGE_5); + list_transforms(b, proposal, "ake6", ADDITIONAL_KEY_EXCHANGE_6); + list_transforms(b, proposal, "ake7", ADDITIONAL_KEY_EXCHANGE_7); + list_transforms(b, proposal, "sn", EXTENDED_SEQUENCE_NUMBERS); + b->end_section(b); + } + } + enumerator->destroy(enumerator); + b->end_section(b); +} + /** * List additional key exchanges */ @@ -1006,6 +1081,10 @@ CALLBACK(list_conns, vici_message_t*, b->add_kv(b, "unique", "%N", unique_policy_names, peer_cfg->get_unique_policy(peer_cfg)); + list = ike_cfg->get_proposals(ike_cfg, FALSE); + list_proposals(b, list, "proposals", PROTO_IKE); + list->destroy_offset(list, offsetof(proposal_t, destroy)); + dpd_delay = peer_cfg->get_dpd(peer_cfg); if (dpd_delay) { @@ -1052,6 +1131,11 @@ CALLBACK(list_conns, vici_message_t*, b->add_kv(b, "close_action", "%N", action_names, child_cfg->get_close_action(child_cfg)); + list = child_cfg->get_proposals(child_cfg, FALSE, FALSE); + list_proposals(b, list, "esp_proposals", PROTO_ESP); + list_proposals(b, list, "ah_proposals", PROTO_AH); + list->destroy_offset(list, offsetof(proposal_t, destroy)); + b->begin_list(b, "local-ts"); list = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL); selectors = list->create_enumerator(list); diff --git a/src/libcharon/sa/ikev1/tasks/aggressive_mode.c b/src/libcharon/sa/ikev1/tasks/aggressive_mode.c index d86c95178..681c8a12f 100644 --- a/src/libcharon/sa/ikev1/tasks/aggressive_mode.c +++ b/src/libcharon/sa/ikev1/tasks/aggressive_mode.c @@ -240,7 +240,7 @@ METHOD(task_t, build_i, status_t, FALSE); } this->lifetime += this->peer_cfg->get_over_time(this->peer_cfg); - proposals = ike_cfg->get_proposals(ike_cfg); + proposals = ike_cfg->get_proposals(ike_cfg, TRUE); sa_payload = sa_payload_create_from_proposals_v1(proposals, this->lifetime, 0, this->method, MODE_NONE, ENCAP_NONE, 0); diff --git a/src/libcharon/sa/ikev1/tasks/main_mode.c b/src/libcharon/sa/ikev1/tasks/main_mode.c index e8ddff9ab..936e05c36 100644 --- a/src/libcharon/sa/ikev1/tasks/main_mode.c +++ b/src/libcharon/sa/ikev1/tasks/main_mode.c @@ -271,7 +271,7 @@ METHOD(task_t, build_i, status_t, FALSE); } this->lifetime += this->peer_cfg->get_over_time(this->peer_cfg); - proposals = ike_cfg->get_proposals(ike_cfg); + proposals = ike_cfg->get_proposals(ike_cfg, TRUE); sa_payload = sa_payload_create_from_proposals_v1(proposals, this->lifetime, 0, this->method, MODE_NONE, ENCAP_NONE, 0); diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c index 8c06db523..bafe46af0 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.c +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c @@ -802,7 +802,7 @@ static linked_list_t *get_proposals(private_quick_mode_t *this, proposal_t *proposal; enumerator_t *enumerator; - list = this->config->get_proposals(this->config, FALSE); + list = this->config->get_proposals(this->config, FALSE, TRUE); enumerator = list->create_enumerator(list); while (enumerator->enumerate(enumerator, &proposal)) { @@ -864,7 +864,7 @@ METHOD(task_t, build_i, status_t, } } - list = this->config->get_proposals(this->config, FALSE); + list = this->config->get_proposals(this->config, FALSE, TRUE); if (list->get_first(list, (void**)&proposal) == SUCCESS) { this->proto = proposal->get_protocol(proposal); diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c index 149808ee2..13ea7be47 100644 --- a/src/libcharon/sa/ikev2/tasks/child_create.c +++ b/src/libcharon/sa/ikev2/tasks/child_create.c @@ -1768,7 +1768,7 @@ METHOD(task_t, build_i, status_t, OPT_PER_CPU_SAS); } - this->proposals = this->config->get_proposals(this->config, no_ke); + this->proposals = this->config->get_proposals(this->config, no_ke, TRUE); this->mode = this->config->get_mode(this->config); this->child.if_id_in_def = this->ike_sa->get_if_id(this->ike_sa, TRUE); @@ -2486,7 +2486,7 @@ static void raise_alerts(private_child_create_t *this, notify_type_t type) switch (type) { case NO_PROPOSAL_CHOSEN: - list = this->config->get_proposals(this->config, FALSE); + list = this->config->get_proposals(this->config, FALSE, FALSE); charon->bus->alert(charon->bus, ALERT_PROPOSAL_MISMATCH_CHILD, list); list->destroy_offset(list, offsetof(proposal_t, destroy)); break; diff --git a/src/libcharon/sa/ikev2/tasks/ike_init.c b/src/libcharon/sa/ikev2/tasks/ike_init.c index b7083917a..a28996225 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_init.c +++ b/src/libcharon/sa/ikev2/tasks/ike_init.c @@ -367,7 +367,7 @@ static bool build_payloads(private_ike_init_t *this, message_t *message) if (this->initiator) { - proposal_list = ike_cfg->get_proposals(ike_cfg); + proposal_list = ike_cfg->get_proposals(ike_cfg, TRUE); other_ke_methods = linked_list_create(); enumerator = proposal_list->create_enumerator(proposal_list); while (enumerator->enumerate(enumerator, (void**)&proposal)) @@ -1216,7 +1216,7 @@ static void raise_alerts(private_ike_init_t *this, notify_type_t type) { case NO_PROPOSAL_CHOSEN: ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa); - list = ike_cfg->get_proposals(ike_cfg); + list = ike_cfg->get_proposals(ike_cfg, FALSE); charon->bus->alert(charon->bus, ALERT_PROPOSAL_MISMATCH_IKE, list); list->destroy_offset(list, offsetof(proposal_t, destroy)); break; diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c index 90a29b29b..9a4f08d07 100644 --- a/src/libcharon/sa/trap_manager.c +++ b/src/libcharon/sa/trap_manager.c @@ -219,7 +219,7 @@ static status_t install_trap(child_sa_t *child_sa, linked_list_t *local, /* we don't know the finally negotiated protocol (ESP|AH), we install * the SA with the protocol of the first proposal */ - proposals = child->get_proposals(child, TRUE); + proposals = child->get_proposals(child, TRUE, FALSE); if (proposals->get_first(proposals, (void**)&proposal) == SUCCESS) { proto = proposal->get_protocol(proposal);