23 RCSID(
"$Id: 5dbf58baff32192cf241671f539de7e2acbaa606 $")
30 #include <freeradius-devel/rad_assert.h>
84 inst->
identity = talloc_asprintf(inst,
"freeradius-%s", RADIUSD_VERSION_STRING);
90 cf_log_err_cs(cs,
"Failed to find 'Auth-Type MS-CHAP' section. Cannot authenticate users.");
118 switch (reply->
da->
attr) {
151 length = htons(length);
152 memcpy(hdr->
ms_length, &length,
sizeof(uint16_t));
160 memcpy(ptr, reply->vp_octets, reply->vp_length);
191 length = htons(length);
192 memcpy((eap_round->
request->
type.
data + 2), &length,
sizeof(uint16_t));
193 memcpy((eap_round->
request->
type.
data + 4), reply->vp_strvalue + 1, 42);
198 length = 4 + reply->vp_length - 1;
210 length = htons(length);
211 memcpy((eap_round->
request->
type.
data + 2), &length,
sizeof(uint16_t));
216 reply->vp_strvalue + 1, reply->vp_length - 1);
220 RERROR(
"Internal sanity check failed");
238 REQUEST *request = eap_session->request;
240 bool created_challenge =
false;
245 RWDEBUG(
"control:MS-CHAP-Challenge is incorrect length. Ignoring it.");
250 created_challenge =
true;
276 eap_session->opaque =
data;
317 REQUEST *request = eap_session->request;
322 RDEBUG2(
"Passing reply from proxy back into the tunnel %d", request->
reply->
code);
329 RDEBUG2(
"Proxied authentication succeeded");
341 REDEBUG(
"Proxied authentication was rejected");
349 REDEBUG(
"Proxied reply contained no MS-CHAP2-Success or MS-CHAP-Error");
398 REQUEST *request = eap_session->request;
412 switch (data->
code) {
415 RDEBUG2(
"Authentication re-try from client after we sent a failure");
428 int copied = 0 ,seq = 1;
430 RDEBUG2(
"Password change packet received");
433 if (!challenge)
return 0;
437 p = talloc_array(cpw, uint8_t, 68);
446 while (copied < 516) {
449 int to_copy = 516 - copied;
450 if (to_copy > 243) to_copy = 243;
453 p = talloc_array(nt_enc, uint8_t, 4 + to_copy);
464 RDEBUG2(
"Built change password packet");
477 REDEBUG(
"Sent FAILURE expecting FAILURE but got %d", ccode);
510 REDEBUG(
"Sent SUCCESS expecting SUCCESS (or ACK) but got %d", ccode);
520 REDEBUG(
"Sent CHALLENGE expecting RESPONSE but got %d", ccode);
542 REDEBUG(
"Response is too short");
561 if ((length < (5 + 49)) || (length > (256 + 5 + 49))) {
562 REDEBUG(
"Response contains contradictory length %zu %d", length, 5 + 49);
576 if (!challenge)
return 0;
580 if (!response)
return 0;
594 name->vp_length = length - 49 - 5;
595 name->vp_strvalue = q = talloc_array(name,
char, name->vp_length + 1);
597 q[name->vp_length] =
'\0';
613 char *username = NULL;
616 RDEBUG2(
"Cancelling authentication and letting it be proxied");
624 tunnel->
callback = mschap_postproxy;
630 tunnel,
false,
false,
false);
653 ((username = strchr(challenge->vp_strvalue,
'\\')) != NULL)) {
701 RDEBUG2(
"MSCHAP-Error: %s", response->vp_strvalue);
709 n = sscanf(response->vp_strvalue,
"%*cE=%d R=%d C=%32s", &err, &retry, &buf[0]);
711 RDEBUG2(
"Found new challenge from MS-CHAP-Error: err=%d retry=%d challenge=%s",
715 RDEBUG2(
"Could not parse new challenge from MS-CHAP-Error: %d", n);
728 REDEBUG(
"No MS-CHAP2-Success or MS-CHAP-Error was found");
748 .
name =
"eap_mschapv2",
#define PW_MSCHAP_CHALLENGE
void fr_pair_list_free(VALUE_PAIR **)
Free memory used by a valuepair list.
2nd highest priority debug messages (-xx | -X).
VALUE_PAIR * config
VALUE_PAIR (s) used to set per request parameters for modules and the server core at runtime...
#define MSCHAPV2_CHALLENGE_LEN
RFC2865 - Access-Challenge.
The module is OK, continue.
#define RAD_REQUEST_OPTION_PROXY_EAP
void fr_pair_list_mcopy_by_num(TALLOC_CTX *ctx, VALUE_PAIR **to, VALUE_PAIR **from, unsigned int vendor, unsigned int attr, int8_t tag)
Copy / delete matching pairs between VALUE_PAIR lists.
uint32_t fr_rand(void)
Return a 32-bit random number.
#define MSCHAPV2_HEADER_LEN
static CONF_PARSER module_config[]
#define REQUEST_DATA_EAP_TUNNEL_CALLBACK
VALUE_PAIR * vps
Result of decoding the packet into VALUE_PAIRs.
#define CONF_PARSER_TERMINATOR
#define pair_make_request(_a, _b, _c)
eap_packet_t * request
Packet we will send to the peer.
static int mod_process(void *instance, eap_session_t *eap_session)
Defines a CONF_PAIR to C data type mapping.
fr_dict_enum_t * fr_dict_enum_by_name(fr_dict_t *dict, fr_dict_attr_t const *da, char const *val)
REQUEST * request
Request that contains the response we're processing.
static int mod_session_init(void *instance, eap_session_t *eap_session)
static void fix_mppe_keys(eap_session_t *eap_session, mschapv2_opaque_t *data)
#define VENDORPEC_MICROSOFT
RADIUS_PACKET * proxy
Outgoing request to proxy server.
#define MSCHAPV2_RESPONSE_LEN
static int eapmschapv2_compose(rlm_eap_mschapv2_t *inst, eap_session_t *eap_session, VALUE_PAIR *reply)
VALUE_PAIR * fr_pair_list_copy(TALLOC_CTX *ctx, VALUE_PAIR *from)
Copy a pairlist.
void fr_pair_value_strcpy(VALUE_PAIR *vp, char const *src)
Copy data into an "string" data type.
rlm_rcode_t process_authenticate(int type, REQUEST *request)
size_t fr_hex2bin(uint8_t *bin, size_t outlen, char const *hex, size_t inlen)
Convert hex strings to binary data.
Tracks the progress of a single session of any EAP method.
#define PW_EAP_MSCHAPV2_CHGPASSWD
int cf_section_parse(CONF_SECTION *, void *base, CONF_PARSER const *variables)
Parse a configuration section into user-supplied variables.
unsigned int attr
Attribute number.
unsigned int code
Packet code (type).
eap_round_t * this_round
The EAP response we're processing, and the EAP request we're building.
uint8_t challenge[MSCHAPV2_CHALLENGE_LEN]
Stores an attribute, a value and various bits of other data.
eap_tunnel_callback_t callback
RADIUS_PACKET * reply
Outgoing response.
#define PW_EAP_MSCHAPV2_RESPONSE
void void cf_log_err_cs(CONF_SECTION const *cs, char const *fmt,...) CC_HINT(format(printf
#define PW_EAP_MSCHAPV2_CHALLENGE
static int CC_HINT(nonnull)
rlm_eap_module_t rlm_eap_mschapv2
Contains a pair of request and response packets.
char const * name
The name of the sub-module (without rlm_ prefix).
void rdebug_pair_list(log_lvl_t level, REQUEST *, VALUE_PAIR *, char const *)
Print a list of VALUE_PAIRs.
void fr_pair_delete_by_num(VALUE_PAIR **head, unsigned int vendor, unsigned int attr, int8_t tag)
Delete matching pairs.
void fr_pair_value_memsteal(VALUE_PAIR *vp, uint8_t const *src)
Reparent an allocated octet buffer to a VALUE_PAIR.
Interface to call EAP sub mdoules.
struct rlm_eap_mschapv2_t rlm_eap_mschapv2_t
#define FR_CONF_OFFSET(_n, _t, _s, _f)
RADIUS_PACKET * packet
Incoming request.
int request_data_add(REQUEST *request, void *unique_ptr, int unique_int, void *opaque, bool free_on_replace, bool free_on_parent, bool persist)
Add opaque data to a REQUEST.
VALUE_PAIR * fr_pair_find_by_num(VALUE_PAIR *head, unsigned int vendor, unsigned int attr, int8_t tag)
Find the pair with the matching attribute.
fr_dict_attr_t const * da
Dictionary attribute defines the attribute.
#define PW_EAP_MSCHAPV2_FAILURE
eap_packet_t * response
Packet we received from the peer.
fr_dict_attr_t const * fr_dict_attr_by_num(fr_dict_t *dict, unsigned int vendor, unsigned int attr)
Lookup a fr_dict_attr_t by its vendor and attribute numbers.
String of printable characters.
#define PW_MSCHAP2_SUCCESS
VALUE_PAIR * fr_pair_make(TALLOC_CTX *ctx, VALUE_PAIR **vps, char const *attribute, char const *value, FR_TOKEN op)
Create a VALUE_PAIR from ASCII strings.
uint32_t options
mainly for proxying EAP-MSCHAPv2.
#define PW_EAP_MSCHAPV2_ACK
Value of an enumerated attribute.
void fr_pair_value_memcpy(VALUE_PAIR *vp, uint8_t const *src, size_t len)
Copy data into an "octets" data type.
#define PW_EAP_MSCHAPV2_SUCCESS
static int mod_instantiate(CONF_SECTION *cs, void **instance)