diff --git a/src/charon/plugins/stroke/stroke_config.c b/src/charon/plugins/stroke/stroke_config.c index e9a9cc99d..c894b8f8d 100644 --- a/src/charon/plugins/stroke/stroke_config.c +++ b/src/charon/plugins/stroke/stroke_config.c @@ -528,11 +528,6 @@ static void build_auth_info(private_stroke_config_t *this, bool other_ca_same = FALSE; cert_validation_t valid; - if (msg->add_conn.other.groups) - { - /* TODO: AC groups */ - } - switch (msg->add_conn.crl_policy) { case CRL_STRICT_YES: @@ -632,6 +627,7 @@ static void build_auth_info(private_stroke_config_t *this, auth->add_item(auth, AUTHN_EAP_VENDOR, &msg->add_conn.eap_vendor); } } + if (msg->add_conn.eap_identity) { if (streq(msg->add_conn.eap_identity, "%identity")) @@ -647,6 +643,41 @@ static void build_auth_info(private_stroke_config_t *this, auth->add_item(auth, AUTHN_EAP_IDENTITY, id); id->destroy(id); } + + if (msg->add_conn.other.groups) + { + chunk_t line = { msg->add_conn.other.groups, + strlen(msg->add_conn.other.groups) }; + + while (eat_whitespace(&line)) + { + chunk_t group; + + /* extract the next comma-separated group attribute */ + if (!extract_token(&group, ',', &line)) + { + group = line; + line.len = 0; + } + + /* remove any trailing spaces */ + while (group.len > 0 && *(group.ptr + group.len - 1) == ' ') + { + group.len--; + } + + /* add the group attribute to the list */ + if (group.len > 0) + { + identification_t *ac_group; + + ac_group = identification_create_from_encoding( + ID_IETF_ATTR_STRING, group); + auth->add_item(auth, AUTHZ_AC_GROUP, ac_group); + ac_group->destroy(ac_group); + } + } + } } /** diff --git a/src/charon/plugins/stroke/stroke_list.c b/src/charon/plugins/stroke/stroke_list.c index fb33c9c7c..37147ec2a 100644 --- a/src/charon/plugins/stroke/stroke_list.c +++ b/src/charon/plugins/stroke/stroke_list.c @@ -281,6 +281,7 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo 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)))) @@ -288,7 +289,9 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo continue; } - /* determine any required CAs */ + /* 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)) @@ -315,6 +318,9 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo case AUTHZ_CA_CERT_NAME: other_ca = (identification_t *)ptr; break; + case AUTHZ_AC_GROUP: + ac_groups = TRUE; + break; default: break; } @@ -346,6 +352,26 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo } } + 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) @@ -364,8 +390,6 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo } fprintf(out, "\n"); - /* TODO: list groups */ - children = peer_cfg->create_child_cfg_enumerator(peer_cfg); while (children->enumerate(children, &child_cfg)) { diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c index 4b7ba357b..b5b438a74 100644 --- a/src/libstrongswan/utils/identification.c +++ b/src/libstrongswan/utils/identification.c @@ -916,6 +916,7 @@ static int print(FILE *stream, const struct printf_info *info, case ID_RFC822_ADDR: case ID_DER_ASN1_GN_URI: case ID_EAP: + case ID_IETF_ATTR_STRING: proper = sanitize_chunk(this->encoded); snprintf(buf, sizeof(buf), "%.*s", proper.len, proper.ptr); chunk_free(&proper); @@ -1171,6 +1172,7 @@ identification_t *identification_create_from_encoding(id_type_t type, chunk_t en case ID_PUBKEY_SHA1: case ID_CERT_DER_SHA1: case ID_EAP: + case ID_IETF_ATTR_STRING: default: break; } diff --git a/src/libstrongswan/utils/identification.h b/src/libstrongswan/utils/identification.h index 3b1f55ab2..c83db3aee 100644 --- a/src/libstrongswan/utils/identification.h +++ b/src/libstrongswan/utils/identification.h @@ -131,22 +131,27 @@ enum id_type_t { /** * SHA1 hash over PKCS#1 subjectPublicKeyInfo */ - ID_PUBKEY_INFO_SHA1, + ID_PUBKEY_INFO_SHA1 = 202, /** * SHA1 hash over PKCS#1 subjectPublicKey */ - ID_PUBKEY_SHA1, + ID_PUBKEY_SHA1 = 203, /** * SHA1 hash of the binary DER encoding of a certificate */ - ID_CERT_DER_SHA1, + ID_CERT_DER_SHA1 = 204, /** * Generic EAP identity */ - ID_EAP, + ID_EAP = 205, + + /** + * IETF Attribute Syntax String (RFC 3281) + */ + ID_IETF_ATTR_STRING = 206, }; /**