iPXE
Data Structures | Functions | Variables
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)
 
static int eap_rx_mschapv2_request (struct eap_supplicant *supplicant, const struct eap_mschapv2 *hdr, size_t len)
 Handle EAP MS-CHAPv2 request. More...
 
static int eap_rx_mschapv2_success (struct eap_supplicant *supplicant, const struct eap_mschapv2 *hdr, size_t len)
 Handle EAP MS-CHAPv2 success request. More...
 
static int eap_rx_mschapv2 (struct eap_supplicant *supplicant, const void *req, size_t req_len)
 Handle EAP MS-CHAPv2. More...
 

Variables

struct eap_method eap_mschapv2_method __eap_method
 EAP MS-CHAPv2 method. More...
 

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  )

◆ eap_rx_mschapv2_request()

static 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 88 of file eap_mschapv2.c.

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

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

Referenced by eap_rx_mschapv2().

◆ eap_rx_mschapv2_success()

static 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 180 of file eap_mschapv2.c.

182  {
183  const struct eap_mschapv2_success_request *msreq =
185  static const struct eap_mschapv2_success_response msrsp = {
187  };
188 
189  /* Sanity check */
190  assert ( len >= sizeof ( *msreq ) );
191 
192  /* The success request contains the MS-CHAPv2 authenticator
193  * response, which could potentially be used to verify that
194  * the EAP authenticator also knew the password (or, at least,
195  * the MD4 hash of the password).
196  *
197  * Our model for EAP does not encompass mutual authentication:
198  * we will starting sending plaintext packets (e.g. DHCP
199  * requests) over the link even before EAP completes, and our
200  * only use for an EAP success is to mark the link as
201  * unblocked.
202  *
203  * We therefore ignore the content of the success request and
204  * just send back a success response, so that the EAP
205  * authenticator will complete the process and send through
206  * the real EAP success packet (which will, in turn, cause us
207  * to unblock the link).
208  */
209  return eap_tx_response ( supplicant, &msrsp, sizeof ( msrsp ) );
210 }
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
int eap_tx_response(struct eap_supplicant *supplicant, const void *rsp, size_t rsp_len)
Transmit EAP response.
Definition: eap.c:47
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
An EAP MS-CHAPv2 success response message.
Definition: eap_mschapv2.c:75
An EAP MS-CHAPv2 success request message.
Definition: eap_mschapv2.c:67
#define EAP_CODE_SUCCESS
EAP success.
Definition: eap.h:93
uint32_t len
Length.
Definition: ena.h:14

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

Referenced by eap_rx_mschapv2().

◆ eap_rx_mschapv2()

static 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 220 of file eap_mschapv2.c.

221  {
222  struct net_device *netdev = supplicant->netdev;
223  const struct eap_mschapv2 *hdr = req;
224 
225  /* Sanity check */
226  if ( req_len < sizeof ( *hdr ) ) {
227  DBGC ( netdev, "EAP %s underlength MS-CHAPv2:\n",
228  netdev->name );
229  DBGC_HDA ( netdev, 0, req, req_len );
230  return -EINVAL;
231  }
232 
233  /* Handle according to opcode */
234  switch ( hdr->code ) {
235  case EAP_CODE_REQUEST:
236  return eap_rx_mschapv2_request ( supplicant, hdr, req_len );
237  case EAP_CODE_SUCCESS:
238  return eap_rx_mschapv2_success ( supplicant, hdr, req_len );
239  default:
240  DBGC ( netdev, "EAP %s unsupported MS-CHAPv2 opcode %d\n",
241  netdev->name, hdr->code );
242  DBGC_HDA ( netdev, 0, req, req_len );
243  return -ENOTSUP;
244  }
245 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
EAP MS-CHAPv2 request/response type data.
Definition: eap.h:67
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
#define EAP_CODE_REQUEST
EAP request.
Definition: eap.h:28
#define DBGC(...)
Definition: compiler.h:505
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
#define DBGC_HDA(...)
Definition: compiler.h:506
static struct net_device * netdev
Definition: gdbudp.c:52
A network device.
Definition: netdevice.h:352
#define EAP_CODE_SUCCESS
EAP success.
Definition: eap.h:93
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
static int eap_rx_mschapv2_success(struct eap_supplicant *supplicant, const struct eap_mschapv2 *hdr, size_t len)
Handle EAP MS-CHAPv2 success request.
Definition: eap_mschapv2.c:180
struct net_device * netdev
Network device.
Definition: eap.h:140
static int eap_rx_mschapv2_request(struct eap_supplicant *supplicant, const struct eap_mschapv2 *hdr, size_t len)
Handle EAP MS-CHAPv2 request.
Definition: eap_mschapv2.c:88

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

Variable Documentation

◆ __eap_method

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

EAP MS-CHAPv2 method.

Definition at line 248 of file eap_mschapv2.c.