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