]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
EAP-TTLS peer: Fix parsing auth= and autheap= phase2 params
authorPali Rohár <pali.rohar@gmail.com>
Sun, 6 Dec 2015 11:01:32 +0000 (12:01 +0100)
committerJouni Malinen <j@w1.fi>
Thu, 17 Dec 2015 22:24:30 +0000 (00:24 +0200)
This patch fixes an issue with an invalid phase2 parameter value
auth=MSCHAPv2 getting interpreted as auth=MSCHAP (v1) which could
degrade security (though, only within a protected TLS tunnel). Now when
invalid or unsupported auth= phase2 parameter combinations are
specified, EAP-TTLS initialization throws an error instead of silently
doing something.

More then one auth= phase2 type cannot be specified and also both auth= and
autheap= options cannot be specified.

Parsing phase2 type is case sensitive (as in other EAP parts), so phase2
parameter auth=MSCHAPv2 is invalid. Only auth=MSCHAPV2 is correct.

Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
[Use cstr_token() to get rid of unnecessary allocation; cleanup]
Signed-off-by: Jouni Malinen <j@w1.fi>
src/eap_peer/eap_ttls.c

index 9741dedefb84af22c8f94fec1bb19e9c0f352bf4..a4b269715b572abef9a3783971829b2c8f56fb59 100644 (file)
@@ -71,6 +71,7 @@ static void * eap_ttls_init(struct eap_sm *sm)
 {
        struct eap_ttls_data *data;
        struct eap_peer_config *config = eap_get_config(sm);
+       int selected_non_eap;
        char *selected;
 
        data = os_zalloc(sizeof(*data));
@@ -78,26 +79,67 @@ static void * eap_ttls_init(struct eap_sm *sm)
                return NULL;
        data->ttls_version = EAP_TTLS_VERSION;
        selected = "EAP";
+       selected_non_eap = 0;
        data->phase2_type = EAP_TTLS_PHASE2_EAP;
 
+       /*
+        * Either one auth= type or one or more autheap= methods can be
+        * specified.
+        */
        if (config && config->phase2) {
+               const char *token, *last = NULL;
+
+               while ((token = cstr_token(config->phase2, " \t", &last))) {
+                       if (os_strncmp(token, "auth=", 5) != 0)
+                               continue;
+                       token += 5;
+
+                       if (last - token == 8 &&
+                           os_strncmp(token, "MSCHAPV2", 8) == 0) {
+                               selected = "MSCHAPV2";
+                               data->phase2_type = EAP_TTLS_PHASE2_MSCHAPV2;
+                       } else if (last - token == 6 &&
+                                  os_strncmp(token, "MSCHAP", 6) == 0) {
+                               selected = "MSCHAP";
+                               data->phase2_type = EAP_TTLS_PHASE2_MSCHAP;
+                       } else if (last - token == 3 &&
+                                  os_strncmp(token, "PAP", 3) == 0) {
+                               selected = "PAP";
+                               data->phase2_type = EAP_TTLS_PHASE2_PAP;
+                       } else if (last - token == 4 &&
+                                  os_strncmp(token, "CHAP", 4) == 0) {
+                               selected = "CHAP";
+                               data->phase2_type = EAP_TTLS_PHASE2_CHAP;
+                       } else {
+                               wpa_printf(MSG_ERROR,
+                                          "EAP-TTLS: Unsupported Phase2 type '%s'",
+                                          token);
+                               eap_ttls_deinit(sm, data);
+                               return NULL;
+                       }
+
+                       if (selected_non_eap) {
+                               wpa_printf(MSG_ERROR,
+                                          "EAP-TTLS: Only one Phase2 type can be specified");
+                               eap_ttls_deinit(sm, data);
+                               return NULL;
+                       }
+
+                       selected_non_eap = 1;
+               }
+
                if (os_strstr(config->phase2, "autheap=")) {
+                       if (selected_non_eap) {
+                               wpa_printf(MSG_ERROR,
+                                          "EAP-TTLS: Both auth= and autheap= params cannot be specified");
+                               eap_ttls_deinit(sm, data);
+                               return NULL;
+                       }
                        selected = "EAP";
                        data->phase2_type = EAP_TTLS_PHASE2_EAP;
-               } else if (os_strstr(config->phase2, "auth=MSCHAPV2")) {
-                       selected = "MSCHAPV2";
-                       data->phase2_type = EAP_TTLS_PHASE2_MSCHAPV2;
-               } else if (os_strstr(config->phase2, "auth=MSCHAP")) {
-                       selected = "MSCHAP";
-                       data->phase2_type = EAP_TTLS_PHASE2_MSCHAP;
-               } else if (os_strstr(config->phase2, "auth=PAP")) {
-                       selected = "PAP";
-                       data->phase2_type = EAP_TTLS_PHASE2_PAP;
-               } else if (os_strstr(config->phase2, "auth=CHAP")) {
-                       selected = "CHAP";
-                       data->phase2_type = EAP_TTLS_PHASE2_CHAP;
                }
        }
+
        wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 type: %s", selected);
 
        if (data->phase2_type == EAP_TTLS_PHASE2_EAP) {