Send EAP-Nak with supported types if requested type is unsupported
[strongswan.git] / src / libcharon / sa / ikev2 / authenticators / eap_authenticator.c
index b81c5c8..46913a7 100644 (file)
@@ -219,23 +219,12 @@ static eap_payload_t* server_initiate_eap(private_eap_authenticator_t *this,
  */
 static void replace_eap_identity(private_eap_authenticator_t *this)
 {
-       enumerator_t *enumerator;
-       auth_rule_t rule;
+       identification_t *eap_identity;
        auth_cfg_t *cfg;
-       void *ptr;
 
+       eap_identity = this->eap_identity->clone(this->eap_identity);
        cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
-       enumerator = cfg->create_enumerator(cfg);
-       while (enumerator->enumerate(enumerator, &rule, &ptr))
-       {
-               if (rule == AUTH_RULE_EAP_IDENTITY)
-               {
-                       cfg->replace(cfg, enumerator, AUTH_RULE_EAP_IDENTITY,
-                                                this->eap_identity->clone(this->eap_identity));
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
+       cfg->add(cfg, AUTH_RULE_EAP_IDENTITY, eap_identity);
 }
 
 /**
@@ -368,9 +357,11 @@ static eap_payload_t* client_process_eap(private_eap_authenticator_t *this,
                        this->method->destroy(this->method);
                        this->method = NULL;
                }
+               /* FIXME: sending a Nak is not correct here as EAP_IDENTITY (1) is no
+                * EAP method (types 3-253, 255) */
                DBG1(DBG_IKE, "%N not supported, sending EAP_NAK",
                         eap_type_names, type);
-               return eap_payload_create_nak(in->get_identifier(in));
+               return eap_payload_create_nak(in->get_identifier(in), FALSE);
        }
        if (this->method == NULL)
        {
@@ -388,7 +379,7 @@ static eap_payload_t* client_process_eap(private_eap_authenticator_t *this,
                if (!this->method)
                {
                        DBG1(DBG_IKE, "EAP method not supported, sending EAP_NAK");
-                       return eap_payload_create_nak(in->get_identifier(in));
+                       return eap_payload_create_nak(in->get_identifier(in), vendor != 0);
                }
        }
 
@@ -431,8 +422,11 @@ static bool verify_auth(private_eap_authenticator_t *this, message_t *message,
        }
        other_id = this->ike_sa->get_other_id(this->ike_sa);
        keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
-       auth_data = keymat->get_psk_sig(keymat, TRUE, init, nonce,
-                                                                       this->msk, other_id, this->reserved);
+       if (!keymat->get_psk_sig(keymat, TRUE, init, nonce,
+                                                        this->msk, other_id, this->reserved, &auth_data))
+       {
+               return FALSE;
+       }
        recv_auth_data = auth_payload->get_data(auth_payload);
        if (!auth_data.len || !chunk_equals(auth_data, recv_auth_data))
        {
@@ -454,7 +448,7 @@ static bool verify_auth(private_eap_authenticator_t *this, message_t *message,
 /**
  * Build AUTH payload
  */
-static void build_auth(private_eap_authenticator_t *this, message_t *message,
+static bool build_auth(private_eap_authenticator_t *this, message_t *message,
                                           chunk_t nonce, chunk_t init)
 {
        auth_payload_t *auth_payload;
@@ -468,13 +462,17 @@ static void build_auth(private_eap_authenticator_t *this, message_t *message,
        DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N",
                 my_id, auth_class_names, AUTH_CLASS_EAP);
 
-       auth_data = keymat->get_psk_sig(keymat, FALSE, init, nonce,
-                                                                       this->msk, my_id, this->reserved);
+       if (!keymat->get_psk_sig(keymat, FALSE, init, nonce,
+                                                       this->msk, my_id, this->reserved, &auth_data))
+       {
+               return FALSE;
+       }
        auth_payload = auth_payload_create();
        auth_payload->set_auth_method(auth_payload, AUTH_PSK);
        auth_payload->set_data(auth_payload, auth_data);
        message->add_payload(message, (payload_t*)auth_payload);
        chunk_free(&auth_data);
+       return TRUE;
 }
 
 METHOD(authenticator_t, process_server, status_t,
@@ -524,9 +522,9 @@ METHOD(authenticator_t, build_server, status_t,
                }
                return NEED_MORE;
        }
-       if (this->eap_complete && this->auth_complete)
+       if (this->eap_complete && this->auth_complete &&
+               build_auth(this, message, this->received_nonce, this->sent_init))
        {
-               build_auth(this, message, this->received_nonce, this->sent_init);
                return SUCCESS;
        }
        return FAILED;
@@ -622,9 +620,9 @@ METHOD(authenticator_t, build_client, status_t,
                this->eap_payload = NULL;
                return NEED_MORE;
        }
-       if (this->eap_complete)
+       if (this->eap_complete &&
+               build_auth(this, message, this->received_nonce, this->sent_init))
        {
-               build_auth(this, message, this->received_nonce, this->sent_init);
                return NEED_MORE;
        }
        return NEED_MORE;