iPXE
eap_mschapv2.c File Reference

EAP MS-CHAPv2 authentication method. More...

#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/mschapv2.h>
#include <ipxe/eap.h>

Go to the source code of this file.

Data Structures

struct  eap_mschapv2_request
 An EAP MS-CHAPv2 request message. More...
struct  eap_mschapv2_response
 An EAP MS-CHAPv2 response message. More...
struct  eap_mschapv2_success_request
 An EAP MS-CHAPv2 success request message. More...
struct  eap_mschapv2_success_response
 An EAP MS-CHAPv2 success response message. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static int eap_rx_mschapv2_request (struct eap_supplicant *supplicant, const struct eap_mschapv2 *hdr, size_t len)
 Handle EAP MS-CHAPv2 request.
static int eap_rx_mschapv2_success (struct eap_supplicant *supplicant, const struct eap_mschapv2 *hdr, size_t len)
 Handle EAP MS-CHAPv2 success request.
static int eap_rx_mschapv2 (struct eap_supplicant *supplicant, const void *req, size_t req_len)
 Handle EAP MS-CHAPv2.

Variables

struct eap_method eap_mschapv2_method __eap_method
 EAP MS-CHAPv2 method.

Detailed Description

EAP MS-CHAPv2 authentication method.

EAP-MSCHAPv2 was described in a draft RFC first published in 2002 (draft-kamath-pppext-eap-mschapv2-02.txt). The draft eventually expired in 2007 without becoming an official RFC, quite possibly because the protocol design was too ugly to be called an IETF standard. It is, however, fairly widely used.

Definition in file eap_mschapv2.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ eap_rx_mschapv2_request()

int eap_rx_mschapv2_request ( struct eap_supplicant * supplicant,
const struct eap_mschapv2 * hdr,
size_t len )
static

Handle EAP MS-CHAPv2 request.

Parameters
supplicantEAP supplicant
hdrEAP-MSCHAPv2 header
lenMessage length
Return values
rcReturn status code

Definition at line 89 of file eap_mschapv2.c.

91 {
92 struct net_device *netdev = supplicant->netdev;
94 const struct eap_mschapv2_request *msreq =
96 struct eap_mschapv2_response *msrsp;
98 char *username;
99 char *password;
100 int username_len;
101 int password_len;
102 size_t msrsp_len;
103 unsigned int i;
104 int rc;
105
106 /* Sanity check */
107 if ( len < sizeof ( *msreq ) ) {
108 DBGC ( netdev, "EAP %s underlength MS-CHAPv2 request\n",
109 netdev->name );
110 DBGC_HDA ( netdev, 0, hdr, len );
111 rc = -EINVAL;
112 goto err_sanity;
113 }
114
115 /* Fetch username and password */
116 username_len = fetch_string_setting_copy ( settings, &username_setting,
117 &username );
118 if ( username_len < 0 ) {
119 rc = username_len;
120 DBGC ( netdev, "EAP %s has no username: %s\n",
121 netdev->name, strerror ( rc ) );
122 goto err_username;
123 }
124 password_len = fetch_string_setting_copy ( settings, &password_setting,
125 &password );
126 if ( password_len < 0 ) {
127 rc = password_len;
128 DBGC ( netdev, "EAP %s has no password: %s\n",
129 netdev->name, strerror ( rc ) );
130 goto err_password;
131 }
132
133 /* Construct a peer challenge. We do not perform mutual
134 * authentication, so this does not need to be strong.
135 */
136 for ( i = 0 ; i < ( sizeof ( peer.byte ) /
137 sizeof ( peer.byte[0] ) ) ; i++ ) {
138 peer.byte[i] = random();
139 }
140
141 /* Allocate response */
142 msrsp_len = ( sizeof ( *msrsp ) + username_len );
143 msrsp = malloc ( msrsp_len );
144 if ( ! msrsp ) {
145 rc = -ENOMEM;
146 goto err_alloc;
147 }
148
149 /* Construct response */
150 msrsp->hdr.code = EAP_CODE_RESPONSE;
151 msrsp->hdr.id = msreq->hdr.id;
152 msrsp->hdr.len = htons ( msrsp_len );
153 msrsp->len = sizeof ( msrsp->msg );
155 &msrsp->msg );
156 memcpy ( msrsp->name, username, username_len );
157
158 /* Send response */
159 if ( ( rc = eap_tx_response ( supplicant, msrsp, msrsp_len ) ) != 0 )
160 goto err_tx;
161
162 err_tx:
163 free ( msrsp );
164 err_alloc:
165 free ( password );
166 err_password:
167 free ( username );
168 err_username:
169 err_sanity:
170 return rc;
171}
struct golan_inbox_hdr hdr
Message header.
Definition CIB_PRM.h:0
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
ring len
Length.
Definition dwmac.h:226
int eap_tx_response(struct eap_supplicant *supplicant, const void *rsp, size_t rsp_len)
Transmit EAP response.
Definition eap.c:48
#define EAP_CODE_RESPONSE
EAP response.
Definition eap.h:32
static struct net_device * netdev
Definition gdbudp.c:53
#define DBGC(...)
Definition compiler.h:505
#define DBGC_HDA(...)
Definition compiler.h:506
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENOMEM
Not enough space.
Definition errno.h:535
#define htons(value)
Definition byteswap.h:136
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static struct dynamic_item username
Definition login_ui.c:36
static struct dynamic_item password
Definition login_ui.c:37
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
void mschapv2_response(const char *username, const char *password, const struct mschapv2_challenge *challenge, const struct mschapv2_challenge *peer, struct mschapv2_response *response)
Calculate MS-CHAPv2 challenge response.
Definition mschapv2.c:270
struct mschapv2_challenge peer
Peer challenge.
Definition mschapv2.h:1
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition netdevice.h:587
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition random.c:32
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
int fetch_string_setting_copy(struct settings *settings, const struct setting *setting, char **data)
Fetch value of string setting.
Definition settings.c:874
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
An EAP MS-CHAPv2 request message.
struct eap_mschapv2 hdr
EAP-MSCHAPv2 header.
struct mschapv2_challenge msg
MS-CHAPv2 challenge.
An EAP MS-CHAPv2 response message.
struct eap_mschapv2 hdr
EAP-MSCHAPv2 header.
char name[0]
User name.
struct mschapv2_response msg
MS-CHAPv2 response.
uint8_t len
MS-CHAPv2 response length (fixed value)
uint16_t len
Length.
Definition eap.h:90
uint8_t code
Code.
Definition eap.h:75
uint8_t id
Identifier.
Definition eap.h:82
struct net_device * netdev
Network device.
Definition eap.h:141
An MS-CHAPv2 challenge.
Definition mschapv2.h:16
A network device.
Definition netdevice.h:353
A settings block.
Definition settings.h:133

References eap_mschapv2::code, container_of, DBGC, DBGC_HDA, EAP_CODE_RESPONSE, eap_tx_response(), EINVAL, ENOMEM, fetch_string_setting_copy(), free, eap_mschapv2_request::hdr, eap_mschapv2_response::hdr, hdr, htons, eap_mschapv2::id, eap_mschapv2::len, eap_mschapv2_response::len, len, malloc(), memcpy(), mschapv2_response(), eap_mschapv2_request::msg, eap_mschapv2_response::msg, eap_mschapv2_response::name, eap_supplicant::netdev, netdev, netdev_settings(), password, peer, random(), rc, strerror(), and username.

Referenced by eap_rx_mschapv2().

◆ eap_rx_mschapv2_success()

int eap_rx_mschapv2_success ( struct eap_supplicant * supplicant,
const struct eap_mschapv2 * hdr,
size_t len )
static

Handle EAP MS-CHAPv2 success request.

Parameters
supplicantEAP supplicant
hdrEAP-MSCHAPv2 header
lenMessage length
Return values
rcReturn status code

Definition at line 181 of file eap_mschapv2.c.

183 {
184 const struct eap_mschapv2_success_request *msreq =
186 static const struct eap_mschapv2_success_response msrsp = {
187 .code = EAP_CODE_SUCCESS,
188 };
189
190 /* Sanity check */
191 assert ( len >= sizeof ( *msreq ) );
192
193 /* The success request contains the MS-CHAPv2 authenticator
194 * response, which could potentially be used to verify that
195 * the EAP authenticator also knew the password (or, at least,
196 * the MD4 hash of the password).
197 *
198 * Our model for EAP does not encompass mutual authentication:
199 * we will starting sending plaintext packets (e.g. DHCP
200 * requests) over the link even before EAP completes, and our
201 * only use for an EAP success is to mark the link as
202 * unblocked.
203 *
204 * We therefore ignore the content of the success request and
205 * just send back a success response, so that the EAP
206 * authenticator will complete the process and send through
207 * the real EAP success packet (which will, in turn, cause us
208 * to unblock the link).
209 */
210 return eap_tx_response ( supplicant, &msrsp, sizeof ( msrsp ) );
211}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define EAP_CODE_SUCCESS
EAP success.
Definition eap.h:94
An EAP MS-CHAPv2 success request message.
An EAP MS-CHAPv2 success response message.

References assert, container_of, EAP_CODE_SUCCESS, eap_tx_response(), hdr, and len.

Referenced by eap_rx_mschapv2().

◆ eap_rx_mschapv2()

int eap_rx_mschapv2 ( struct eap_supplicant * supplicant,
const void * req,
size_t req_len )
static

Handle EAP MS-CHAPv2.

Parameters
supplicantEAP supplicant
reqRequest type data
req_lenLength of request type data
Return values
rcReturn status code

Definition at line 221 of file eap_mschapv2.c.

222 {
223 struct net_device *netdev = supplicant->netdev;
224 const struct eap_mschapv2 *hdr = req;
225
226 /* Sanity check */
227 if ( req_len < sizeof ( *hdr ) ) {
228 DBGC ( netdev, "EAP %s underlength MS-CHAPv2:\n",
229 netdev->name );
230 DBGC_HDA ( netdev, 0, req, req_len );
231 return -EINVAL;
232 }
233
234 /* Handle according to opcode */
235 switch ( hdr->code ) {
236 case EAP_CODE_REQUEST:
237 return eap_rx_mschapv2_request ( supplicant, hdr, req_len );
238 case EAP_CODE_SUCCESS:
239 return eap_rx_mschapv2_success ( supplicant, hdr, req_len );
240 default:
241 DBGC ( netdev, "EAP %s unsupported MS-CHAPv2 opcode %d\n",
242 netdev->name, hdr->code );
243 DBGC_HDA ( netdev, 0, req, req_len );
244 return -ENOTSUP;
245 }
246}
#define EAP_CODE_REQUEST
EAP request.
Definition eap.h:29
static int eap_rx_mschapv2_success(struct eap_supplicant *supplicant, const struct eap_mschapv2 *hdr, size_t len)
Handle EAP MS-CHAPv2 success request.
static int eap_rx_mschapv2_request(struct eap_supplicant *supplicant, const struct eap_mschapv2 *hdr, size_t len)
Handle EAP MS-CHAPv2 request.
#define ENOTSUP
Operation not supported.
Definition errno.h:590
EAP MS-CHAPv2 request/response type data.
Definition eap.h:68

References DBGC, DBGC_HDA, EAP_CODE_REQUEST, EAP_CODE_SUCCESS, eap_rx_mschapv2_request(), eap_rx_mschapv2_success(), EINVAL, ENOTSUP, hdr, eap_supplicant::netdev, and netdev.

Variable Documentation

◆ __eap_method

struct eap_method eap_mschapv2_method __eap_method
Initial value:
= {
}
#define EAP_TYPE_MSCHAPV2
EAP MS-CHAPv2 request/response.
Definition eap.h:65
static int eap_rx_mschapv2(struct eap_supplicant *supplicant, const void *req, size_t req_len)
Handle EAP MS-CHAPv2.

EAP MS-CHAPv2 method.

Definition at line 249 of file eap_mschapv2.c.

249 {
250 .type = EAP_TYPE_MSCHAPV2,
251 .rx = eap_rx_mschapv2,
252};