mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-25 17:59:25 +01:00
eap-peap: Fix failures with session resumption
The PEAP RFC wants implementations to enforce that Phase2 methods have been successfully completed prior to accepting a successful result TLV. However, when TLS session resumption is used, some servers will skip phase2 methods entirely and simply send a Result TLV with a success code. This results in iwd (erroneously) rejecting the authentication attempt. Fix this by marking phase2 method as successful if session resumption is being used.
This commit is contained in:
parent
58d70a8c10
commit
eda02fb929
@ -468,7 +468,8 @@ static void eap_extensions_handle_request(struct eap_state *eap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool eap_peap_tunnel_ready(struct eap_state *eap,
|
static bool eap_peap_tunnel_ready(struct eap_state *eap,
|
||||||
const char *peer_identity)
|
const char *peer_identity,
|
||||||
|
bool resumed)
|
||||||
{
|
{
|
||||||
struct peap_state *peap_state = eap_tls_common_get_variant_data(eap);
|
struct peap_state *peap_state = eap_tls_common_get_variant_data(eap);
|
||||||
|
|
||||||
@ -480,6 +481,15 @@ static bool eap_peap_tunnel_ready(struct eap_state *eap,
|
|||||||
*/
|
*/
|
||||||
eap_discard_success_and_failure(eap, true);
|
eap_discard_success_and_failure(eap, true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In case of a resumed session, the server will typically not run
|
||||||
|
* phase2 methods at all, but will instead send a result TLV right
|
||||||
|
* away. Treat this like a successful phase2. In case the server
|
||||||
|
* does proceed with phase2, the success/failure state will be updated.
|
||||||
|
*/
|
||||||
|
if (resumed)
|
||||||
|
eap_method_success(peap_state->phase2);
|
||||||
|
|
||||||
/* MSK, EMSK and challenge derivation */
|
/* MSK, EMSK and challenge derivation */
|
||||||
eap_tls_common_tunnel_prf_get_bytes(eap, true, "client EAP encryption",
|
eap_tls_common_tunnel_prf_get_bytes(eap, true, "client EAP encryption",
|
||||||
peap_state->key, 128);
|
peap_state->key, 128);
|
||||||
|
@ -244,6 +244,7 @@ static void eap_tls_tunnel_ready(const char *peer_identity, void *user_data)
|
|||||||
{
|
{
|
||||||
struct eap_state *eap = user_data;
|
struct eap_state *eap = user_data;
|
||||||
struct eap_tls_state *eap_tls = eap_get_data(eap);
|
struct eap_tls_state *eap_tls = eap_get_data(eap);
|
||||||
|
bool resumed = l_tls_get_session_resumed(eap_tls->tunnel);
|
||||||
|
|
||||||
if (eap_tls->ca_cert && !peer_identity) {
|
if (eap_tls->ca_cert && !peer_identity) {
|
||||||
l_error("%s: TLS did not verify AP identity",
|
l_error("%s: TLS did not verify AP identity",
|
||||||
@ -264,7 +265,7 @@ static void eap_tls_tunnel_ready(const char *peer_identity, void *user_data)
|
|||||||
if (!eap_tls->variant_ops->tunnel_ready)
|
if (!eap_tls->variant_ops->tunnel_ready)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!eap_tls->variant_ops->tunnel_ready(eap, peer_identity))
|
if (!eap_tls->variant_ops->tunnel_ready(eap, peer_identity, resumed))
|
||||||
l_tls_close(eap_tls->tunnel);
|
l_tls_close(eap_tls->tunnel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,8 @@ enum eap_tls_version {
|
|||||||
struct eap_tls_variant_ops {
|
struct eap_tls_variant_ops {
|
||||||
enum eap_tls_version version_max_supported;
|
enum eap_tls_version version_max_supported;
|
||||||
|
|
||||||
bool (*tunnel_ready)(struct eap_state *eap, const char *peer_identity);
|
bool (*tunnel_ready)(struct eap_state *eap, const char *peer_identity,
|
||||||
|
bool resumed);
|
||||||
bool (*tunnel_handle_request)(struct eap_state *eap,
|
bool (*tunnel_handle_request)(struct eap_state *eap,
|
||||||
const uint8_t *data, size_t data_len);
|
const uint8_t *data, size_t data_len);
|
||||||
void (*reset)(void *variant_data);
|
void (*reset)(void *variant_data);
|
||||||
|
@ -35,7 +35,8 @@
|
|||||||
#include "src/eap-tls-common.h"
|
#include "src/eap-tls-common.h"
|
||||||
|
|
||||||
static bool eap_tls_tunnel_ready(struct eap_state *eap,
|
static bool eap_tls_tunnel_ready(struct eap_state *eap,
|
||||||
const char *peer_identity)
|
const char *peer_identity,
|
||||||
|
bool resumed)
|
||||||
{
|
{
|
||||||
uint8_t msk_emsk[128];
|
uint8_t msk_emsk[128];
|
||||||
uint8_t iv[64];
|
uint8_t iv[64];
|
||||||
|
@ -902,7 +902,8 @@ static const struct phase2_method_ops phase2_eap_ops = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static bool eap_ttls_tunnel_ready(struct eap_state *eap,
|
static bool eap_ttls_tunnel_ready(struct eap_state *eap,
|
||||||
const char *peer_identity)
|
const char *peer_identity,
|
||||||
|
bool resumed)
|
||||||
{
|
{
|
||||||
struct phase2_method *phase2 = eap_tls_common_get_variant_data(eap);
|
struct phase2_method *phase2 = eap_tls_common_get_variant_data(eap);
|
||||||
uint8_t msk_emsk[128];
|
uint8_t msk_emsk[128];
|
||||||
|
Loading…
Reference in New Issue
Block a user