From ac1bc549483ca2b95eb54ac67ba24a795b763d8f Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 6 Oct 2013 18:14:51 -0700 Subject: [PATCH] Interworking: Add domain_suffix_match for credentials This allow domain_suffix_match to be specified for a cred block and then get this copied for the network blocks generated from this credential as part of Interworking network selection. Signed-hostap: Jouni Malinen --- wpa_supplicant/README-HS20 | 15 +++++++++++++++ wpa_supplicant/config.c | 7 +++++++ wpa_supplicant/config.h | 18 ++++++++++++++++++ wpa_supplicant/config_file.c | 3 +++ wpa_supplicant/interworking.c | 5 +++++ 5 files changed, 48 insertions(+) diff --git a/wpa_supplicant/README-HS20 b/wpa_supplicant/README-HS20 index 7a570bdd7..940c57669 100644 --- a/wpa_supplicant/README-HS20 +++ b/wpa_supplicant/README-HS20 @@ -166,6 +166,20 @@ Credentials can be pre-configured for automatic network selection: # milenage: Milenage parameters for SIM/USIM simulator in :: # format # +# domain_suffix_match: Constraint for server domain name +# If set, this FQDN is used as a suffix match requirement for the AAA +# server certificate in SubjectAltName dNSName element(s). If a +# matching dNSName is found, this constraint is met. If no dNSName +# values are present, this constraint is matched against SubjetName CN +# using same suffix match comparison. Suffix match here means that the +# host/domain name is compared one label at a time starting from the +# top-level domain and all the labels in @domain_suffix_match shall be +# included in the certificate. The certificate may include additional +# sub-level labels in addition to the required labels. +# +# For example, domain_suffix_match=example.com would match +# test.example.com but would not match test-example.com. +# # domain: Home service provider FQDN(s) # This is used to compare against the Domain Name List to figure out # whether the AP is operated by the Home SP. Multiple domain entries can @@ -205,6 +219,7 @@ Credentials can be pre-configured for automatic network selection: # password="password" # ca_cert="/etc/wpa_supplicant/ca.pem" # domain="example.com" +# domain_suffix_match="example.com" #} # #cred={ diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 2b47e8e69..888518ea1 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -1869,6 +1869,7 @@ void wpa_config_free_cred(struct wpa_cred *cred) for (i = 0; i < cred->num_domain; i++) os_free(cred->domain[i]); os_free(cred->domain); + os_free(cred->domain_suffix_match); os_free(cred->eap_method); os_free(cred->phase1); os_free(cred->phase2); @@ -2440,6 +2441,12 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var, return 0; } + if (os_strcmp(var, "domain_suffix_match") == 0) { + os_free(cred->domain_suffix_match); + cred->domain_suffix_match = val; + return 0; + } + if (os_strcmp(var, "domain") == 0) { char **new_domain; new_domain = os_realloc_array(cred->domain, diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 27301b803..64396df0d 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -149,6 +149,24 @@ struct wpa_cred { */ char *milenage; + /** + * domain_suffix_match - Constraint for server domain name + * + * If set, this FQDN is used as a suffix match requirement for the AAA + * server certificate in SubjectAltName dNSName element(s). If a + * matching dNSName is found, this constraint is met. If no dNSName + * values are present, this constraint is matched against SubjetName CN + * using same suffix match comparison. Suffix match here means that the + * host/domain name is compared one label at a time starting from the + * top-level domain and all the labels in @domain_suffix_match shall be + * included in the certificate. The certificate may include additional + * sub-level labels in addition to the required labels. + * + * For example, domain_suffix_match=example.com would match + * test.example.com but would not match test-example.com. + */ + char *domain_suffix_match; + /** * domain - Home service provider FQDN(s) * diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 2c14a2c91..f3eeca8d5 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -757,6 +757,9 @@ static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred) fprintf(f, "\tmilenage=\"%s\"\n", cred->milenage); for (i = 0; i < cred->num_domain; i++) fprintf(f, "\tdomain=\"%s\"\n", cred->domain[i]); + if (cred->domain_suffix_match) + fprintf(f, "\tdomain_suffix_match=\"%s\"", + cred->domain_suffix_match); if (cred->roaming_consortium_len) { fprintf(f, "\troaming_consortium="); for (i = 0; i < cred->roaming_consortium_len; i++) diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c index 01acae1c6..c296386eb 100644 --- a/wpa_supplicant/interworking.c +++ b/wpa_supplicant/interworking.c @@ -1100,6 +1100,11 @@ static int interworking_set_eap_params(struct wpa_ssid *ssid, wpa_config_set_quoted(ssid, "ca_cert", cred->ca_cert) < 0) return -1; + if (cred->domain_suffix_match && cred->domain_suffix_match[0] && + wpa_config_set_quoted(ssid, "domain_suffix_match", + cred->domain_suffix_match) < 0) + return -1; + return 0; }