The Pedigree Project  0.1
eap.c
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /*
21  * eap.c - Extensible Authentication Protocol for PPP (RFC 2284)
22  *
23  * Copyright (c) 2001 by Sun Microsystems, Inc.
24  * All rights reserved.
25  *
26  * Non-exclusive rights to redistribute, modify, translate, and use
27  * this software in source and binary forms, in whole or in part, is
28  * hereby granted, provided that the above copyright notice is
29  * duplicated in any source form, and that neither the name of the
30  * copyright holder nor the author is used to endorse or promote
31  * products derived from this software.
32  *
33  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
34  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
35  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
36  *
37  * Original version by James Carlson
38  *
39  * This implementation of EAP supports MD5-Challenge and SRP-SHA1
40  * authentication styles. Note that support of MD5-Challenge is a
41  * requirement of RFC 2284, and that it's essentially just a
42  * reimplementation of regular RFC 1994 CHAP using EAP messages.
43  *
44  * As an authenticator ("server"), there are multiple phases for each
45  * style. In the first phase of each style, the unauthenticated peer
46  * name is queried using the EAP Identity request type. If the
47  * "remotename" option is used, then this phase is skipped, because
48  * the peer's name is presumed to be known.
49  *
50  * For MD5-Challenge, there are two phases, and the second phase
51  * consists of sending the challenge itself and handling the
52  * associated response.
53  *
54  * For SRP-SHA1, there are four phases. The second sends 's', 'N',
55  * and 'g'. The reply contains 'A'. The third sends 'B', and the
56  * reply contains 'M1'. The forth sends the 'M2' value.
57  *
58  * As an authenticatee ("client"), there's just a single phase --
59  * responding to the queries generated by the peer. EAP is an
60  * authenticator-driven protocol.
61  *
62  * Based on draft-ietf-pppext-eap-srp-03.txt.
63  */
64 
65 #include "netif/ppp/ppp_opts.h"
66 #if PPP_SUPPORT && EAP_SUPPORT /* don't build if not configured for use in lwipopts.h */
67 
68 #include "netif/ppp/ppp_impl.h"
69 #include "netif/ppp/eap.h"
70 #include "netif/ppp/magic.h"
71 #include "netif/ppp/pppcrypt.h"
72 
73 #ifdef USE_SRP
74 #include <t_pwd.h>
75 #include <t_server.h>
76 #include <t_client.h>
77 #endif /* USE_SRP */
78 
79 #ifndef SHA_DIGESTSIZE
80 #define SHA_DIGESTSIZE 20
81 #endif
82 
83 #ifdef USE_SRP
84 static char *pn_secret = NULL; /* Pseudonym generating secret */
85 #endif
86 
87 #if PPP_OPTIONS
88 /*
89  * Command-line options.
90  */
91 static option_t eap_option_list[] = {
92  { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout,
93  "Set retransmit timeout for EAP Requests (server)" },
94  { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests,
95  "Set max number of EAP Requests sent (server)" },
96  { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout,
97  "Set time limit for peer EAP authentication" },
98  { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests,
99  "Set max number of EAP Requests allows (client)" },
100  { "eap-interval", o_int, &eap_states[0].es_rechallenge,
101  "Set interval for EAP rechallenge" },
102 #ifdef USE_SRP
103  { "srp-interval", o_int, &eap_states[0].es_lwrechallenge,
104  "Set interval for SRP lightweight rechallenge" },
105  { "srp-pn-secret", o_string, &pn_secret,
106  "Long term pseudonym generation secret" },
107  { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo,
108  "Use pseudonym if offered one by server", 1 },
109 #endif
110  { NULL }
111 };
112 #endif /* PPP_OPTIONS */
113 
114 /*
115  * Protocol entry points.
116  */
117 static void eap_init(ppp_pcb *pcb);
118 static void eap_input(ppp_pcb *pcb, u_char *inp, int inlen);
119 static void eap_protrej(ppp_pcb *pcb);
120 static void eap_lowerup(ppp_pcb *pcb);
121 static void eap_lowerdown(ppp_pcb *pcb);
122 #if PRINTPKT_SUPPORT
123 static int eap_printpkt(const u_char *inp, int inlen,
124  void (*)(void *arg, const char *fmt, ...), void *arg);
125 #endif /* PRINTPKT_SUPPORT */
126 
127 const struct protent eap_protent = {
128  PPP_EAP, /* protocol number */
129  eap_init, /* initialization procedure */
130  eap_input, /* process a received packet */
131  eap_protrej, /* process a received protocol-reject */
132  eap_lowerup, /* lower layer has gone up */
133  eap_lowerdown, /* lower layer has gone down */
134  NULL, /* open the protocol */
135  NULL, /* close the protocol */
136 #if PRINTPKT_SUPPORT
137  eap_printpkt, /* print a packet in readable form */
138 #endif /* PRINTPKT_SUPPORT */
139 #if PPP_DATAINPUT
140  NULL, /* process a received data packet */
141 #endif /* PPP_DATAINPUT */
142 #if PRINTPKT_SUPPORT
143  "EAP", /* text name of protocol */
144  NULL, /* text name of corresponding data protocol */
145 #endif /* PRINTPKT_SUPPORT */
146 #if PPP_OPTIONS
147  eap_option_list, /* list of command-line options */
148  NULL, /* check requested options; assign defaults */
149 #endif /* PPP_OPTIONS */
150 #if DEMAND_SUPPORT
151  NULL, /* configure interface for demand-dial */
152  NULL /* say whether to bring up link for this pkt */
153 #endif /* DEMAND_SUPPORT */
154 };
155 
156 #ifdef USE_SRP
157 /*
158  * A well-known 2048 bit modulus.
159  */
160 static const u_char wkmodulus[] = {
161  0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B,
162  0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F,
163  0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07,
164  0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50,
165  0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED,
166  0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D,
167  0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D,
168  0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50,
169  0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
170  0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3,
171  0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8,
172  0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8,
173  0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA,
174  0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74,
175  0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7,
176  0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B,
177  0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16,
178  0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
179  0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A,
180  0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48,
181  0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D,
182  0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA,
183  0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78,
184  0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6,
185  0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29,
186  0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8,
187  0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
188  0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6,
189  0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4,
190  0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75,
191  0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
192  0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
193 };
194 #endif
195 
196 #if PPP_SERVER
197 /* Local forward declarations. */
198 static void eap_server_timeout(void *arg);
199 #endif /* PPP_SERVER */
200 
201 /*
202  * Convert EAP state code to printable string for debug.
203  */
204 static const char * eap_state_name(enum eap_state_code esc)
205 {
206  static const char *state_names[] = { EAP_STATES };
207 
208  return (state_names[(int)esc]);
209 }
210 
211 /*
212  * eap_init - Initialize state for an EAP user. This is currently
213  * called once by main() during start-up.
214  */
215 static void eap_init(ppp_pcb *pcb) {
216 
217  BZERO(&pcb->eap, sizeof(eap_state));
218 #if PPP_SERVER
219  pcb->eap.es_server.ea_id = magic();
220 #endif /* PPP_SERVER */
221 }
222 
223 /*
224  * eap_client_timeout - Give up waiting for the peer to send any
225  * Request messages.
226  */
227 static void eap_client_timeout(void *arg) {
228  ppp_pcb *pcb = (ppp_pcb*)arg;
229 
230  if (!eap_client_active(pcb))
231  return;
232 
233  ppp_error("EAP: timeout waiting for Request from peer");
234  auth_withpeer_fail(pcb, PPP_EAP);
235  pcb->eap.es_client.ea_state = eapBadAuth;
236 }
237 
238 /*
239  * eap_authwithpeer - Authenticate to our peer (behave as client).
240  *
241  * Start client state and wait for requests. This is called only
242  * after eap_lowerup.
243  */
244 void eap_authwithpeer(ppp_pcb *pcb, const char *localname) {
245 
246  if(NULL == localname)
247  return;
248 
249  /* Save the peer name we're given */
250  pcb->eap.es_client.ea_name = localname;
251  pcb->eap.es_client.ea_namelen = strlen(localname);
252 
253  pcb->eap.es_client.ea_state = eapListen;
254 
255  /*
256  * Start a timer so that if the other end just goes
257  * silent, we don't sit here waiting forever.
258  */
259  if (pcb->settings.eap_req_time > 0)
260  TIMEOUT(eap_client_timeout, pcb,
261  pcb->settings.eap_req_time);
262 }
263 
264 #if PPP_SERVER
265 /*
266  * Format a standard EAP Failure message and send it to the peer.
267  * (Server operation)
268  */
269 static void eap_send_failure(ppp_pcb *pcb) {
270  struct pbuf *p;
271  u_char *outp;
272 
273  p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PPP_CTRL_PBUF_TYPE);
274  if(NULL == p)
275  return;
276  if(p->tot_len != p->len) {
277  pbuf_free(p);
278  return;
279  }
280 
281  outp = (u_char*)p->payload;
282 
283  MAKEHEADER(outp, PPP_EAP);
284 
285  PUTCHAR(EAP_FAILURE, outp);
286  pcb->eap.es_server.ea_id++;
287  PUTCHAR(pcb->eap.es_server.ea_id, outp);
288  PUTSHORT(EAP_HEADERLEN, outp);
289 
290  ppp_write(pcb, p);
291 
292  pcb->eap.es_server.ea_state = eapBadAuth;
293  auth_peer_fail(pcb, PPP_EAP);
294 }
295 
296 /*
297  * Format a standard EAP Success message and send it to the peer.
298  * (Server operation)
299  */
300 static void eap_send_success(ppp_pcb *pcb) {
301  struct pbuf *p;
302  u_char *outp;
303 
304  p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PPP_CTRL_PBUF_TYPE);
305  if(NULL == p)
306  return;
307  if(p->tot_len != p->len) {
308  pbuf_free(p);
309  return;
310  }
311 
312  outp = (u_char*)p->payload;
313 
314  MAKEHEADER(outp, PPP_EAP);
315 
316  PUTCHAR(EAP_SUCCESS, outp);
317  pcb->eap.es_server.ea_id++;
318  PUTCHAR(pcb->eap.es_server.ea_id, outp);
319  PUTSHORT(EAP_HEADERLEN, outp);
320 
321  ppp_write(pcb, p);
322 
323  auth_peer_success(pcb, PPP_EAP, 0,
324  pcb->eap.es_server.ea_peer, pcb->eap.es_server.ea_peerlen);
325 }
326 #endif /* PPP_SERVER */
327 
328 #ifdef USE_SRP
329 /*
330  * Set DES key according to pseudonym-generating secret and current
331  * date.
332  */
333 static bool
334 pncrypt_setkey(int timeoffs)
335 {
336  struct tm *tp;
337  char tbuf[9];
338  SHA1_CTX ctxt;
339  u_char dig[SHA_DIGESTSIZE];
340  time_t reftime;
341 
342  if (pn_secret == NULL)
343  return (0);
344  reftime = time(NULL) + timeoffs;
345  tp = localtime(&reftime);
346  SHA1Init(&ctxt);
347  SHA1Update(&ctxt, pn_secret, strlen(pn_secret));
348  strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
349  SHA1Update(&ctxt, tbuf, strlen(tbuf));
350  SHA1Final(dig, &ctxt);
351  /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */
352  return (DesSetkey(dig));
353 }
354 
355 static char base64[] =
356 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
357 
358 struct b64state {
359  u32_t bs_bits;
360  int bs_offs;
361 };
362 
363 static int
364 b64enc(bs, inp, inlen, outp)
365 struct b64state *bs;
366 u_char *inp;
367 int inlen;
368 u_char *outp;
369 {
370  int outlen = 0;
371 
372  while (inlen > 0) {
373  bs->bs_bits = (bs->bs_bits << 8) | *inp++;
374  inlen--;
375  bs->bs_offs += 8;
376  if (bs->bs_offs >= 24) {
377  *outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
378  *outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
379  *outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
380  *outp++ = base64[bs->bs_bits & 0x3F];
381  outlen += 4;
382  bs->bs_offs = 0;
383  bs->bs_bits = 0;
384  }
385  }
386  return (outlen);
387 }
388 
389 static int
390 b64flush(bs, outp)
391 struct b64state *bs;
392 u_char *outp;
393 {
394  int outlen = 0;
395 
396  if (bs->bs_offs == 8) {
397  *outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
398  *outp++ = base64[(bs->bs_bits << 4) & 0x3F];
399  outlen = 2;
400  } else if (bs->bs_offs == 16) {
401  *outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
402  *outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
403  *outp++ = base64[(bs->bs_bits << 2) & 0x3F];
404  outlen = 3;
405  }
406  bs->bs_offs = 0;
407  bs->bs_bits = 0;
408  return (outlen);
409 }
410 
411 static int
412 b64dec(bs, inp, inlen, outp)
413 struct b64state *bs;
414 u_char *inp;
415 int inlen;
416 u_char *outp;
417 {
418  int outlen = 0;
419  char *cp;
420 
421  while (inlen > 0) {
422  if ((cp = strchr(base64, *inp++)) == NULL)
423  break;
424  bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
425  inlen--;
426  bs->bs_offs += 6;
427  if (bs->bs_offs >= 8) {
428  *outp++ = bs->bs_bits >> (bs->bs_offs - 8);
429  outlen++;
430  bs->bs_offs -= 8;
431  }
432  }
433  return (outlen);
434 }
435 #endif /* USE_SRP */
436 
437 #if PPP_SERVER
438 /*
439  * Assume that current waiting server state is complete and figure
440  * next state to use based on available authentication data. 'status'
441  * indicates if there was an error in handling the last query. It is
442  * 0 for success and non-zero for failure.
443  */
444 static void eap_figure_next_state(ppp_pcb *pcb, int status) {
445 #ifdef USE_SRP
446  unsigned char secbuf[MAXSECRETLEN], clear[8], *sp, *dp;
447  struct t_pw tpw;
448  struct t_confent *tce, mytce;
449  char *cp, *cp2;
450  struct t_server *ts;
451  int id, i, plen, toffs;
452  u_char vals[2];
453  struct b64state bs;
454 #endif /* USE_SRP */
455 
456  pcb->settings.eap_timeout_time = pcb->eap.es_savedtime;
457  switch (pcb->eap.es_server.ea_state) {
458  case eapBadAuth:
459  return;
460 
461  case eapIdentify:
462 #ifdef USE_SRP
463  /* Discard any previous session. */
464  ts = (struct t_server *)pcb->eap.es_server.ea_session;
465  if (ts != NULL) {
466  t_serverclose(ts);
467  pcb->eap.es_server.ea_session = NULL;
468  pcb->eap.es_server.ea_skey = NULL;
469  }
470 #endif /* USE_SRP */
471  if (status != 0) {
472  pcb->eap.es_server.ea_state = eapBadAuth;
473  break;
474  }
475 #ifdef USE_SRP
476  /* If we've got a pseudonym, try to decode to real name. */
477  if (pcb->eap.es_server.ea_peerlen > SRP_PSEUDO_LEN &&
478  strncmp(pcb->eap.es_server.ea_peer, SRP_PSEUDO_ID,
479  SRP_PSEUDO_LEN) == 0 &&
480  (pcb->eap.es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
481  sizeof (secbuf)) {
482  BZERO(&bs, sizeof (bs));
483  plen = b64dec(&bs,
484  pcb->eap.es_server.ea_peer + SRP_PSEUDO_LEN,
485  pcb->eap.es_server.ea_peerlen - SRP_PSEUDO_LEN,
486  secbuf);
487  toffs = 0;
488  for (i = 0; i < 5; i++) {
489  pncrypt_setkey(toffs);
490  toffs -= 86400;
491  /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */
492  if (!DesDecrypt(secbuf, clear)) {
493  ppp_dbglog("no DES here; cannot decode "
494  "pseudonym");
495  return;
496  }
497  id = *(unsigned char *)clear;
498  if (id + 1 <= plen && id + 9 > plen)
499  break;
500  }
501  if (plen % 8 == 0 && i < 5) {
502  /*
503  * Note that this is always shorter than the
504  * original stored string, so there's no need
505  * to realloc.
506  */
507  if ((i = plen = *(unsigned char *)clear) > 7)
508  i = 7;
509  pcb->eap.es_server.ea_peerlen = plen;
510  dp = (unsigned char *)pcb->eap.es_server.ea_peer;
511  MEMCPY(dp, clear + 1, i);
512  plen -= i;
513  dp += i;
514  sp = secbuf + 8;
515  while (plen > 0) {
516  /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */
517  (void) DesDecrypt(sp, dp);
518  sp += 8;
519  dp += 8;
520  plen -= 8;
521  }
522  pcb->eap.es_server.ea_peer[
523  pcb->eap.es_server.ea_peerlen] = '\0';
524  ppp_dbglog("decoded pseudonym to \"%.*q\"",
525  pcb->eap.es_server.ea_peerlen,
526  pcb->eap.es_server.ea_peer);
527  } else {
528  ppp_dbglog("failed to decode real name");
529  /* Stay in eapIdentfy state; requery */
530  break;
531  }
532  }
533  /* Look up user in secrets database. */
534  if (get_srp_secret(pcb->eap.es_unit, pcb->eap.es_server.ea_peer,
535  pcb->eap.es_server.ea_name, (char *)secbuf, 1) != 0) {
536  /* Set up default in case SRP entry is bad */
537  pcb->eap.es_server.ea_state = eapMD5Chall;
538  /* Get t_confent based on index in srp-secrets */
539  id = strtol((char *)secbuf, &cp, 10);
540  if (*cp++ != ':' || id < 0)
541  break;
542  if (id == 0) {
543  mytce.index = 0;
544  mytce.modulus.data = (u_char *)wkmodulus;
545  mytce.modulus.len = sizeof (wkmodulus);
546  mytce.generator.data = (u_char *)"\002";
547  mytce.generator.len = 1;
548  tce = &mytce;
549  } else if ((tce = gettcid(id)) != NULL) {
550  /*
551  * Client will have to verify this modulus/
552  * generator combination, and that will take
553  * a while. Lengthen the timeout here.
554  */
555  if (pcb->settings.eap_timeout_time > 0 &&
556  pcb->settings.eap_timeout_time < 30)
557  pcb->settings.eap_timeout_time = 30;
558  } else {
559  break;
560  }
561  if ((cp2 = strchr(cp, ':')) == NULL)
562  break;
563  *cp2++ = '\0';
564  tpw.pebuf.name = pcb->eap.es_server.ea_peer;
565  tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
566  cp);
567  tpw.pebuf.password.data = tpw.pwbuf;
568  tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
569  cp2);
570  tpw.pebuf.salt.data = tpw.saltbuf;
571  if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
572  break;
573  pcb->eap.es_server.ea_session = (void *)ts;
574  pcb->eap.es_server.ea_state = eapSRP1;
575  vals[0] = pcb->eap.es_server.ea_id + 1;
576  vals[1] = EAPT_SRP;
577  t_serveraddexdata(ts, vals, 2);
578  /* Generate B; must call before t_servergetkey() */
579  t_servergenexp(ts);
580  break;
581  }
582 #endif /* USE_SRP */
583  pcb->eap.es_server.ea_state = eapMD5Chall;
584  break;
585 
586  case eapSRP1:
587 #ifdef USE_SRP
588  ts = (struct t_server *)pcb->eap.es_server.ea_session;
589  if (ts != NULL && status != 0) {
590  t_serverclose(ts);
591  pcb->eap.es_server.ea_session = NULL;
592  pcb->eap.es_server.ea_skey = NULL;
593  }
594 #endif /* USE_SRP */
595  if (status == 1) {
596  pcb->eap.es_server.ea_state = eapMD5Chall;
597  } else if (status != 0 || pcb->eap.es_server.ea_session == NULL) {
598  pcb->eap.es_server.ea_state = eapBadAuth;
599  } else {
600  pcb->eap.es_server.ea_state = eapSRP2;
601  }
602  break;
603 
604  case eapSRP2:
605 #ifdef USE_SRP
606  ts = (struct t_server *)pcb->eap.es_server.ea_session;
607  if (ts != NULL && status != 0) {
608  t_serverclose(ts);
609  pcb->eap.es_server.ea_session = NULL;
610  pcb->eap.es_server.ea_skey = NULL;
611  }
612 #endif /* USE_SRP */
613  if (status != 0 || pcb->eap.es_server.ea_session == NULL) {
614  pcb->eap.es_server.ea_state = eapBadAuth;
615  } else {
616  pcb->eap.es_server.ea_state = eapSRP3;
617  }
618  break;
619 
620  case eapSRP3:
621  case eapSRP4:
622 #ifdef USE_SRP
623  ts = (struct t_server *)pcb->eap.es_server.ea_session;
624  if (ts != NULL && status != 0) {
625  t_serverclose(ts);
626  pcb->eap.es_server.ea_session = NULL;
627  pcb->eap.es_server.ea_skey = NULL;
628  }
629 #endif /* USE_SRP */
630  if (status != 0 || pcb->eap.es_server.ea_session == NULL) {
631  pcb->eap.es_server.ea_state = eapBadAuth;
632  } else {
633  pcb->eap.es_server.ea_state = eapOpen;
634  }
635  break;
636 
637  case eapMD5Chall:
638  if (status != 0) {
639  pcb->eap.es_server.ea_state = eapBadAuth;
640  } else {
641  pcb->eap.es_server.ea_state = eapOpen;
642  }
643  break;
644 
645  default:
646  pcb->eap.es_server.ea_state = eapBadAuth;
647  break;
648  }
649  if (pcb->eap.es_server.ea_state == eapBadAuth)
650  eap_send_failure(pcb);
651 }
652 
653 /*
654  * Format an EAP Request message and send it to the peer. Message
655  * type depends on current state. (Server operation)
656  */
657 static void eap_send_request(ppp_pcb *pcb) {
658  struct pbuf *p;
659  u_char *outp;
660  u_char *lenloc;
661  int outlen;
662  int len;
663  const char *str;
664 #ifdef USE_SRP
665  struct t_server *ts;
666  u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;
667  int i, j;
668  struct b64state b64;
669  SHA1_CTX ctxt;
670 #endif /* USE_SRP */
671 
672  /* Handle both initial auth and restart */
673  if (pcb->eap.es_server.ea_state < eapIdentify &&
674  pcb->eap.es_server.ea_state != eapInitial) {
675  pcb->eap.es_server.ea_state = eapIdentify;
676 #if PPP_REMOTENAME
677  if (pcb->settings.explicit_remote && pcb->remote_name) {
678  /*
679  * If we already know the peer's
680  * unauthenticated name, then there's no
681  * reason to ask. Go to next state instead.
682  */
683  int len = (int)strlen(pcb->remote_name);
684  if (len > MAXNAMELEN) {
685  len = MAXNAMELEN;
686  }
687  MEMCPY(pcb->eap.es_server.ea_peer, pcb->remote_name, len);
688  pcb->eap.es_server.ea_peer[len] = '\0';
689  pcb->eap.es_server.ea_peerlen = len;
690  eap_figure_next_state(pcb, 0);
691  }
692 #endif /* PPP_REMOTENAME */
693  }
694 
695  if (pcb->settings.eap_max_transmits > 0 &&
696  pcb->eap.es_server.ea_requests >= pcb->settings.eap_max_transmits) {
697  if (pcb->eap.es_server.ea_responses > 0)
698  ppp_error("EAP: too many Requests sent");
699  else
700  ppp_error("EAP: no response to Requests");
701  eap_send_failure(pcb);
702  return;
703  }
704 
705  p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_CTRL_PBUF_MAX_SIZE), PPP_CTRL_PBUF_TYPE);
706  if(NULL == p)
707  return;
708  if(p->tot_len != p->len) {
709  pbuf_free(p);
710  return;
711  }
712 
713  outp = (u_char*)p->payload;
714 
715  MAKEHEADER(outp, PPP_EAP);
716 
717  PUTCHAR(EAP_REQUEST, outp);
718  PUTCHAR(pcb->eap.es_server.ea_id, outp);
719  lenloc = outp;
720  INCPTR(2, outp);
721 
722  switch (pcb->eap.es_server.ea_state) {
723  case eapIdentify:
724  PUTCHAR(EAPT_IDENTITY, outp);
725  str = "Name";
726  len = strlen(str);
727  MEMCPY(outp, str, len);
728  INCPTR(len, outp);
729  break;
730 
731  case eapMD5Chall:
732  PUTCHAR(EAPT_MD5CHAP, outp);
733  /*
734  * pick a random challenge length between
735  * EAP_MIN_CHALLENGE_LENGTH and EAP_MAX_CHALLENGE_LENGTH
736  */
737  pcb->eap.es_challen = EAP_MIN_CHALLENGE_LENGTH +
738  magic_pow(EAP_MIN_MAX_POWER_OF_TWO_CHALLENGE_LENGTH);
739  PUTCHAR(pcb->eap.es_challen, outp);
740  magic_random_bytes(pcb->eap.es_challenge, pcb->eap.es_challen);
741  MEMCPY(outp, pcb->eap.es_challenge, pcb->eap.es_challen);
742  INCPTR(pcb->eap.es_challen, outp);
743  MEMCPY(outp, pcb->eap.es_server.ea_name, pcb->eap.es_server.ea_namelen);
744  INCPTR(pcb->eap.es_server.ea_namelen, outp);
745  break;
746 
747 #ifdef USE_SRP
748  case eapSRP1:
749  PUTCHAR(EAPT_SRP, outp);
750  PUTCHAR(EAPSRP_CHALLENGE, outp);
751 
752  PUTCHAR(pcb->eap.es_server.ea_namelen, outp);
753  MEMCPY(outp, pcb->eap.es_server.ea_name, pcb->eap.es_server.ea_namelen);
754  INCPTR(pcb->eap.es_server.ea_namelen, outp);
755 
756  ts = (struct t_server *)pcb->eap.es_server.ea_session;
757  assert(ts != NULL);
758  PUTCHAR(ts->s.len, outp);
759  MEMCPY(outp, ts->s.data, ts->s.len);
760  INCPTR(ts->s.len, outp);
761 
762  if (ts->g.len == 1 && ts->g.data[0] == 2) {
763  PUTCHAR(0, outp);
764  } else {
765  PUTCHAR(ts->g.len, outp);
766  MEMCPY(outp, ts->g.data, ts->g.len);
767  INCPTR(ts->g.len, outp);
768  }
769 
770  if (ts->n.len != sizeof (wkmodulus) ||
771  BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
772  MEMCPY(outp, ts->n.data, ts->n.len);
773  INCPTR(ts->n.len, outp);
774  }
775  break;
776 
777  case eapSRP2:
778  PUTCHAR(EAPT_SRP, outp);
779  PUTCHAR(EAPSRP_SKEY, outp);
780 
781  ts = (struct t_server *)pcb->eap.es_server.ea_session;
782  assert(ts != NULL);
783  MEMCPY(outp, ts->B.data, ts->B.len);
784  INCPTR(ts->B.len, outp);
785  break;
786 
787  case eapSRP3:
788  PUTCHAR(EAPT_SRP, outp);
789  PUTCHAR(EAPSRP_SVALIDATOR, outp);
790  PUTLONG(SRPVAL_EBIT, outp);
791  ts = (struct t_server *)pcb->eap.es_server.ea_session;
792  assert(ts != NULL);
793  MEMCPY(outp, t_serverresponse(ts), SHA_DIGESTSIZE);
794  INCPTR(SHA_DIGESTSIZE, outp);
795 
796  if (pncrypt_setkey(0)) {
797  /* Generate pseudonym */
798  optr = outp;
799  cp = (unsigned char *)pcb->eap.es_server.ea_peer;
800  if ((j = i = pcb->eap.es_server.ea_peerlen) > 7)
801  j = 7;
802  clear[0] = i;
803  MEMCPY(clear + 1, cp, j);
804  i -= j;
805  cp += j;
806  /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */
807  if (!DesEncrypt(clear, cipher)) {
808  ppp_dbglog("no DES here; not generating pseudonym");
809  break;
810  }
811  BZERO(&b64, sizeof (b64));
812  outp++; /* space for pseudonym length */
813  outp += b64enc(&b64, cipher, 8, outp);
814  while (i >= 8) {
815  /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */
816  (void) DesEncrypt(cp, cipher);
817  outp += b64enc(&b64, cipher, 8, outp);
818  cp += 8;
819  i -= 8;
820  }
821  if (i > 0) {
822  MEMCPY(clear, cp, i);
823  cp += i;
824  magic_random_bytes(cp, 8-i);
825  /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */
826  (void) DesEncrypt(clear, cipher);
827  outp += b64enc(&b64, cipher, 8, outp);
828  }
829  outp += b64flush(&b64, outp);
830 
831  /* Set length and pad out to next 20 octet boundary */
832  i = outp - optr - 1;
833  *optr = i;
834  i %= SHA_DIGESTSIZE;
835  if (i != 0) {
836  magic_random_bytes(outp, SHA_DIGESTSIZE-i);
837  INCPTR(SHA_DIGESTSIZE-i, outp);
838  }
839 
840  /* Obscure the pseudonym with SHA1 hash */
841  SHA1Init(&ctxt);
842  SHA1Update(&ctxt, &pcb->eap.es_server.ea_id, 1);
843  SHA1Update(&ctxt, pcb->eap.es_server.ea_skey,
844  SESSION_KEY_LEN);
845  SHA1Update(&ctxt, pcb->eap.es_server.ea_peer,
846  pcb->eap.es_server.ea_peerlen);
847  while (optr < outp) {
848  SHA1Final(dig, &ctxt);
849  cp = dig;
850  while (cp < dig + SHA_DIGESTSIZE)
851  *optr++ ^= *cp++;
852  SHA1Init(&ctxt);
853  SHA1Update(&ctxt, &pcb->eap.es_server.ea_id, 1);
854  SHA1Update(&ctxt, pcb->eap.es_server.ea_skey,
855  SESSION_KEY_LEN);
856  SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,
857  SHA_DIGESTSIZE);
858  }
859  }
860  break;
861 
862  case eapSRP4:
863  PUTCHAR(EAPT_SRP, outp);
864  PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
865  pcb->eap.es_challen = EAP_MIN_CHALLENGE_LENGTH +
866  magic_pow(EAP_MIN_MAX_POWER_OF_TWO_CHALLENGE_LENGTH);
867  magic_random_bytes(pcb->eap.es_challenge, pcb->eap.es_challen);
868  MEMCPY(outp, pcb->eap.es_challenge, pcb->eap.es_challen);
869  INCPTR(pcb->eap.es_challen, outp);
870  break;
871 #endif /* USE_SRP */
872 
873  default:
874  return;
875  }
876 
877  outlen = (outp - (unsigned char*)p->payload) - PPP_HDRLEN;
878  PUTSHORT(outlen, lenloc);
879 
880  pbuf_realloc(p, outlen + PPP_HDRLEN);
881  ppp_write(pcb, p);
882 
883  pcb->eap.es_server.ea_requests++;
884 
885  if (pcb->settings.eap_timeout_time > 0)
886  TIMEOUT(eap_server_timeout, pcb, pcb->settings.eap_timeout_time);
887 }
888 
889 /*
890  * eap_authpeer - Authenticate our peer (behave as server).
891  *
892  * Start server state and send first request. This is called only
893  * after eap_lowerup.
894  */
895 void eap_authpeer(ppp_pcb *pcb, const char *localname) {
896 
897  /* Save the name we're given. */
898  pcb->eap.es_server.ea_name = localname;
899  pcb->eap.es_server.ea_namelen = strlen(localname);
900 
901  pcb->eap.es_savedtime = pcb->settings.eap_timeout_time;
902 
903  /* Lower layer up yet? */
904  if (pcb->eap.es_server.ea_state == eapInitial ||
905  pcb->eap.es_server.ea_state == eapPending) {
906  pcb->eap.es_server.ea_state = eapPending;
907  return;
908  }
909 
910  pcb->eap.es_server.ea_state = eapPending;
911 
912  /* ID number not updated here intentionally; hashed into M1 */
913  eap_send_request(pcb);
914 }
915 
916 /*
917  * eap_server_timeout - Retransmission timer for sending Requests
918  * expired.
919  */
920 static void eap_server_timeout(void *arg) {
921  ppp_pcb *pcb = (ppp_pcb*)arg;
922 
923  if (!eap_server_active(pcb))
924  return;
925 
926  /* EAP ID number must not change on timeout. */
927  eap_send_request(pcb);
928 }
929 
930 /*
931  * When it's time to send rechallenge the peer, this timeout is
932  * called. Once the rechallenge is successful, the response handler
933  * will restart the timer. If it fails, then the link is dropped.
934  */
935 static void eap_rechallenge(void *arg) {
936  ppp_pcb *pcb = (ppp_pcb*)arg;
937 
938  if (pcb->eap.es_server.ea_state != eapOpen &&
939  pcb->eap.es_server.ea_state != eapSRP4)
940  return;
941 
942  pcb->eap.es_server.ea_requests = 0;
943  pcb->eap.es_server.ea_state = eapIdentify;
944  eap_figure_next_state(pcb, 0);
945  pcb->eap.es_server.ea_id++;
946  eap_send_request(pcb);
947 }
948 
949 static void srp_lwrechallenge(void *arg) {
950  ppp_pcb *pcb = (ppp_pcb*)arg;
951 
952  if (pcb->eap.es_server.ea_state != eapOpen ||
953  pcb->eap.es_server.ea_type != EAPT_SRP)
954  return;
955 
956  pcb->eap.es_server.ea_requests = 0;
957  pcb->eap.es_server.ea_state = eapSRP4;
958  pcb->eap.es_server.ea_id++;
959  eap_send_request(pcb);
960 }
961 #endif /* PPP_SERVER */
962 
963 /*
964  * eap_lowerup - The lower layer is now up.
965  *
966  * This is called before either eap_authpeer or eap_authwithpeer. See
967  * link_established() in auth.c. All that's necessary here is to
968  * return to closed state so that those two routines will do the right
969  * thing.
970  */
971 static void eap_lowerup(ppp_pcb *pcb) {
972  pcb->eap.es_client.ea_state = eapClosed;
973 #if PPP_SERVER
974  pcb->eap.es_server.ea_state = eapClosed;
975 #endif /* PPP_SERVER */
976 }
977 
978 /*
979  * eap_lowerdown - The lower layer is now down.
980  *
981  * Cancel all timeouts and return to initial state.
982  */
983 static void eap_lowerdown(ppp_pcb *pcb) {
984 
985  if (eap_client_active(pcb) && pcb->settings.eap_req_time > 0) {
986  UNTIMEOUT(eap_client_timeout, pcb);
987  }
988 #if PPP_SERVER
989  if (eap_server_active(pcb)) {
990  if (pcb->settings.eap_timeout_time > 0) {
991  UNTIMEOUT(eap_server_timeout, pcb);
992  }
993  } else {
994  if ((pcb->eap.es_server.ea_state == eapOpen ||
995  pcb->eap.es_server.ea_state == eapSRP4) &&
996  pcb->eap.es_rechallenge > 0) {
997  UNTIMEOUT(eap_rechallenge, (void *)pcb);
998  }
999  if (pcb->eap.es_server.ea_state == eapOpen &&
1000  pcb->eap.es_lwrechallenge > 0) {
1001  UNTIMEOUT(srp_lwrechallenge, (void *)pcb);
1002  }
1003  }
1004 
1005  pcb->eap.es_client.ea_state = pcb->eap.es_server.ea_state = eapInitial;
1006  pcb->eap.es_client.ea_requests = pcb->eap.es_server.ea_requests = 0;
1007 #endif /* PPP_SERVER */
1008 }
1009 
1010 /*
1011  * eap_protrej - Peer doesn't speak this protocol.
1012  *
1013  * This shouldn't happen. If it does, it represents authentication
1014  * failure.
1015  */
1016 static void eap_protrej(ppp_pcb *pcb) {
1017 
1018  if (eap_client_active(pcb)) {
1019  ppp_error("EAP authentication failed due to Protocol-Reject");
1020  auth_withpeer_fail(pcb, PPP_EAP);
1021  }
1022 #if PPP_SERVER
1023  if (eap_server_active(pcb)) {
1024  ppp_error("EAP authentication of peer failed on Protocol-Reject");
1025  auth_peer_fail(pcb, PPP_EAP);
1026  }
1027 #endif /* PPP_SERVER */
1028  eap_lowerdown(pcb);
1029 }
1030 
1031 /*
1032  * Format and send a regular EAP Response message.
1033  */
1034 static void eap_send_response(ppp_pcb *pcb, u_char id, u_char typenum, const u_char *str, int lenstr) {
1035  struct pbuf *p;
1036  u_char *outp;
1037  int msglen;
1038 
1039  msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr;
1040  p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE);
1041  if(NULL == p)
1042  return;
1043  if(p->tot_len != p->len) {
1044  pbuf_free(p);
1045  return;
1046  }
1047 
1048  outp = (u_char*)p->payload;
1049 
1050  MAKEHEADER(outp, PPP_EAP);
1051 
1052  PUTCHAR(EAP_RESPONSE, outp);
1053  PUTCHAR(id, outp);
1054  pcb->eap.es_client.ea_id = id;
1055  PUTSHORT(msglen, outp);
1056  PUTCHAR(typenum, outp);
1057  if (lenstr > 0) {
1058  MEMCPY(outp, str, lenstr);
1059  }
1060 
1061  ppp_write(pcb, p);
1062 }
1063 
1064 /*
1065  * Format and send an MD5-Challenge EAP Response message.
1066  */
1067 static void eap_chap_response(ppp_pcb *pcb, u_char id, u_char *hash, const char *name, int namelen) {
1068  struct pbuf *p;
1069  u_char *outp;
1070  int msglen;
1071 
1072  msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE +
1073  namelen;
1074  p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE);
1075  if(NULL == p)
1076  return;
1077  if(p->tot_len != p->len) {
1078  pbuf_free(p);
1079  return;
1080  }
1081 
1082  outp = (u_char*)p->payload;
1083 
1084  MAKEHEADER(outp, PPP_EAP);
1085 
1086  PUTCHAR(EAP_RESPONSE, outp);
1087  PUTCHAR(id, outp);
1088  pcb->eap.es_client.ea_id = id;
1089  PUTSHORT(msglen, outp);
1090  PUTCHAR(EAPT_MD5CHAP, outp);
1091  PUTCHAR(MD5_SIGNATURE_SIZE, outp);
1092  MEMCPY(outp, hash, MD5_SIGNATURE_SIZE);
1093  INCPTR(MD5_SIGNATURE_SIZE, outp);
1094  if (namelen > 0) {
1095  MEMCPY(outp, name, namelen);
1096  }
1097 
1098  ppp_write(pcb, p);
1099 }
1100 
1101 #ifdef USE_SRP
1102 /*
1103  * Format and send a SRP EAP Response message.
1104  */
1105 static void
1106 eap_srp_response(esp, id, subtypenum, str, lenstr)
1107 eap_state *esp;
1108 u_char id;
1109 u_char subtypenum;
1110 u_char *str;
1111 int lenstr;
1112 {
1113  ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit];
1114  struct pbuf *p;
1115  u_char *outp;
1116  int msglen;
1117 
1118  msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr;
1119  p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE);
1120  if(NULL == p)
1121  return;
1122  if(p->tot_len != p->len) {
1123  pbuf_free(p);
1124  return;
1125  }
1126 
1127  outp = p->payload;
1128 
1129  MAKEHEADER(outp, PPP_EAP);
1130 
1131  PUTCHAR(EAP_RESPONSE, outp);
1132  PUTCHAR(id, outp);
1133  pcb->eap.es_client.ea_id = id;
1134  PUTSHORT(msglen, outp);
1135  PUTCHAR(EAPT_SRP, outp);
1136  PUTCHAR(subtypenum, outp);
1137  if (lenstr > 0) {
1138  MEMCPY(outp, str, lenstr);
1139  }
1140 
1141  ppp_write(pcb, p);
1142 }
1143 
1144 /*
1145  * Format and send a SRP EAP Client Validator Response message.
1146  */
1147 static void
1148 eap_srpval_response(esp, id, flags, str)
1149 eap_state *esp;
1150 u_char id;
1151 u32_t flags;
1152 u_char *str;
1153 {
1154  ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit];
1155  struct pbuf *p;
1156  u_char *outp;
1157  int msglen;
1158 
1159  msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u32_t) +
1160  SHA_DIGESTSIZE;
1161  p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE);
1162  if(NULL == p)
1163  return;
1164  if(p->tot_len != p->len) {
1165  pbuf_free(p);
1166  return;
1167  }
1168 
1169  outp = p->payload;
1170 
1171  MAKEHEADER(outp, PPP_EAP);
1172 
1173  PUTCHAR(EAP_RESPONSE, outp);
1174  PUTCHAR(id, outp);
1175  pcb->eap.es_client.ea_id = id;
1176  PUTSHORT(msglen, outp);
1177  PUTCHAR(EAPT_SRP, outp);
1178  PUTCHAR(EAPSRP_CVALIDATOR, outp);
1179  PUTLONG(flags, outp);
1180  MEMCPY(outp, str, SHA_DIGESTSIZE);
1181 
1182  ppp_write(pcb, p);
1183 }
1184 #endif /* USE_SRP */
1185 
1186 static void eap_send_nak(ppp_pcb *pcb, u_char id, u_char type) {
1187  struct pbuf *p;
1188  u_char *outp;
1189  int msglen;
1190 
1191  msglen = EAP_HEADERLEN + 2 * sizeof (u_char);
1192  p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE);
1193  if(NULL == p)
1194  return;
1195  if(p->tot_len != p->len) {
1196  pbuf_free(p);
1197  return;
1198  }
1199 
1200  outp = (u_char*)p->payload;
1201 
1202  MAKEHEADER(outp, PPP_EAP);
1203 
1204  PUTCHAR(EAP_RESPONSE, outp);
1205  PUTCHAR(id, outp);
1206  pcb->eap.es_client.ea_id = id;
1207  PUTSHORT(msglen, outp);
1208  PUTCHAR(EAPT_NAK, outp);
1209  PUTCHAR(type, outp);
1210 
1211  ppp_write(pcb, p);
1212 }
1213 
1214 #ifdef USE_SRP
1215 static char *
1216 name_of_pn_file()
1217 {
1218  char *user, *path, *file;
1219  struct passwd *pw;
1220  size_t pl;
1221  static bool pnlogged = 0;
1222 
1223  pw = getpwuid(getuid());
1224  if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
1225  errno = EINVAL;
1226  return (NULL);
1227  }
1228  file = _PATH_PSEUDONYM;
1229  pl = strlen(user) + strlen(file) + 2;
1230  path = malloc(pl);
1231  if (path == NULL)
1232  return (NULL);
1233  (void) slprintf(path, pl, "%s/%s", user, file);
1234  if (!pnlogged) {
1235  ppp_dbglog("pseudonym file: %s", path);
1236  pnlogged = 1;
1237  }
1238  return (path);
1239 }
1240 
1241 static int
1242 open_pn_file(modebits)
1243 mode_t modebits;
1244 {
1245  char *path;
1246  int fd, err;
1247 
1248  if ((path = name_of_pn_file()) == NULL)
1249  return (-1);
1250  fd = open(path, modebits, S_IRUSR | S_IWUSR);
1251  err = errno;
1252  free(path);
1253  errno = err;
1254  return (fd);
1255 }
1256 
1257 static void
1258 remove_pn_file()
1259 {
1260  char *path;
1261 
1262  if ((path = name_of_pn_file()) != NULL) {
1263  (void) unlink(path);
1264  (void) free(path);
1265  }
1266 }
1267 
1268 static void
1269 write_pseudonym(esp, inp, len, id)
1270 eap_state *esp;
1271 u_char *inp;
1272 int len, id;
1273 {
1274  u_char val;
1275  u_char *datp, *digp;
1276  SHA1_CTX ctxt;
1277  u_char dig[SHA_DIGESTSIZE];
1278  int dsize, fd, olen = len;
1279 
1280  /*
1281  * Do the decoding by working backwards. This eliminates the need
1282  * to save the decoded output in a separate buffer.
1283  */
1284  val = id;
1285  while (len > 0) {
1286  if ((dsize = len % SHA_DIGESTSIZE) == 0)
1287  dsize = SHA_DIGESTSIZE;
1288  len -= dsize;
1289  datp = inp + len;
1290  SHA1Init(&ctxt);
1291  SHA1Update(&ctxt, &val, 1);
1292  SHA1Update(&ctxt, pcb->eap.es_client.ea_skey, SESSION_KEY_LEN);
1293  if (len > 0) {
1294  SHA1Update(&ctxt, datp, SHA_DIGESTSIZE);
1295  } else {
1296  SHA1Update(&ctxt, pcb->eap.es_client.ea_name,
1297  pcb->eap.es_client.ea_namelen);
1298  }
1299  SHA1Final(dig, &ctxt);
1300  for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++)
1301  *datp++ ^= *digp;
1302  }
1303 
1304  /* Now check that the result is sane */
1305  if (olen <= 0 || *inp + 1 > olen) {
1306  ppp_dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp);
1307  return;
1308  }
1309 
1310  /* Save it away */
1311  fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
1312  if (fd < 0) {
1313  ppp_dbglog("EAP: error saving pseudonym: %m");
1314  return;
1315  }
1316  len = write(fd, inp + 1, *inp);
1317  if (close(fd) != -1 && len == *inp) {
1318  ppp_dbglog("EAP: saved pseudonym");
1319  pcb->eap.es_usedpseudo = 0;
1320  } else {
1321  ppp_dbglog("EAP: failed to save pseudonym");
1322  remove_pn_file();
1323  }
1324 }
1325 #endif /* USE_SRP */
1326 
1327 /*
1328  * eap_request - Receive EAP Request message (client mode).
1329  */
1330 static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) {
1331  u_char typenum;
1332  u_char vallen;
1333  int secret_len;
1334  char secret[MAXSECRETLEN];
1335  char rhostname[MAXNAMELEN];
1336  lwip_md5_context mdContext;
1337  u_char hash[MD5_SIGNATURE_SIZE];
1338 #ifdef USE_SRP
1339  struct t_client *tc;
1340  struct t_num sval, gval, Nval, *Ap, Bval;
1341  u_char vals[2];
1342  SHA1_CTX ctxt;
1343  u_char dig[SHA_DIGESTSIZE];
1344  int fd;
1345 #endif /* USE_SRP */
1346 
1347  /*
1348  * Note: we update es_client.ea_id *only if* a Response
1349  * message is being generated. Otherwise, we leave it the
1350  * same for duplicate detection purposes.
1351  */
1352 
1353  pcb->eap.es_client.ea_requests++;
1354  if (pcb->settings.eap_allow_req != 0 &&
1355  pcb->eap.es_client.ea_requests > pcb->settings.eap_allow_req) {
1356  ppp_info("EAP: received too many Request messages");
1357  if (pcb->settings.eap_req_time > 0) {
1358  UNTIMEOUT(eap_client_timeout, pcb);
1359  }
1360  auth_withpeer_fail(pcb, PPP_EAP);
1361  return;
1362  }
1363 
1364  if (len <= 0) {
1365  ppp_error("EAP: empty Request message discarded");
1366  return;
1367  }
1368 
1369  GETCHAR(typenum, inp);
1370  len--;
1371 
1372  switch (typenum) {
1373  case EAPT_IDENTITY:
1374  if (len > 0)
1375  ppp_info("EAP: Identity prompt \"%.*q\"", len, inp);
1376 #ifdef USE_SRP
1377  if (pcb->eap.es_usepseudo &&
1378  (pcb->eap.es_usedpseudo == 0 ||
1379  (pcb->eap.es_usedpseudo == 1 &&
1380  id == pcb->eap.es_client.ea_id))) {
1381  pcb->eap.es_usedpseudo = 1;
1382  /* Try to get a pseudonym */
1383  if ((fd = open_pn_file(O_RDONLY)) >= 0) {
1384  strcpy(rhostname, SRP_PSEUDO_ID);
1385  len = read(fd, rhostname + SRP_PSEUDO_LEN,
1386  sizeof (rhostname) - SRP_PSEUDO_LEN);
1387  /* XXX NAI unsupported */
1388  if (len > 0) {
1389  eap_send_response(pcb, id, typenum,
1390  rhostname, len + SRP_PSEUDO_LEN);
1391  }
1392  (void) close(fd);
1393  if (len > 0)
1394  break;
1395  }
1396  }
1397  /* Stop using pseudonym now. */
1398  if (pcb->eap.es_usepseudo && pcb->eap.es_usedpseudo != 2) {
1399  remove_pn_file();
1400  pcb->eap.es_usedpseudo = 2;
1401  }
1402 #endif /* USE_SRP */
1403  eap_send_response(pcb, id, typenum, (const u_char*)pcb->eap.es_client.ea_name,
1404  pcb->eap.es_client.ea_namelen);
1405  break;
1406 
1407  case EAPT_NOTIFICATION:
1408  if (len > 0)
1409  ppp_info("EAP: Notification \"%.*q\"", len, inp);
1410  eap_send_response(pcb, id, typenum, NULL, 0);
1411  break;
1412 
1413  case EAPT_NAK:
1414  /*
1415  * Avoid the temptation to send Response Nak in reply
1416  * to Request Nak here. It can only lead to trouble.
1417  */
1418  ppp_warn("EAP: unexpected Nak in Request; ignored");
1419  /* Return because we're waiting for something real. */
1420  return;
1421 
1422  case EAPT_MD5CHAP:
1423  if (len < 1) {
1424  ppp_error("EAP: received MD5-Challenge with no data");
1425  /* Bogus request; wait for something real. */
1426  return;
1427  }
1428  GETCHAR(vallen, inp);
1429  len--;
1430  if (vallen < 8 || vallen > len) {
1431  ppp_error("EAP: MD5-Challenge with bad length %d (8..%d)",
1432  vallen, len);
1433  /* Try something better. */
1434  eap_send_nak(pcb, id, EAPT_SRP);
1435  break;
1436  }
1437 
1438  /* Not so likely to happen. */
1439  if (vallen >= len + sizeof (rhostname)) {
1440  ppp_dbglog("EAP: trimming really long peer name down");
1441  MEMCPY(rhostname, inp + vallen, sizeof (rhostname) - 1);
1442  rhostname[sizeof (rhostname) - 1] = '\0';
1443  } else {
1444  MEMCPY(rhostname, inp + vallen, len - vallen);
1445  rhostname[len - vallen] = '\0';
1446  }
1447 
1448 #if PPP_REMOTENAME
1449  /* In case the remote doesn't give us his name. */
1450  if (pcb->settings.explicit_remote ||
1451  (pcb->settings.remote_name[0] != '\0' && vallen == len))
1452  strlcpy(rhostname, pcb->settings.remote_name, sizeof (rhostname));
1453 #endif /* PPP_REMOTENAME */
1454 
1455  /*
1456  * Get the secret for authenticating ourselves with
1457  * the specified host.
1458  */
1459  if (!get_secret(pcb, pcb->eap.es_client.ea_name,
1460  rhostname, secret, &secret_len, 0)) {
1461  ppp_dbglog("EAP: no MD5 secret for auth to %q", rhostname);
1462  eap_send_nak(pcb, id, EAPT_SRP);
1463  break;
1464  }
1465  lwip_md5_init(&mdContext);
1466  lwip_md5_starts(&mdContext);
1467  typenum = id;
1468  lwip_md5_update(&mdContext, &typenum, 1);
1469  lwip_md5_update(&mdContext, (u_char *)secret, secret_len);
1470  BZERO(secret, sizeof (secret));
1471  lwip_md5_update(&mdContext, inp, vallen);
1472  lwip_md5_finish(&mdContext, hash);
1473  lwip_md5_free(&mdContext);
1474  eap_chap_response(pcb, id, hash, pcb->eap.es_client.ea_name,
1475  pcb->eap.es_client.ea_namelen);
1476  break;
1477 
1478 #ifdef USE_SRP
1479  case EAPT_SRP:
1480  if (len < 1) {
1481  ppp_error("EAP: received empty SRP Request");
1482  /* Bogus request; wait for something real. */
1483  return;
1484  }
1485 
1486  /* Get subtype */
1487  GETCHAR(vallen, inp);
1488  len--;
1489  switch (vallen) {
1490  case EAPSRP_CHALLENGE:
1491  tc = NULL;
1492  if (pcb->eap.es_client.ea_session != NULL) {
1493  tc = (struct t_client *)pcb->eap.es_client.
1494  ea_session;
1495  /*
1496  * If this is a new challenge, then start
1497  * over with a new client session context.
1498  * Otherwise, just resend last response.
1499  */
1500  if (id != pcb->eap.es_client.ea_id) {
1501  t_clientclose(tc);
1502  pcb->eap.es_client.ea_session = NULL;
1503  tc = NULL;
1504  }
1505  }
1506  /* No session key just yet */
1507  pcb->eap.es_client.ea_skey = NULL;
1508  if (tc == NULL) {
1509  int rhostnamelen;
1510 
1511  GETCHAR(vallen, inp);
1512  len--;
1513  if (vallen >= len) {
1514  ppp_error("EAP: badly-formed SRP Challenge"
1515  " (name)");
1516  /* Ignore badly-formed messages */
1517  return;
1518  }
1519  MEMCPY(rhostname, inp, vallen);
1520  rhostname[vallen] = '\0';
1521  INCPTR(vallen, inp);
1522  len -= vallen;
1523 
1524  /*
1525  * In case the remote doesn't give us his name,
1526  * use configured name.
1527  */
1528  if (explicit_remote ||
1529  (remote_name[0] != '\0' && vallen == 0)) {
1530  strlcpy(rhostname, remote_name,
1531  sizeof (rhostname));
1532  }
1533 
1534  rhostnamelen = (int)strlen(rhostname);
1535  if (rhostnamelen > MAXNAMELEN) {
1536  rhostnamelen = MAXNAMELEN;
1537  }
1538  MEMCPY(pcb->eap.es_client.ea_peer, rhostname, rhostnamelen);
1539  pcb->eap.es_client.ea_peer[rhostnamelen] = '\0';
1540  pcb->eap.es_client.ea_peerlen = rhostnamelen;
1541 
1542  GETCHAR(vallen, inp);
1543  len--;
1544  if (vallen >= len) {
1545  ppp_error("EAP: badly-formed SRP Challenge"
1546  " (s)");
1547  /* Ignore badly-formed messages */
1548  return;
1549  }
1550  sval.data = inp;
1551  sval.len = vallen;
1552  INCPTR(vallen, inp);
1553  len -= vallen;
1554 
1555  GETCHAR(vallen, inp);
1556  len--;
1557  if (vallen > len) {
1558  ppp_error("EAP: badly-formed SRP Challenge"
1559  " (g)");
1560  /* Ignore badly-formed messages */
1561  return;
1562  }
1563  /* If no generator present, then use value 2 */
1564  if (vallen == 0) {
1565  gval.data = (u_char *)"\002";
1566  gval.len = 1;
1567  } else {
1568  gval.data = inp;
1569  gval.len = vallen;
1570  }
1571  INCPTR(vallen, inp);
1572  len -= vallen;
1573 
1574  /*
1575  * If no modulus present, then use well-known
1576  * value.
1577  */
1578  if (len == 0) {
1579  Nval.data = (u_char *)wkmodulus;
1580  Nval.len = sizeof (wkmodulus);
1581  } else {
1582  Nval.data = inp;
1583  Nval.len = len;
1584  }
1585  tc = t_clientopen(pcb->eap.es_client.ea_name,
1586  &Nval, &gval, &sval);
1587  if (tc == NULL) {
1588  eap_send_nak(pcb, id, EAPT_MD5CHAP);
1589  break;
1590  }
1591  pcb->eap.es_client.ea_session = (void *)tc;
1592 
1593  /* Add Challenge ID & type to verifier */
1594  vals[0] = id;
1595  vals[1] = EAPT_SRP;
1596  t_clientaddexdata(tc, vals, 2);
1597  }
1598  Ap = t_clientgenexp(tc);
1599  eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data,
1600  Ap->len);
1601  break;
1602 
1603  case EAPSRP_SKEY:
1604  tc = (struct t_client *)pcb->eap.es_client.ea_session;
1605  if (tc == NULL) {
1606  ppp_warn("EAP: peer sent Subtype 2 without 1");
1607  eap_send_nak(pcb, id, EAPT_MD5CHAP);
1608  break;
1609  }
1610  if (pcb->eap.es_client.ea_skey != NULL) {
1611  /*
1612  * ID number should not change here. Warn
1613  * if it does (but otherwise ignore).
1614  */
1615  if (id != pcb->eap.es_client.ea_id) {
1616  ppp_warn("EAP: ID changed from %d to %d "
1617  "in SRP Subtype 2 rexmit",
1618  pcb->eap.es_client.ea_id, id);
1619  }
1620  } else {
1621  if (get_srp_secret(pcb->eap.es_unit,
1622  pcb->eap.es_client.ea_name,
1623  pcb->eap.es_client.ea_peer, secret, 0) == 0) {
1624  /*
1625  * Can't work with this peer because
1626  * the secret is missing. Just give
1627  * up.
1628  */
1629  eap_send_nak(pcb, id, EAPT_MD5CHAP);
1630  break;
1631  }
1632  Bval.data = inp;
1633  Bval.len = len;
1634  t_clientpasswd(tc, secret);
1635  BZERO(secret, sizeof (secret));
1636  pcb->eap.es_client.ea_skey =
1637  t_clientgetkey(tc, &Bval);
1638  if (pcb->eap.es_client.ea_skey == NULL) {
1639  /* Server is rogue; stop now */
1640  ppp_error("EAP: SRP server is rogue");
1641  goto client_failure;
1642  }
1643  }
1644  eap_srpval_response(esp, id, SRPVAL_EBIT,
1645  t_clientresponse(tc));
1646  break;
1647 
1648  case EAPSRP_SVALIDATOR:
1649  tc = (struct t_client *)pcb->eap.es_client.ea_session;
1650  if (tc == NULL || pcb->eap.es_client.ea_skey == NULL) {
1651  ppp_warn("EAP: peer sent Subtype 3 without 1/2");
1652  eap_send_nak(pcb, id, EAPT_MD5CHAP);
1653  break;
1654  }
1655  /*
1656  * If we're already open, then this ought to be a
1657  * duplicate. Otherwise, check that the server is
1658  * who we think it is.
1659  */
1660  if (pcb->eap.es_client.ea_state == eapOpen) {
1661  if (id != pcb->eap.es_client.ea_id) {
1662  ppp_warn("EAP: ID changed from %d to %d "
1663  "in SRP Subtype 3 rexmit",
1664  pcb->eap.es_client.ea_id, id);
1665  }
1666  } else {
1667  len -= sizeof (u32_t) + SHA_DIGESTSIZE;
1668  if (len < 0 || t_clientverify(tc, inp +
1669  sizeof (u32_t)) != 0) {
1670  ppp_error("EAP: SRP server verification "
1671  "failed");
1672  goto client_failure;
1673  }
1674  GETLONG(pcb->eap.es_client.ea_keyflags, inp);
1675  /* Save pseudonym if user wants it. */
1676  if (len > 0 && pcb->eap.es_usepseudo) {
1677  INCPTR(SHA_DIGESTSIZE, inp);
1678  write_pseudonym(esp, inp, len, id);
1679  }
1680  }
1681  /*
1682  * We've verified our peer. We're now mostly done,
1683  * except for waiting on the regular EAP Success
1684  * message.
1685  */
1686  eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0);
1687  break;
1688 
1689  case EAPSRP_LWRECHALLENGE:
1690  if (len < 4) {
1691  ppp_warn("EAP: malformed Lightweight rechallenge");
1692  return;
1693  }
1694  SHA1Init(&ctxt);
1695  vals[0] = id;
1696  SHA1Update(&ctxt, vals, 1);
1697  SHA1Update(&ctxt, pcb->eap.es_client.ea_skey,
1698  SESSION_KEY_LEN);
1699  SHA1Update(&ctxt, inp, len);
1700  SHA1Update(&ctxt, pcb->eap.es_client.ea_name,
1701  pcb->eap.es_client.ea_namelen);
1702  SHA1Final(dig, &ctxt);
1703  eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
1704  SHA_DIGESTSIZE);
1705  break;
1706 
1707  default:
1708  ppp_error("EAP: unknown SRP Subtype %d", vallen);
1709  eap_send_nak(pcb, id, EAPT_MD5CHAP);
1710  break;
1711  }
1712  break;
1713 #endif /* USE_SRP */
1714 
1715  default:
1716  ppp_info("EAP: unknown authentication type %d; Naking", typenum);
1717  eap_send_nak(pcb, id, EAPT_SRP);
1718  break;
1719  }
1720 
1721  if (pcb->settings.eap_req_time > 0) {
1722  UNTIMEOUT(eap_client_timeout, pcb);
1723  TIMEOUT(eap_client_timeout, pcb,
1724  pcb->settings.eap_req_time);
1725  }
1726  return;
1727 
1728 #ifdef USE_SRP
1729 client_failure:
1730  pcb->eap.es_client.ea_state = eapBadAuth;
1731  if (pcb->settings.eap_req_time > 0) {
1732  UNTIMEOUT(eap_client_timeout, (void *)esp);
1733  }
1734  pcb->eap.es_client.ea_session = NULL;
1735  t_clientclose(tc);
1736  auth_withpeer_fail(pcb, PPP_EAP);
1737 #endif /* USE_SRP */
1738 }
1739 
1740 #if PPP_SERVER
1741 /*
1742  * eap_response - Receive EAP Response message (server mode).
1743  */
1744 static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) {
1745  u_char typenum;
1746  u_char vallen;
1747  int secret_len;
1748  char secret[MAXSECRETLEN];
1749  char rhostname[MAXNAMELEN];
1750  lwip_md5_context mdContext;
1751  u_char hash[MD5_SIGNATURE_SIZE];
1752 #ifdef USE_SRP
1753  struct t_server *ts;
1754  struct t_num A;
1755  SHA1_CTX ctxt;
1756  u_char dig[SHA_DIGESTSIZE];
1757 #endif /* USE_SRP */
1758 
1759  if (pcb->eap.es_server.ea_id != id) {
1760  ppp_dbglog("EAP: discarding Response %d; expected ID %d", id,
1761  pcb->eap.es_server.ea_id);
1762  return;
1763  }
1764 
1765  pcb->eap.es_server.ea_responses++;
1766 
1767  if (len <= 0) {
1768  ppp_error("EAP: empty Response message discarded");
1769  return;
1770  }
1771 
1772  GETCHAR(typenum, inp);
1773  len--;
1774 
1775  switch (typenum) {
1776  case EAPT_IDENTITY:
1777  if (pcb->eap.es_server.ea_state != eapIdentify) {
1778  ppp_dbglog("EAP discarding unwanted Identify \"%.q\"", len,
1779  inp);
1780  break;
1781  }
1782  ppp_info("EAP: unauthenticated peer name \"%.*q\"", len, inp);
1783  if (len > MAXNAMELEN) {
1784  len = MAXNAMELEN;
1785  }
1786  MEMCPY(pcb->eap.es_server.ea_peer, inp, len);
1787  pcb->eap.es_server.ea_peer[len] = '\0';
1788  pcb->eap.es_server.ea_peerlen = len;
1789  eap_figure_next_state(pcb, 0);
1790  break;
1791 
1792  case EAPT_NOTIFICATION:
1793  ppp_dbglog("EAP unexpected Notification; response discarded");
1794  break;
1795 
1796  case EAPT_NAK:
1797  if (len < 1) {
1798  ppp_info("EAP: Nak Response with no suggested protocol");
1799  eap_figure_next_state(pcb, 1);
1800  break;
1801  }
1802 
1803  GETCHAR(vallen, inp);
1804  len--;
1805 
1806  if (
1807 #if PPP_REMOTENAME
1808  !pcb->explicit_remote &&
1809 #endif /* PPP_REMOTENAME */
1810  pcb->eap.es_server.ea_state == eapIdentify){
1811  /* Peer cannot Nak Identify Request */
1812  eap_figure_next_state(pcb, 1);
1813  break;
1814  }
1815 
1816  switch (vallen) {
1817  case EAPT_SRP:
1818  /* Run through SRP validator selection again. */
1819  pcb->eap.es_server.ea_state = eapIdentify;
1820  eap_figure_next_state(pcb, 0);
1821  break;
1822 
1823  case EAPT_MD5CHAP:
1824  pcb->eap.es_server.ea_state = eapMD5Chall;
1825  break;
1826 
1827  default:
1828  ppp_dbglog("EAP: peer requesting unknown Type %d", vallen);
1829  switch (pcb->eap.es_server.ea_state) {
1830  case eapSRP1:
1831  case eapSRP2:
1832  case eapSRP3:
1833  pcb->eap.es_server.ea_state = eapMD5Chall;
1834  break;
1835  case eapMD5Chall:
1836  case eapSRP4:
1837  pcb->eap.es_server.ea_state = eapIdentify;
1838  eap_figure_next_state(pcb, 0);
1839  break;
1840  default:
1841  break;
1842  }
1843  break;
1844  }
1845  break;
1846 
1847  case EAPT_MD5CHAP:
1848  if (pcb->eap.es_server.ea_state != eapMD5Chall) {
1849  ppp_error("EAP: unexpected MD5-Response");
1850  eap_figure_next_state(pcb, 1);
1851  break;
1852  }
1853  if (len < 1) {
1854  ppp_error("EAP: received MD5-Response with no data");
1855  eap_figure_next_state(pcb, 1);
1856  break;
1857  }
1858  GETCHAR(vallen, inp);
1859  len--;
1860  if (vallen != 16 || vallen > len) {
1861  ppp_error("EAP: MD5-Response with bad length %d", vallen);
1862  eap_figure_next_state(pcb, 1);
1863  break;
1864  }
1865 
1866  /* Not so likely to happen. */
1867  if (vallen >= len + sizeof (rhostname)) {
1868  ppp_dbglog("EAP: trimming really long peer name down");
1869  MEMCPY(rhostname, inp + vallen, sizeof (rhostname) - 1);
1870  rhostname[sizeof (rhostname) - 1] = '\0';
1871  } else {
1872  MEMCPY(rhostname, inp + vallen, len - vallen);
1873  rhostname[len - vallen] = '\0';
1874  }
1875 
1876 #if PPP_REMOTENAME
1877  /* In case the remote doesn't give us his name. */
1878  if (explicit_remote ||
1879  (remote_name[0] != '\0' && vallen == len))
1880  strlcpy(rhostname, remote_name, sizeof (rhostname));
1881 #endif /* PPP_REMOTENAME */
1882 
1883  /*
1884  * Get the secret for authenticating the specified
1885  * host.
1886  */
1887  if (!get_secret(pcb, rhostname,
1888  pcb->eap.es_server.ea_name, secret, &secret_len, 1)) {
1889  ppp_dbglog("EAP: no MD5 secret for auth of %q", rhostname);
1890  eap_send_failure(pcb);
1891  break;
1892  }
1893  lwip_md5_init(&mdContext);
1894  lwip_md5_starts(&mdContext);
1895  lwip_md5_update(&mdContext, &pcb->eap.es_server.ea_id, 1);
1896  lwip_md5_update(&mdContext, (u_char *)secret, secret_len);
1897  BZERO(secret, sizeof (secret));
1898  lwip_md5_update(&mdContext, pcb->eap.es_challenge, pcb->eap.es_challen);
1899  lwip_md5_finish(&mdContext, hash);
1900  lwip_md5_free(&mdContext);
1901  if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) {
1902  eap_send_failure(pcb);
1903  break;
1904  }
1905  pcb->eap.es_server.ea_type = EAPT_MD5CHAP;
1906  eap_send_success(pcb);
1907  eap_figure_next_state(pcb, 0);
1908  if (pcb->eap.es_rechallenge != 0)
1909  TIMEOUT(eap_rechallenge, pcb, pcb->eap.es_rechallenge);
1910  break;
1911 
1912 #ifdef USE_SRP
1913  case EAPT_SRP:
1914  if (len < 1) {
1915  ppp_error("EAP: empty SRP Response");
1916  eap_figure_next_state(pcb, 1);
1917  break;
1918  }
1919  GETCHAR(typenum, inp);
1920  len--;
1921  switch (typenum) {
1922  case EAPSRP_CKEY:
1923  if (pcb->eap.es_server.ea_state != eapSRP1) {
1924  ppp_error("EAP: unexpected SRP Subtype 1 Response");
1925  eap_figure_next_state(pcb, 1);
1926  break;
1927  }
1928  A.data = inp;
1929  A.len = len;
1930  ts = (struct t_server *)pcb->eap.es_server.ea_session;
1931  assert(ts != NULL);
1932  pcb->eap.es_server.ea_skey = t_servergetkey(ts, &A);
1933  if (pcb->eap.es_server.ea_skey == NULL) {
1934  /* Client's A value is bogus; terminate now */
1935  ppp_error("EAP: bogus A value from client");
1936  eap_send_failure(pcb);
1937  } else {
1938  eap_figure_next_state(pcb, 0);
1939  }
1940  break;
1941 
1942  case EAPSRP_CVALIDATOR:
1943  if (pcb->eap.es_server.ea_state != eapSRP2) {
1944  ppp_error("EAP: unexpected SRP Subtype 2 Response");
1945  eap_figure_next_state(pcb, 1);
1946  break;
1947  }
1948  if (len < sizeof (u32_t) + SHA_DIGESTSIZE) {
1949  ppp_error("EAP: M1 length %d < %d", len,
1950  sizeof (u32_t) + SHA_DIGESTSIZE);
1951  eap_figure_next_state(pcb, 1);
1952  break;
1953  }
1954  GETLONG(pcb->eap.es_server.ea_keyflags, inp);
1955  ts = (struct t_server *)pcb->eap.es_server.ea_session;
1956  assert(ts != NULL);
1957  if (t_serververify(ts, inp)) {
1958  ppp_info("EAP: unable to validate client identity");
1959  eap_send_failure(pcb);
1960  break;
1961  }
1962  eap_figure_next_state(pcb, 0);
1963  break;
1964 
1965  case EAPSRP_ACK:
1966  if (pcb->eap.es_server.ea_state != eapSRP3) {
1967  ppp_error("EAP: unexpected SRP Subtype 3 Response");
1968  eap_send_failure(esp);
1969  break;
1970  }
1971  pcb->eap.es_server.ea_type = EAPT_SRP;
1972  eap_send_success(pcb, esp);
1973  eap_figure_next_state(pcb, 0);
1974  if (pcb->eap.es_rechallenge != 0)
1975  TIMEOUT(eap_rechallenge, pcb,
1976  pcb->eap.es_rechallenge);
1977  if (pcb->eap.es_lwrechallenge != 0)
1978  TIMEOUT(srp_lwrechallenge, pcb,
1979  pcb->eap.es_lwrechallenge);
1980  break;
1981 
1982  case EAPSRP_LWRECHALLENGE:
1983  if (pcb->eap.es_server.ea_state != eapSRP4) {
1984  ppp_info("EAP: unexpected SRP Subtype 4 Response");
1985  return;
1986  }
1987  if (len != SHA_DIGESTSIZE) {
1988  ppp_error("EAP: bad Lightweight rechallenge "
1989  "response");
1990  return;
1991  }
1992  SHA1Init(&ctxt);
1993  vallen = id;
1994  SHA1Update(&ctxt, &vallen, 1);
1995  SHA1Update(&ctxt, pcb->eap.es_server.ea_skey,
1996  SESSION_KEY_LEN);
1997  SHA1Update(&ctxt, pcb->eap.es_challenge, pcb->eap.es_challen);
1998  SHA1Update(&ctxt, pcb->eap.es_server.ea_peer,
1999  pcb->eap.es_server.ea_peerlen);
2000  SHA1Final(dig, &ctxt);
2001  if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
2002  ppp_error("EAP: failed Lightweight rechallenge");
2003  eap_send_failure(pcb);
2004  break;
2005  }
2006  pcb->eap.es_server.ea_state = eapOpen;
2007  if (pcb->eap.es_lwrechallenge != 0)
2008  TIMEOUT(srp_lwrechallenge, esp,
2009  pcb->eap.es_lwrechallenge);
2010  break;
2011  }
2012  break;
2013 #endif /* USE_SRP */
2014 
2015  default:
2016  /* This can't happen. */
2017  ppp_error("EAP: unknown Response type %d; ignored", typenum);
2018  return;
2019  }
2020 
2021  if (pcb->settings.eap_timeout_time > 0) {
2022  UNTIMEOUT(eap_server_timeout, pcb);
2023  }
2024 
2025  if (pcb->eap.es_server.ea_state != eapBadAuth &&
2026  pcb->eap.es_server.ea_state != eapOpen) {
2027  pcb->eap.es_server.ea_id++;
2028  eap_send_request(pcb);
2029  }
2030 }
2031 #endif /* PPP_SERVER */
2032 
2033 /*
2034  * eap_success - Receive EAP Success message (client mode).
2035  */
2036 static void eap_success(ppp_pcb *pcb, u_char *inp, int id, int len) {
2037  LWIP_UNUSED_ARG(id);
2038 
2039  if (pcb->eap.es_client.ea_state != eapOpen && !eap_client_active(pcb)) {
2040  ppp_dbglog("EAP unexpected success message in state %s (%d)",
2041  eap_state_name(pcb->eap.es_client.ea_state),
2042  pcb->eap.es_client.ea_state);
2043  return;
2044  }
2045 
2046  if (pcb->settings.eap_req_time > 0) {
2047  UNTIMEOUT(eap_client_timeout, pcb);
2048  }
2049 
2050  if (len > 0) {
2051  /* This is odd. The spec doesn't allow for this. */
2052  PRINTMSG(inp, len);
2053  }
2054 
2055  pcb->eap.es_client.ea_state = eapOpen;
2056  auth_withpeer_success(pcb, PPP_EAP, 0);
2057 }
2058 
2059 /*
2060  * eap_failure - Receive EAP Failure message (client mode).
2061  */
2062 static void eap_failure(ppp_pcb *pcb, u_char *inp, int id, int len) {
2063  LWIP_UNUSED_ARG(id);
2064 
2065  if (!eap_client_active(pcb)) {
2066  ppp_dbglog("EAP unexpected failure message in state %s (%d)",
2067  eap_state_name(pcb->eap.es_client.ea_state),
2068  pcb->eap.es_client.ea_state);
2069  }
2070 
2071  if (pcb->settings.eap_req_time > 0) {
2072  UNTIMEOUT(eap_client_timeout, pcb);
2073  }
2074 
2075  if (len > 0) {
2076  /* This is odd. The spec doesn't allow for this. */
2077  PRINTMSG(inp, len);
2078  }
2079 
2080  pcb->eap.es_client.ea_state = eapBadAuth;
2081 
2082  ppp_error("EAP: peer reports authentication failure");
2083  auth_withpeer_fail(pcb, PPP_EAP);
2084 }
2085 
2086 /*
2087  * eap_input - Handle received EAP message.
2088  */
2089 static void eap_input(ppp_pcb *pcb, u_char *inp, int inlen) {
2090  u_char code, id;
2091  int len;
2092 
2093  /*
2094  * Parse header (code, id and length). If packet too short,
2095  * drop it.
2096  */
2097  if (inlen < EAP_HEADERLEN) {
2098  ppp_error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
2099  return;
2100  }
2101  GETCHAR(code, inp);
2102  GETCHAR(id, inp);
2103  GETSHORT(len, inp);
2104  if (len < EAP_HEADERLEN || len > inlen) {
2105  ppp_error("EAP: packet has illegal length field %d (%d..%d)", len,
2106  EAP_HEADERLEN, inlen);
2107  return;
2108  }
2109  len -= EAP_HEADERLEN;
2110 
2111  /* Dispatch based on message code */
2112  switch (code) {
2113  case EAP_REQUEST:
2114  eap_request(pcb, inp, id, len);
2115  break;
2116 
2117 #if PPP_SERVER
2118  case EAP_RESPONSE:
2119  eap_response(pcb, inp, id, len);
2120  break;
2121 #endif /* PPP_SERVER */
2122 
2123  case EAP_SUCCESS:
2124  eap_success(pcb, inp, id, len);
2125  break;
2126 
2127  case EAP_FAILURE:
2128  eap_failure(pcb, inp, id, len);
2129  break;
2130 
2131  default: /* XXX Need code reject */
2132  /* Note: it's not legal to send EAP Nak here. */
2133  ppp_warn("EAP: unknown code %d received", code);
2134  break;
2135  }
2136 }
2137 
2138 #if PRINTPKT_SUPPORT
2139 /*
2140  * eap_printpkt - print the contents of an EAP packet.
2141  */
2142 static const char* const eap_codenames[] = {
2143  "Request", "Response", "Success", "Failure"
2144 };
2145 
2146 static const char* const eap_typenames[] = {
2147  "Identity", "Notification", "Nak", "MD5-Challenge",
2148  "OTP", "Generic-Token", NULL, NULL,
2149  "RSA", "DSS", "KEA", "KEA-Validate",
2150  "TLS", "Defender", "Windows 2000", "Arcot",
2151  "Cisco", "Nokia", "SRP"
2152 };
2153 
2154 static int eap_printpkt(const u_char *inp, int inlen, void (*printer) (void *, const char *, ...), void *arg) {
2155  int code, id, len, rtype, vallen;
2156  const u_char *pstart;
2157  u32_t uval;
2158 
2159  if (inlen < EAP_HEADERLEN)
2160  return (0);
2161  pstart = inp;
2162  GETCHAR(code, inp);
2163  GETCHAR(id, inp);
2164  GETSHORT(len, inp);
2165  if (len < EAP_HEADERLEN || len > inlen)
2166  return (0);
2167 
2168  if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(eap_codenames))
2169  printer(arg, " %s", eap_codenames[code-1]);
2170  else
2171  printer(arg, " code=0x%x", code);
2172  printer(arg, " id=0x%x", id);
2173  len -= EAP_HEADERLEN;
2174  switch (code) {
2175  case EAP_REQUEST:
2176  if (len < 1) {
2177  printer(arg, " <missing type>");
2178  break;
2179  }
2180  GETCHAR(rtype, inp);
2181  len--;
2182  if (rtype >= 1 && rtype <= (int)LWIP_ARRAYSIZE(eap_typenames))
2183  printer(arg, " %s", eap_typenames[rtype-1]);
2184  else
2185  printer(arg, " type=0x%x", rtype);
2186  switch (rtype) {
2187  case EAPT_IDENTITY:
2188  case EAPT_NOTIFICATION:
2189  if (len > 0) {
2190  printer(arg, " <Message ");
2191  ppp_print_string(inp, len, printer, arg);
2192  printer(arg, ">");
2193  INCPTR(len, inp);
2194  len = 0;
2195  } else {
2196  printer(arg, " <No message>");
2197  }
2198  break;
2199 
2200  case EAPT_MD5CHAP:
2201  if (len <= 0)
2202  break;
2203  GETCHAR(vallen, inp);
2204  len--;
2205  if (vallen > len)
2206  goto truncated;
2207  printer(arg, " <Value%.*B>", vallen, inp);
2208  INCPTR(vallen, inp);
2209  len -= vallen;
2210  if (len > 0) {
2211  printer(arg, " <Name ");
2212  ppp_print_string(inp, len, printer, arg);
2213  printer(arg, ">");
2214  INCPTR(len, inp);
2215  len = 0;
2216  } else {
2217  printer(arg, " <No name>");
2218  }
2219  break;
2220 
2221  case EAPT_SRP:
2222  if (len < 3)
2223  goto truncated;
2224  GETCHAR(vallen, inp);
2225  len--;
2226  printer(arg, "-%d", vallen);
2227  switch (vallen) {
2228  case EAPSRP_CHALLENGE:
2229  GETCHAR(vallen, inp);
2230  len--;
2231  if (vallen >= len)
2232  goto truncated;
2233  if (vallen > 0) {
2234  printer(arg, " <Name ");
2235  ppp_print_string(inp, vallen, printer,
2236  arg);
2237  printer(arg, ">");
2238  } else {
2239  printer(arg, " <No name>");
2240  }
2241  INCPTR(vallen, inp);
2242  len -= vallen;
2243  GETCHAR(vallen, inp);
2244  len--;
2245  if (vallen >= len)
2246  goto truncated;
2247  printer(arg, " <s%.*B>", vallen, inp);
2248  INCPTR(vallen, inp);
2249  len -= vallen;
2250  GETCHAR(vallen, inp);
2251  len--;
2252  if (vallen > len)
2253  goto truncated;
2254  if (vallen == 0) {
2255  printer(arg, " <Default g=2>");
2256  } else {
2257  printer(arg, " <g%.*B>", vallen, inp);
2258  }
2259  INCPTR(vallen, inp);
2260  len -= vallen;
2261  if (len == 0) {
2262  printer(arg, " <Default N>");
2263  } else {
2264  printer(arg, " <N%.*B>", len, inp);
2265  INCPTR(len, inp);
2266  len = 0;
2267  }
2268  break;
2269 
2270  case EAPSRP_SKEY:
2271  printer(arg, " <B%.*B>", len, inp);
2272  INCPTR(len, inp);
2273  len = 0;
2274  break;
2275 
2276  case EAPSRP_SVALIDATOR:
2277  if (len < (int)sizeof (u32_t))
2278  break;
2279  GETLONG(uval, inp);
2280  len -= sizeof (u32_t);
2281  if (uval & SRPVAL_EBIT) {
2282  printer(arg, " E");
2283  uval &= ~SRPVAL_EBIT;
2284  }
2285  if (uval != 0) {
2286  printer(arg, " f<%X>", uval);
2287  }
2288  if ((vallen = len) > SHA_DIGESTSIZE)
2289  vallen = SHA_DIGESTSIZE;
2290  printer(arg, " <M2%.*B%s>", len, inp,
2291  len < SHA_DIGESTSIZE ? "?" : "");
2292  INCPTR(vallen, inp);
2293  len -= vallen;
2294  if (len > 0) {
2295  printer(arg, " <PN%.*B>", len, inp);
2296  INCPTR(len, inp);
2297  len = 0;
2298  }
2299  break;
2300 
2301  case EAPSRP_LWRECHALLENGE:
2302  printer(arg, " <Challenge%.*B>", len, inp);
2303  INCPTR(len, inp);
2304  len = 0;
2305  break;
2306  default:
2307  break;
2308  }
2309  break;
2310  default:
2311  break;
2312  }
2313  break;
2314 
2315  case EAP_RESPONSE:
2316  if (len < 1)
2317  break;
2318  GETCHAR(rtype, inp);
2319  len--;
2320  if (rtype >= 1 && rtype <= (int)LWIP_ARRAYSIZE(eap_typenames))
2321  printer(arg, " %s", eap_typenames[rtype-1]);
2322  else
2323  printer(arg, " type=0x%x", rtype);
2324  switch (rtype) {
2325  case EAPT_IDENTITY:
2326  if (len > 0) {
2327  printer(arg, " <Name ");
2328  ppp_print_string(inp, len, printer, arg);
2329  printer(arg, ">");
2330  INCPTR(len, inp);
2331  len = 0;
2332  }
2333  break;
2334 
2335  case EAPT_NAK:
2336  if (len <= 0) {
2337  printer(arg, " <missing hint>");
2338  break;
2339  }
2340  GETCHAR(rtype, inp);
2341  len--;
2342  printer(arg, " <Suggested-type %02X", rtype);
2343  if (rtype >= 1 && rtype < (int)LWIP_ARRAYSIZE(eap_typenames))
2344  printer(arg, " (%s)", eap_typenames[rtype-1]);
2345  printer(arg, ">");
2346  break;
2347 
2348  case EAPT_MD5CHAP:
2349  if (len <= 0) {
2350  printer(arg, " <missing length>");
2351  break;
2352  }
2353  GETCHAR(vallen, inp);
2354  len--;
2355  if (vallen > len)
2356  goto truncated;
2357  printer(arg, " <Value%.*B>", vallen, inp);
2358  INCPTR(vallen, inp);
2359  len -= vallen;
2360  if (len > 0) {
2361  printer(arg, " <Name ");
2362  ppp_print_string(inp, len, printer, arg);
2363  printer(arg, ">");
2364  INCPTR(len, inp);
2365  len = 0;
2366  } else {
2367  printer(arg, " <No name>");
2368  }
2369  break;
2370 
2371  case EAPT_SRP:
2372  if (len < 1)
2373  goto truncated;
2374  GETCHAR(vallen, inp);
2375  len--;
2376  printer(arg, "-%d", vallen);
2377  switch (vallen) {
2378  case EAPSRP_CKEY:
2379  printer(arg, " <A%.*B>", len, inp);
2380  INCPTR(len, inp);
2381  len = 0;
2382  break;
2383 
2384  case EAPSRP_CVALIDATOR:
2385  if (len < (int)sizeof (u32_t))
2386  break;
2387  GETLONG(uval, inp);
2388  len -= sizeof (u32_t);
2389  if (uval & SRPVAL_EBIT) {
2390  printer(arg, " E");
2391  uval &= ~SRPVAL_EBIT;
2392  }
2393  if (uval != 0) {
2394  printer(arg, " f<%X>", uval);
2395  }
2396  printer(arg, " <M1%.*B%s>", len, inp,
2397  len == SHA_DIGESTSIZE ? "" : "?");
2398  INCPTR(len, inp);
2399  len = 0;
2400  break;
2401 
2402  case EAPSRP_ACK:
2403  break;
2404 
2405  case EAPSRP_LWRECHALLENGE:
2406  printer(arg, " <Response%.*B%s>", len, inp,
2407  len == SHA_DIGESTSIZE ? "" : "?");
2408  if ((vallen = len) > SHA_DIGESTSIZE)
2409  vallen = SHA_DIGESTSIZE;
2410  INCPTR(vallen, inp);
2411  len -= vallen;
2412  break;
2413  default:
2414  break;
2415  }
2416  break;
2417  default:
2418  break;
2419  }
2420  break;
2421 
2422  case EAP_SUCCESS: /* No payload expected for these! */
2423  case EAP_FAILURE:
2424  default:
2425  break;
2426 
2427  truncated:
2428  printer(arg, " <truncated>");
2429  break;
2430  }
2431 
2432  if (len > 8)
2433  printer(arg, "%8B...", inp);
2434  else if (len > 0)
2435  printer(arg, "%.*B", len, inp);
2436  INCPTR(len, inp);
2437 
2438  return (inp - pstart);
2439 }
2440 #endif /* PRINTPKT_SUPPORT */
2441 
2442 #endif /* PPP_SUPPORT && EAP_SUPPORT */
u16_t tot_len
Definition: pbuf.h:175
void pbuf_realloc(struct pbuf *p, u16_t new_len)
Definition: pbuf.c:512
Definition: pbuf.h:113
u16_t len
Definition: pbuf.h:178
u8_t flags
Definition: pbuf.h:184
Definition: pbuf.h:161
#define assert(x)
Definition: assert.h:37
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:267
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:327
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:734
void * payload
Definition: pbuf.h:166
u8_t type
Definition: pbuf.h:181