mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-30 14:22:37 +01:00
ttls: add support for tunneled MS-CHAP
This commit is contained in:
parent
b46376980a
commit
e8de229223
@ -30,6 +30,7 @@
|
|||||||
#include <ell/ell.h>
|
#include <ell/ell.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "mschaputil.h"
|
||||||
#include "eap.h"
|
#include "eap.h"
|
||||||
#include "eap-private.h"
|
#include "eap-private.h"
|
||||||
#include "eap-tls-common.h"
|
#include "eap-tls-common.h"
|
||||||
@ -47,6 +48,7 @@ enum radius_attr {
|
|||||||
RADIUS_ATTR_USER_NAME = 1,
|
RADIUS_ATTR_USER_NAME = 1,
|
||||||
RADIUS_ATTR_USER_PASSWORD = 2,
|
RADIUS_ATTR_USER_PASSWORD = 2,
|
||||||
RADIUS_ATTR_CHAP_PASSWORD = 3,
|
RADIUS_ATTR_CHAP_PASSWORD = 3,
|
||||||
|
RADIUS_ATTR_MS_CHAP_CHALLENGE = 11,
|
||||||
RADIUS_ATTR_CHAP_CHALLENGE = 60,
|
RADIUS_ATTR_CHAP_CHALLENGE = 60,
|
||||||
RADIUS_ATTR_EAP_MESSAGE = 79,
|
RADIUS_ATTR_EAP_MESSAGE = 79,
|
||||||
};
|
};
|
||||||
@ -222,6 +224,58 @@ static void build_avp_chap_password(struct avp_builder *builder,
|
|||||||
avp_builder_finalize_avp(builder);
|
avp_builder_finalize_avp(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define RADIUS_VENDOR_ID_MICROSOFT 311
|
||||||
|
#define RADIUS_ATTR_MS_CHAP_RESPONSE 1
|
||||||
|
|
||||||
|
#define MS_CHAP_CHALLENGE_LEN 8
|
||||||
|
#define MS_CHAP_LM_RESPONSE_LEN 24
|
||||||
|
#define MS_CHAP_NT_RESPONSE_LEN 24
|
||||||
|
|
||||||
|
static void build_avp_ms_chap_challenge(struct avp_builder *builder,
|
||||||
|
const uint8_t *challenge)
|
||||||
|
{
|
||||||
|
avp_builder_start_avp(builder, RADIUS_ATTR_MS_CHAP_CHALLENGE, true,
|
||||||
|
RADIUS_VENDOR_ID_MICROSOFT);
|
||||||
|
memcpy(avp_builder_reserve(builder, 1, MS_CHAP_CHALLENGE_LEN),
|
||||||
|
challenge, MS_CHAP_CHALLENGE_LEN);
|
||||||
|
avp_builder_finalize_avp(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void build_avp_ms_chap_response(struct avp_builder *builder,
|
||||||
|
const uint8_t *ident,
|
||||||
|
const uint8_t *challenge,
|
||||||
|
const uint8_t *password_hash)
|
||||||
|
{
|
||||||
|
uint8_t *flags;
|
||||||
|
uint8_t nt_challenge_response[NT_CHALLENGE_RESPONSE_LEN];
|
||||||
|
|
||||||
|
avp_builder_start_avp(builder, RADIUS_ATTR_MS_CHAP_RESPONSE, true,
|
||||||
|
RADIUS_VENDOR_ID_MICROSOFT);
|
||||||
|
|
||||||
|
memcpy(avp_builder_reserve(builder, 1, CHAP_IDENT_LEN),
|
||||||
|
ident, CHAP_IDENT_LEN);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RFC 2548: Section 2.1.3
|
||||||
|
*
|
||||||
|
* The Flags field is set to one (0x01), the NT-Response field is to
|
||||||
|
* be used in preference to the LM-Response field for authentication.
|
||||||
|
*/
|
||||||
|
flags = avp_builder_reserve(builder, 1, 1);
|
||||||
|
*flags = 1;
|
||||||
|
|
||||||
|
/* The LM-Response field is left empty */
|
||||||
|
avp_builder_reserve(builder, 1, MS_CHAP_LM_RESPONSE_LEN);
|
||||||
|
|
||||||
|
mschap_challenge_response(challenge, password_hash,
|
||||||
|
nt_challenge_response);
|
||||||
|
|
||||||
|
memcpy(avp_builder_reserve(builder, 1, NT_CHALLENGE_RESPONSE_LEN),
|
||||||
|
nt_challenge_response, NT_CHALLENGE_RESPONSE_LEN);
|
||||||
|
|
||||||
|
avp_builder_finalize_avp(builder);
|
||||||
|
}
|
||||||
|
|
||||||
struct avp_iter {
|
struct avp_iter {
|
||||||
enum radius_attr type;
|
enum radius_attr type;
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
@ -508,6 +562,45 @@ static struct phase2_method phase2_chap = {
|
|||||||
.destroy = eap_ttls_phase2_credentials_destroy,
|
.destroy = eap_ttls_phase2_credentials_destroy,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool eap_ttls_phase2_ms_chap_init(struct eap_state *eap)
|
||||||
|
{
|
||||||
|
struct eap_ttls_state *ttls = eap_get_data(eap);
|
||||||
|
struct phase2_credentials *credentials = ttls->phase2->state;
|
||||||
|
struct avp_builder *builder;
|
||||||
|
uint8_t challenge[MS_CHAP_CHALLENGE_LEN + CHAP_IDENT_LEN];
|
||||||
|
uint8_t password_hash[16];
|
||||||
|
uint8_t ident;
|
||||||
|
uint8_t *data;
|
||||||
|
size_t data_len;
|
||||||
|
|
||||||
|
eap_ttls_phase2_chap_generate_challenge(ttls->tls, challenge,
|
||||||
|
MS_CHAP_CHALLENGE_LEN +
|
||||||
|
CHAP_IDENT_LEN);
|
||||||
|
|
||||||
|
ident = challenge[MS_CHAP_CHALLENGE_LEN];
|
||||||
|
|
||||||
|
builder = avp_builder_new(512);
|
||||||
|
|
||||||
|
build_avp_user_name(builder, credentials->username);
|
||||||
|
build_avp_ms_chap_challenge(builder, challenge);
|
||||||
|
|
||||||
|
mschap_nt_password_hash(credentials->password, password_hash);
|
||||||
|
|
||||||
|
build_avp_ms_chap_response(builder, &ident, challenge, password_hash);
|
||||||
|
|
||||||
|
data = avp_builder_free(builder, false, &data_len);
|
||||||
|
|
||||||
|
l_tls_write(ttls->tls, data, data_len);
|
||||||
|
l_free(data);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct phase2_method phase2_ms_chap = {
|
||||||
|
.init = eap_ttls_phase2_ms_chap_init,
|
||||||
|
.destroy = eap_ttls_phase2_credentials_destroy,
|
||||||
|
};
|
||||||
|
|
||||||
static bool eap_ttls_phase2_pap_init(struct eap_state *eap)
|
static bool eap_ttls_phase2_pap_init(struct eap_state *eap)
|
||||||
{
|
{
|
||||||
struct eap_ttls_state *ttls = eap_get_data(eap);
|
struct eap_ttls_state *ttls = eap_get_data(eap);
|
||||||
@ -996,6 +1089,7 @@ static const struct {
|
|||||||
struct phase2_method *method;
|
struct phase2_method *method;
|
||||||
} tunneled_non_eap_methods[] = {
|
} tunneled_non_eap_methods[] = {
|
||||||
{ "Tunneled-CHAP", &phase2_chap },
|
{ "Tunneled-CHAP", &phase2_chap },
|
||||||
|
{ "Tunneled-MSCHAP", &phase2_ms_chap },
|
||||||
{ "Tunneled-PAP", &phase2_pap },
|
{ "Tunneled-PAP", &phase2_pap },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user