]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
EAP-TEAP server: Allow a specific Identity-Type to be requested/required
authorJouni Malinen <j@w1.fi>
Mon, 19 Aug 2019 22:37:31 +0000 (01:37 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 19 Aug 2019 23:13:22 +0000 (02:13 +0300)
The new hostapd configuration parameter eap_teap_id can be used to
configure the expected behavior for used identity type.

Signed-off-by: Jouni Malinen <j@w1.fi>
hostapd/config_file.c
hostapd/hostapd.conf
src/ap/ap_config.h
src/ap/authsrv.c
src/ap/ieee802_1x.c
src/eap_server/eap.h
src/eap_server/eap_server_teap.c
src/radius/radius_server.c
src/radius/radius_server.h

index 1ef7d57cc58e2aa472d3aa20b6fdd57574388b2f..4a2f12d94dafbe9d3e56b2b39b9e3b95a0c9db9b 100644 (file)
@@ -2622,6 +2622,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                bss->eap_teap_pac_no_inner = atoi(pos);
        } else if (os_strcmp(buf, "eap_teap_separate_result") == 0) {
                bss->eap_teap_separate_result = atoi(pos);
+       } else if (os_strcmp(buf, "eap_teap_id") == 0) {
+               bss->eap_teap_id = atoi(pos);
 #endif /* EAP_SERVER_TEAP */
 #ifdef EAP_SERVER_SIM
        } else if (os_strcmp(buf, "eap_sim_db") == 0) {
index f36e1fa3ae83941fe1fd3710bd2cd597a117b058..5497df24a38b0eea652eebcf349cbd45329cec76 100644 (file)
@@ -1206,6 +1206,14 @@ eap_server=0
 # 1 = send in a separate message (for testing purposes)
 #eap_teap_separate_result=0
 
+# EAP-TEAP identities
+# 0 = allow any identity type (default)
+# 1 = require user identity
+# 2 = require machine identity
+# 3 = request user identity; accept either user or machine identity
+# 4 = request machine identity; accept either user or machine identity
+#eap_teap_id=0
+
 # EAP-SIM and EAP-AKA protected success/failure indication using AT_RESULT_IND
 # (default: 0 = disabled).
 #eap_sim_aka_result_ind=1
index daf787e1699137a259e3e1477e9fa6a1d5038a2b..484e1b679f5f0c149f1991d7fd9a4145f0333d52 100644 (file)
@@ -430,6 +430,7 @@ struct hostapd_bss_config {
        int eap_teap_auth;
        int eap_teap_pac_no_inner;
        int eap_teap_separate_result;
+       int eap_teap_id;
        int eap_sim_aka_result_ind;
        int eap_sim_id;
        int tnc;
index 21e4c22d8bf0a28357b7c2fe40aebe4d9607ea63..1fd1e382b8a7a80f0d2f8331ac190e891b672ff9 100644 (file)
@@ -123,6 +123,7 @@ static int hostapd_setup_radius_srv(struct hostapd_data *hapd)
        srv.eap_teap_auth = conf->eap_teap_auth;
        srv.eap_teap_pac_no_inner = conf->eap_teap_pac_no_inner;
        srv.eap_teap_separate_result = conf->eap_teap_separate_result;
+       srv.eap_teap_id = conf->eap_teap_id;
        srv.eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;
        srv.eap_sim_id = conf->eap_sim_id;
        srv.tnc = conf->tnc;
index 34637f35ed88ca9ff3d2c85c65a9f0db970859d8..fd47013efe56e6aabd40283dd7a68feb777d92a8 100644 (file)
@@ -2433,6 +2433,7 @@ static struct eap_config * ieee802_1x_eap_config(struct hostapd_data *hapd)
        cfg->pac_key_refresh_time = hapd->conf->pac_key_refresh_time;
        cfg->eap_teap_auth = hapd->conf->eap_teap_auth;
        cfg->eap_teap_separate_result = hapd->conf->eap_teap_separate_result;
+       cfg->eap_teap_id = hapd->conf->eap_teap_id;
        cfg->eap_sim_aka_result_ind = hapd->conf->eap_sim_aka_result_ind;
        cfg->eap_sim_id = hapd->conf->eap_sim_id;
        cfg->tnc = hapd->conf->tnc;
index 6988e0b0f3f8b6fe2e534ceea42543e6a887f57c..0b8265e465cbeac5173ea6cf0adabab0028be1a8 100644 (file)
@@ -198,6 +198,13 @@ struct eap_config {
        int eap_teap_auth;
        int eap_teap_pac_no_inner;
        int eap_teap_separate_result;
+       enum eap_teap_id {
+               EAP_TEAP_ID_ALLOW_ANY = 0,
+               EAP_TEAP_ID_REQUIRE_USER = 1,
+               EAP_TEAP_ID_REQUIRE_MACHINE = 2,
+               EAP_TEAP_ID_REQUEST_USER_ACCEPT_MACHINE = 3,
+               EAP_TEAP_ID_REQUEST_MACHINE_ACCEPT_USER = 4,
+       } eap_teap_id;
 
        /**
         * eap_sim_aka_result_ind - EAP-SIM/AKA protected success indication
index f2f917b7767333d98fa172b89866cae328a7545d..f45034e142e3e797d20cd0bc872148ccc1806324 100644 (file)
@@ -529,30 +529,56 @@ static struct wpabuf * eap_teap_build_phase2_req(struct eap_sm *sm,
                                                 struct eap_teap_data *data,
                                                 u8 id)
 {
-       struct wpabuf *req;
+       struct wpabuf *req, *id_tlv = NULL;
+
+       if (sm->cfg->eap_teap_auth == 1 ||
+           (data->phase2_priv && data->phase2_method &&
+            data->phase2_method->vendor == EAP_VENDOR_IETF &&
+            data->phase2_method->method == EAP_TYPE_IDENTITY)) {
+               switch (sm->cfg->eap_teap_id) {
+               case EAP_TEAP_ID_ALLOW_ANY:
+                       break;
+               case EAP_TEAP_ID_REQUIRE_USER:
+               case EAP_TEAP_ID_REQUEST_USER_ACCEPT_MACHINE:
+                       id_tlv = eap_teap_tlv_identity_type(
+                               TEAP_IDENTITY_TYPE_USER);
+                       break;
+               case EAP_TEAP_ID_REQUIRE_MACHINE:
+               case EAP_TEAP_ID_REQUEST_MACHINE_ACCEPT_USER:
+                       id_tlv = eap_teap_tlv_identity_type(
+                               TEAP_IDENTITY_TYPE_MACHINE);
+                       break;
+               }
+       }
 
        if (sm->cfg->eap_teap_auth == 1) {
                wpa_printf(MSG_DEBUG, "EAP-TEAP: Initiate Basic-Password-Auth");
                req = wpabuf_alloc(sizeof(struct teap_tlv_hdr));
-               if (!req)
+               if (!req) {
+                       wpabuf_free(id_tlv);
                        return NULL;
+               }
                eap_teap_put_tlv_hdr(req, TEAP_TLV_BASIC_PASSWORD_AUTH_REQ, 0);
-               return req;
+               return wpabuf_concat(req, id_tlv);
        }
 
        wpa_printf(MSG_DEBUG, "EAP-TEAP: Initiate inner EAP method");
        if (!data->phase2_priv) {
                wpa_printf(MSG_DEBUG,
                           "EAP-TEAP: Phase 2 method not initialized");
+               wpabuf_free(id_tlv);
                return NULL;
        }
 
        req = data->phase2_method->buildReq(sm, data->phase2_priv, id);
-       if (!req)
+       if (!req) {
+               wpabuf_free(id_tlv);
                return NULL;
+       }
 
        wpa_hexdump_buf_key(MSG_MSGDUMP, "EAP-TEAP: Phase 2 EAP-Request", req);
-       return eap_teap_tlv_eap_payload(req);
+
+       return wpabuf_concat(eap_teap_tlv_eap_payload(req), id_tlv);
 }
 
 
@@ -960,9 +986,27 @@ static int eap_teap_phase2_init(struct eap_sm *sm, struct eap_teap_data *data,
 }
 
 
+static int eap_teap_valid_id_type(struct eap_sm *sm,
+                                 enum teap_identity_types id_type)
+{
+       if (sm->cfg->eap_teap_id == EAP_TEAP_ID_REQUIRE_USER &&
+           id_type != TEAP_IDENTITY_TYPE_USER)
+               return 0;
+       if (sm->cfg->eap_teap_id == EAP_TEAP_ID_REQUIRE_MACHINE &&
+           id_type != TEAP_IDENTITY_TYPE_MACHINE)
+               return 0;
+       if (sm->cfg->eap_teap_id != EAP_TEAP_ID_ALLOW_ANY &&
+           id_type != TEAP_IDENTITY_TYPE_USER &&
+           id_type != TEAP_IDENTITY_TYPE_MACHINE)
+               return 0;
+       return 1;
+}
+
+
 static void eap_teap_process_phase2_response(struct eap_sm *sm,
                                             struct eap_teap_data *data,
-                                            u8 *in_data, size_t in_len)
+                                            u8 *in_data, size_t in_len,
+                                            enum teap_identity_types id_type)
 {
        int next_vendor = EAP_VENDOR_IETF;
        enum eap_type next_type = EAP_TYPE_NONE;
@@ -1041,6 +1085,13 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm,
 
        switch (data->state) {
        case PHASE2_ID:
+               if (!eap_teap_valid_id_type(sm, id_type)) {
+                       wpa_printf(MSG_DEBUG,
+                                  "EAP-TEAP: Provided Identity-Type %u not allowed",
+                                  id_type);
+                       eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD);
+                       break;
+               }
                if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
                        wpa_hexdump_ascii(MSG_DEBUG,
                                          "EAP-TEAP: Phase 2 Identity not found in the user database",
@@ -1097,7 +1148,8 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm,
 
 static void eap_teap_process_phase2_eap(struct eap_sm *sm,
                                        struct eap_teap_data *data,
-                                       u8 *in_data, size_t in_len)
+                                       u8 *in_data, size_t in_len,
+                                       enum teap_identity_types id_type)
 {
        struct eap_hdr *hdr;
        size_t len;
@@ -1124,7 +1176,8 @@ static void eap_teap_process_phase2_eap(struct eap_sm *sm,
                   (unsigned long) len);
        switch (hdr->code) {
        case EAP_CODE_RESPONSE:
-               eap_teap_process_phase2_response(sm, data, (u8 *) hdr, len);
+               eap_teap_process_phase2_response(sm, data, (u8 *) hdr, len,
+                                                id_type);
                break;
        default:
                wpa_printf(MSG_INFO,
@@ -1137,11 +1190,20 @@ static void eap_teap_process_phase2_eap(struct eap_sm *sm,
 
 static void eap_teap_process_basic_auth_resp(struct eap_sm *sm,
                                             struct eap_teap_data *data,
-                                            u8 *in_data, size_t in_len)
-{
+                                            u8 *in_data, size_t in_len,
+                                            enum teap_identity_types id_type)
+                                 {
        u8 *pos, *end, *username, *password, *new_id;
        u8 userlen, passlen;
 
+       if (!eap_teap_valid_id_type(sm, id_type)) {
+               wpa_printf(MSG_DEBUG,
+                          "EAP-TEAP: Provided Identity-Type %u not allowed",
+                          id_type);
+               eap_teap_req_failure(data, 0);
+               return;
+       }
+
        pos = in_data;
        end = pos + in_len;
 
@@ -1533,7 +1595,8 @@ static void eap_teap_process_phase2_tlvs(struct eap_sm *sm,
                        return;
                }
                eap_teap_process_basic_auth_resp(sm, data, tlv.basic_auth_resp,
-                                                tlv.basic_auth_resp_len);
+                                                tlv.basic_auth_resp_len,
+                                                tlv.identity_type);
        }
 
        if (tlv.eap_payload_tlv) {
@@ -1544,7 +1607,8 @@ static void eap_teap_process_phase2_tlvs(struct eap_sm *sm,
                        return;
                }
                eap_teap_process_phase2_eap(sm, data, tlv.eap_payload_tlv,
-                                           tlv.eap_payload_tlv_len);
+                                           tlv.eap_payload_tlv_len,
+                                           tlv.identity_type);
        }
 
        if (data->state == SUCCESS_SEND_RESULT &&
index a24caec116db20cf306d5a0d039067bafb754c23..067147b7b929e48ee85ec3b413cafe554727a3e8 100644 (file)
@@ -2242,6 +2242,7 @@ radius_server_init(struct radius_server_conf *conf)
        eap_cfg->eap_teap_auth = conf->eap_teap_auth;
        eap_cfg->eap_teap_pac_no_inner = conf->eap_teap_pac_no_inner;
        eap_cfg->eap_teap_separate_result = conf->eap_teap_separate_result;
+       eap_cfg->eap_teap_id = conf->eap_teap_id;
        data->get_eap_user = conf->get_eap_user;
        eap_cfg->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;
        eap_cfg->eap_sim_id = conf->eap_sim_id;
index c8c17dbb64f1fee81c62227b1c1830d3b51eb07c..580a653ef5a988cb029e2c3328888c8be80687da 100644 (file)
@@ -131,6 +131,7 @@ struct radius_server_conf {
        int eap_teap_auth;
        int eap_teap_pac_no_inner;
        int eap_teap_separate_result;
+       int eap_teap_id;
 
        /**
         * eap_sim_aka_result_ind - EAP-SIM/AKA protected success indication