18ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
28ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * eap.c - Extensible Authentication Protocol for PPP (RFC 2284)
38ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
48ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Copyright (c) 2001 by Sun Microsystems, Inc.
58ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * All rights reserved.
68ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
78ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Non-exclusive rights to redistribute, modify, translate, and use
88ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * this software in source and binary forms, in whole or in part, is
98ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * hereby granted, provided that the above copyright notice is
108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * duplicated in any source form, and that neither the name of the
118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * copyright holder nor the author is used to endorse or promote
128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * products derived from this software.
138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Original version by James Carlson
198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This implementation of EAP supports MD5-Challenge and SRP-SHA1
218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * authentication styles.  Note that support of MD5-Challenge is a
228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * requirement of RFC 2284, and that it's essentially just a
238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * reimplementation of regular RFC 1994 CHAP using EAP messages.
248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * As an authenticator ("server"), there are multiple phases for each
268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * style.  In the first phase of each style, the unauthenticated peer
278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * name is queried using the EAP Identity request type.  If the
288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * "remotename" option is used, then this phase is skipped, because
298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the peer's name is presumed to be known.
308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * For MD5-Challenge, there are two phases, and the second phase
328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * consists of sending the challenge itself and handling the
338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * associated response.
348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * For SRP-SHA1, there are four phases.  The second sends 's', 'N',
368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * and 'g'.  The reply contains 'A'.  The third sends 'B', and the
378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * reply contains 'M1'.  The forth sends the 'M2' value.
388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * As an authenticatee ("client"), there's just a single phase --
408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * responding to the queries generated by the peer.  EAP is an
418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * authenticator-driven protocol.
428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Based on draft-ietf-pppext-eap-srp-03.txt.
448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define RCSID	"$Id: eap.c,v 1.4 2004/11/09 22:39:25 paulus Exp $"
478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * TODO:
508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdio.h>
538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdlib.h>
548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <string.h>
558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <unistd.h>
568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <pwd.h>
578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/types.h>
588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/stat.h>
598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <fcntl.h>
608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <assert.h>
618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <errno.h>
628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "pppd.h"
648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "pathnames.h"
658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "md5.h"
668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "eap.h"
678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <t_pwd.h>
708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <t_server.h>
718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <t_client.h>
728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "pppcrypt.h"
738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_SRP */
748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifndef SHA_DIGESTSIZE
768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define	SHA_DIGESTSIZE 20
778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic const char rcsid[] = RCSID;
808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_state eap_states[NUM_PPP];		/* EAP state; one for each unit */
828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char *pn_secret = NULL;		/* Pseudonym generating secret */
848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Command-line options.
888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic option_t eap_option_list[] = {
908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout,
918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set retransmit timeout for EAP Requests (server)" },
928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests,
938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set max number of EAP Requests sent (server)" },
948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout,
958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set time limit for peer EAP authentication" },
968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests,
978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set max number of EAP Requests allows (client)" },
988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "eap-interval", o_int, &eap_states[0].es_rechallenge,
998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set interval for EAP rechallenge" },
1008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
1018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "srp-interval", o_int, &eap_states[0].es_lwrechallenge,
1028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Set interval for SRP lightweight rechallenge" },
1038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "srp-pn-secret", o_string, &pn_secret,
1048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Long term pseudonym generation secret" },
1058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo,
1068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      "Use pseudonym if offered one by server", 1 },
1078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
1088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { NULL }
1098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
1108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
1128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Protocol entry points.
1138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
1148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void eap_init __P((int unit));
1158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void eap_input __P((int unit, u_char *inp, int inlen));
1168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void eap_protrej __P((int unit));
1178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void eap_lowerup __P((int unit));
1188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void eap_lowerdown __P((int unit));
1198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int  eap_printpkt __P((u_char *inp, int inlen,
1208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void (*)(void *arg, char *fmt, ...), void *arg));
1218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstruct protent eap_protent = {
1238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PPP_EAP,		/* protocol number */
1248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_init,		/* initialization procedure */
1258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_input,		/* process a received packet */
1268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_protrej,		/* process a received protocol-reject */
1278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_lowerup,		/* lower layer has gone up */
1288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_lowerdown,		/* lower layer has gone down */
1298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	NULL,			/* open the protocol */
1308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	NULL,			/* close the protocol */
1318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_printpkt,		/* print a packet in readable form */
1328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	NULL,			/* process a received data packet */
1338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	1,			/* protocol enabled */
1348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	"EAP",			/* text name of protocol */
1358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	NULL,			/* text name of corresponding data protocol */
1368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_option_list,	/* list of command-line options */
1378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	NULL,			/* check requested options; assign defaults */
1388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	NULL,			/* configure interface for demand-dial */
1398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	NULL			/* say whether to bring up link for this pkt */
1408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
1418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
1438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * A well-known 2048 bit modulus.
1448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
1458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic const u_char wkmodulus[] = {
1468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B,
1478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F,
1488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07,
1498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50,
1508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED,
1518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D,
1528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D,
1538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50,
1548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
1558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3,
1568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8,
1578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8,
1588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA,
1598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74,
1608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7,
1618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B,
1628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16,
1638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
1648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A,
1658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48,
1668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D,
1678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA,
1688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78,
1698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6,
1708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29,
1718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8,
1728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
1738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6,
1748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4,
1758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75,
1768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
1778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
1788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
1798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* Local forward declarations. */
1818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void eap_server_timeout __P((void *arg));
1828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
1848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Convert EAP state code to printable string for debug.
1858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
1868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic const char *
1878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_state_name(esc)
1888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectenum eap_state_code esc;
1898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
1908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	static const char *state_names[] = { EAP_STATES };
1918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return (state_names[(int)esc]);
1938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
1948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
1968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * eap_init - Initialize state for an EAP user.  This is currently
1978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * called once by main() during start-up.
1988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
1998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
2008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_init(unit)
2018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint unit;
2028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
2038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_state *esp = &eap_states[unit];
2048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	BZERO(esp, sizeof (*esp));
2068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_unit = unit;
2078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_timeout = EAP_DEFTIMEOUT;
2088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_maxrequests = EAP_DEFTRANSMITS;
2098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_id = (u_char)(drand48() * 0x100);
2108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_timeout = EAP_DEFREQTIME;
2118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
2128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * eap_client_timeout - Give up waiting for the peer to send any
2168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Request messages.
2178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
2198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_client_timeout(arg)
2208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid *arg;
2218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
2228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_state *esp = (eap_state *) arg;
2238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!eap_client_active(esp))
2258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return;
2268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("EAP: timeout waiting for Request from peer");
2288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	auth_withpeer_fail(esp->es_unit, PPP_EAP);
2298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_state = eapBadAuth;
2308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * eap_authwithpeer - Authenticate to our peer (behave as client).
2348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
2358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Start client state and wait for requests.  This is called only
2368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * after eap_lowerup.
2378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
2398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_authwithpeer(unit, localname)
2408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint unit;
2418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar *localname;
2428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
2438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_state *esp = &eap_states[unit];
2448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Save the peer name we're given */
2468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_name = localname;
2478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_namelen = strlen(localname);
2488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_state = eapListen;
2508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
2528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Start a timer so that if the other end just goes
2538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * silent, we don't sit here waiting forever.
2548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
2558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (esp->es_client.ea_timeout > 0)
2568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		TIMEOUT(eap_client_timeout, (void *)esp,
2578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    esp->es_client.ea_timeout);
2588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Format a standard EAP Failure message and send it to the peer.
2628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * (Server operation)
2638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
2658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_send_failure(esp)
2668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_state *esp;
2678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
2688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char *outp;
2698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	outp = outpacket_buf;
2718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	MAKEHEADER(outp, PPP_EAP);
2738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(EAP_FAILURE, outp);
2758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_id++;
2768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(esp->es_server.ea_id, outp);
2778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTSHORT(EAP_HEADERLEN, outp);
2788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN);
2808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_state = eapBadAuth;
2828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	auth_peer_fail(esp->es_unit, PPP_EAP);
2838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Format a standard EAP Success message and send it to the peer.
2878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * (Server operation)
2888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
2908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_send_success(esp)
2918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_state *esp;
2928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
2938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char *outp;
2948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	outp = outpacket_buf;
2968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	MAKEHEADER(outp, PPP_EAP);
2988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(EAP_SUCCESS, outp);
3008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_id++;
3018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(esp->es_server.ea_id, outp);
3028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTSHORT(EAP_HEADERLEN, outp);
3038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN);
3058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	auth_peer_success(esp->es_unit, PPP_EAP, 0,
3078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    esp->es_server.ea_peer, esp->es_server.ea_peerlen);
3088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
3098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
3118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
3128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Set DES key according to pseudonym-generating secret and current
3138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * date.
3148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
3158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic bool
3168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectpncrypt_setkey(int timeoffs)
3178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	struct tm *tp;
3198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	char tbuf[9];
3208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	SHA1_CTX ctxt;
3218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char dig[SHA_DIGESTSIZE];
3228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	time_t reftime;
3238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (pn_secret == NULL)
3258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return (0);
3268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	reftime = time(NULL) + timeoffs;
3278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	tp = localtime(&reftime);
3288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	SHA1Init(&ctxt);
3298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	SHA1Update(&ctxt, pn_secret, strlen(pn_secret));
3308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
3318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	SHA1Update(&ctxt, tbuf, strlen(tbuf));
3328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	SHA1Final(dig, &ctxt);
3338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return (DesSetkey(dig));
3348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
3358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char base64[] =
3378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
3388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstruct b64state {
3408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_int32_t bs_bits;
3418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int bs_offs;
3428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
3438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
3458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectb64enc(bs, inp, inlen, outp)
3468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstruct b64state *bs;
3478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *inp;
3488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint inlen;
3498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *outp;
3508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int outlen = 0;
3528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	while (inlen > 0) {
3548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		bs->bs_bits = (bs->bs_bits << 8) | *inp++;
3558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		inlen--;
3568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		bs->bs_offs += 8;
3578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (bs->bs_offs >= 24) {
3588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			*outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
3598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			*outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
3608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			*outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
3618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			*outp++ = base64[bs->bs_bits & 0x3F];
3628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			outlen += 4;
3638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			bs->bs_offs = 0;
3648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			bs->bs_bits = 0;
3658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
3668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
3678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return (outlen);
3688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
3698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
3718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectb64flush(bs, outp)
3728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstruct b64state *bs;
3738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *outp;
3748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int outlen = 0;
3768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (bs->bs_offs == 8) {
3788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		*outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
3798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		*outp++ = base64[(bs->bs_bits << 4) & 0x3F];
3808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		outlen = 2;
3818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else if (bs->bs_offs == 16) {
3828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		*outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
3838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		*outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
3848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		*outp++ = base64[(bs->bs_bits << 2) & 0x3F];
3858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		outlen = 3;
3868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
3878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	bs->bs_offs = 0;
3888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	bs->bs_bits = 0;
3898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return (outlen);
3908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
3918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
3938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectb64dec(bs, inp, inlen, outp)
3948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstruct b64state *bs;
3958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *inp;
3968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint inlen;
3978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *outp;
3988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int outlen = 0;
4008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	char *cp;
4018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	while (inlen > 0) {
4038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if ((cp = strchr(base64, *inp++)) == NULL)
4048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
4058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
4068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		inlen--;
4078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		bs->bs_offs += 6;
4088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (bs->bs_offs >= 8) {
4098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			*outp++ = bs->bs_bits >> (bs->bs_offs - 8);
4108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			outlen++;
4118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			bs->bs_offs -= 8;
4128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
4138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
4148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return (outlen);
4158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_SRP */
4178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Assume that current waiting server state is complete and figure
4208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * next state to use based on available authentication data.  'status'
4218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * indicates if there was an error in handling the last query.  It is
4228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 0 for success and non-zero for failure.
4238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
4258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_figure_next_state(esp, status)
4268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_state *esp;
4278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint status;
4288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
4308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp;
4318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	struct t_pw tpw;
4328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	struct t_confent *tce, mytce;
4338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	char *cp, *cp2;
4348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	struct t_server *ts;
4358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int id, i, plen, toffs;
4368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char vals[2];
4378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	struct b64state bs;
4388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_SRP */
4398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_timeout = esp->es_savedtime;
4418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	switch (esp->es_server.ea_state) {
4428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case eapBadAuth:
4438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return;
4448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case eapIdentify:
4468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
4478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* Discard any previous session. */
4488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ts = (struct t_server *)esp->es_server.ea_session;
4498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (ts != NULL) {
4508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			t_serverclose(ts);
4518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_session = NULL;
4528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_skey = NULL;
4538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
4548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_SRP */
4558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (status != 0) {
4568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_state = eapBadAuth;
4578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
4588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
4598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
4608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* If we've got a pseudonym, try to decode to real name. */
4618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN &&
4628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID,
4638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			SRP_PSEUDO_LEN) == 0 &&
4648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    (esp->es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
4658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    sizeof (secbuf)) {
4668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			BZERO(&bs, sizeof (bs));
4678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			plen = b64dec(&bs,
4688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    esp->es_server.ea_peer + SRP_PSEUDO_LEN,
4698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    esp->es_server.ea_peerlen - SRP_PSEUDO_LEN,
4708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    secbuf);
4718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			toffs = 0;
4728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			for (i = 0; i < 5; i++) {
4738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				pncrypt_setkey(toffs);
4748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				toffs -= 86400;
4758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (!DesDecrypt(secbuf, clear)) {
4768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					dbglog("no DES here; cannot decode "
4778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					    "pseudonym");
4788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					return;
4798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
4808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				id = *(unsigned char *)clear;
4818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (id + 1 <= plen && id + 9 > plen)
4828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					break;
4838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
4848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (plen % 8 == 0 && i < 5) {
4858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				/*
4868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 * Note that this is always shorter than the
4878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 * original stored string, so there's no need
4888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 * to realloc.
4898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 */
4908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if ((i = plen = *(unsigned char *)clear) > 7)
4918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					i = 7;
4928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				esp->es_server.ea_peerlen = plen;
4938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				dp = (unsigned char *)esp->es_server.ea_peer;
4948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				BCOPY(clear + 1, dp, i);
4958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				plen -= i;
4968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				dp += i;
4978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				sp = secbuf + 8;
4988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				while (plen > 0) {
4998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					(void) DesDecrypt(sp, dp);
5008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					sp += 8;
5018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					dp += 8;
5028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					plen -= 8;
5038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
5048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				esp->es_server.ea_peer[
5058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					esp->es_server.ea_peerlen] = '\0';
5068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				dbglog("decoded pseudonym to \"%.*q\"",
5078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    esp->es_server.ea_peerlen,
5088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    esp->es_server.ea_peer);
5098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			} else {
5108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				dbglog("failed to decode real name");
5118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				/* Stay in eapIdentfy state; requery */
5128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
5138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
5148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
5158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* Look up user in secrets database. */
5168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer,
5178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    esp->es_server.ea_name, (char *)secbuf, 1) != 0) {
5188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* Set up default in case SRP entry is bad */
5198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_state = eapMD5Chall;
5208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* Get t_confent based on index in srp-secrets */
5218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			id = strtol((char *)secbuf, &cp, 10);
5228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (*cp++ != ':' || id < 0)
5238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
5248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (id == 0) {
5258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				mytce.index = 0;
5268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				mytce.modulus.data = (u_char *)wkmodulus;
5278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				mytce.modulus.len = sizeof (wkmodulus);
5288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				mytce.generator.data = (u_char *)"\002";
5298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				mytce.generator.len = 1;
5308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				tce = &mytce;
5318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			} else if ((tce = gettcid(id)) != NULL) {
5328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				/*
5338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 * Client will have to verify this modulus/
5348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 * generator combination, and that will take
5358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 * a while.  Lengthen the timeout here.
5368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 */
5378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (esp->es_server.ea_timeout > 0 &&
5388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    esp->es_server.ea_timeout < 30)
5398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					esp->es_server.ea_timeout = 30;
5408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			} else {
5418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
5428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
5438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if ((cp2 = strchr(cp, ':')) == NULL)
5448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
5458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			*cp2++ = '\0';
5468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			tpw.pebuf.name = esp->es_server.ea_peer;
5478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
5488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    cp);
5498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			tpw.pebuf.password.data = tpw.pwbuf;
5508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
5518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    cp2);
5528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			tpw.pebuf.salt.data = tpw.saltbuf;
5538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
5548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
5558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_session = (void *)ts;
5568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_state = eapSRP1;
5578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			vals[0] = esp->es_server.ea_id + 1;
5588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			vals[1] = EAPT_SRP;
5598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			t_serveraddexdata(ts, vals, 2);
5608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* Generate B; must call before t_servergetkey() */
5618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			t_servergenexp(ts);
5628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
5638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
5648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_SRP */
5658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		esp->es_server.ea_state = eapMD5Chall;
5668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
5678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case eapSRP1:
5698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
5708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ts = (struct t_server *)esp->es_server.ea_session;
5718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (ts != NULL && status != 0) {
5728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			t_serverclose(ts);
5738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_session = NULL;
5748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_skey = NULL;
5758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
5768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_SRP */
5778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (status == 1) {
5788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_state = eapMD5Chall;
5798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else if (status != 0 || esp->es_server.ea_session == NULL) {
5808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_state = eapBadAuth;
5818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else {
5828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_state = eapSRP2;
5838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
5848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
5858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case eapSRP2:
5878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
5888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ts = (struct t_server *)esp->es_server.ea_session;
5898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (ts != NULL && status != 0) {
5908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			t_serverclose(ts);
5918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_session = NULL;
5928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_skey = NULL;
5938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
5948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_SRP */
5958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (status != 0 || esp->es_server.ea_session == NULL) {
5968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_state = eapBadAuth;
5978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else {
5988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_state = eapSRP3;
5998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
6008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
6018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case eapSRP3:
6038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case eapSRP4:
6048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
6058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ts = (struct t_server *)esp->es_server.ea_session;
6068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (ts != NULL && status != 0) {
6078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			t_serverclose(ts);
6088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_session = NULL;
6098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_skey = NULL;
6108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
6118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_SRP */
6128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (status != 0 || esp->es_server.ea_session == NULL) {
6138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_state = eapBadAuth;
6148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else {
6158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_state = eapOpen;
6168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
6178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
6188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case eapMD5Chall:
6208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (status != 0) {
6218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_state = eapBadAuth;
6228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else {
6238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_state = eapOpen;
6248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
6258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
6268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	default:
6288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		esp->es_server.ea_state = eapBadAuth;
6298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
6308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
6318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (esp->es_server.ea_state == eapBadAuth)
6328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		eap_send_failure(esp);
6338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
6348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
6368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Format an EAP Request message and send it to the peer.  Message
6378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * type depends on current state.  (Server operation)
6388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
6398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
6408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_send_request(esp)
6418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_state *esp;
6428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
6438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char *outp;
6448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char *lenloc;
6458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char *ptr;
6468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int outlen;
6478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int challen;
6488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	char *str;
6498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
6508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	struct t_server *ts;
6518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;
6528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int i, j;
6538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	struct b64state b64;
6548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	SHA1_CTX ctxt;
6558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_SRP */
6568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Handle both initial auth and restart */
6588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (esp->es_server.ea_state < eapIdentify &&
6598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    esp->es_server.ea_state != eapInitial) {
6608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		esp->es_server.ea_state = eapIdentify;
6618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (explicit_remote) {
6628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/*
6638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			 * If we already know the peer's
6648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			 * unauthenticated name, then there's no
6658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			 * reason to ask.  Go to next state instead.
6668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			 */
6678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_peer = remote_name;
6688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_peerlen = strlen(remote_name);
6698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_figure_next_state(esp, 0);
6708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
6718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
6728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (esp->es_server.ea_maxrequests > 0 &&
6748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) {
6758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (esp->es_server.ea_responses > 0)
6768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			error("EAP: too many Requests sent");
6778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		else
6788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			error("EAP: no response to Requests");
6798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		eap_send_failure(esp);
6808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return;
6818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
6828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	outp = outpacket_buf;
6848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	MAKEHEADER(outp, PPP_EAP);
6868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(EAP_REQUEST, outp);
6888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(esp->es_server.ea_id, outp);
6898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	lenloc = outp;
6908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(2, outp);
6918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	switch (esp->es_server.ea_state) {
6938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case eapIdentify:
6948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(EAPT_IDENTITY, outp);
6958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		str = "Name";
6968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		challen = strlen(str);
6978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		BCOPY(str, outp, challen);
6988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		INCPTR(challen, outp);
6998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
7008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case eapMD5Chall:
7028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(EAPT_MD5CHAP, outp);
7038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/*
7048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * pick a random challenge length between
7058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH
7068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 */
7078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		challen = (drand48() *
7088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
7098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    MIN_CHALLENGE_LENGTH;
7108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(challen, outp);
7118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		esp->es_challen = challen;
7128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ptr = esp->es_challenge;
7138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		while (--challen >= 0)
7148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			*ptr++ = (u_char) (drand48() * 0x100);
7158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		BCOPY(esp->es_challenge, outp, esp->es_challen);
7168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		INCPTR(esp->es_challen, outp);
7178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
7188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		INCPTR(esp->es_server.ea_namelen, outp);
7198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
7208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
7228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case eapSRP1:
7238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(EAPT_SRP, outp);
7248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(EAPSRP_CHALLENGE, outp);
7258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(esp->es_server.ea_namelen, outp);
7278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
7288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		INCPTR(esp->es_server.ea_namelen, outp);
7298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ts = (struct t_server *)esp->es_server.ea_session;
7318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		assert(ts != NULL);
7328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(ts->s.len, outp);
7338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		BCOPY(ts->s.data, outp, ts->s.len);
7348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		INCPTR(ts->s.len, outp);
7358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (ts->g.len == 1 && ts->g.data[0] == 2) {
7378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTCHAR(0, outp);
7388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else {
7398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			PUTCHAR(ts->g.len, outp);
7408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			BCOPY(ts->g.data, outp, ts->g.len);
7418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			INCPTR(ts->g.len, outp);
7428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
7438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (ts->n.len != sizeof (wkmodulus) ||
7458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
7468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			BCOPY(ts->n.data, outp, ts->n.len);
7478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			INCPTR(ts->n.len, outp);
7488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
7498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
7508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case eapSRP2:
7528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(EAPT_SRP, outp);
7538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(EAPSRP_SKEY, outp);
7548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ts = (struct t_server *)esp->es_server.ea_session;
7568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		assert(ts != NULL);
7578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		BCOPY(ts->B.data, outp, ts->B.len);
7588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		INCPTR(ts->B.len, outp);
7598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
7608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case eapSRP3:
7628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(EAPT_SRP, outp);
7638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(EAPSRP_SVALIDATOR, outp);
7648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTLONG(SRPVAL_EBIT, outp);
7658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ts = (struct t_server *)esp->es_server.ea_session;
7668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		assert(ts != NULL);
7678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		BCOPY(t_serverresponse(ts), outp, SHA_DIGESTSIZE);
7688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		INCPTR(SHA_DIGESTSIZE, outp);
7698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (pncrypt_setkey(0)) {
7718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* Generate pseudonym */
7728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			optr = outp;
7738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			cp = (unsigned char *)esp->es_server.ea_peer;
7748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if ((j = i = esp->es_server.ea_peerlen) > 7)
7758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				j = 7;
7768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			clear[0] = i;
7778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			BCOPY(cp, clear + 1, j);
7788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			i -= j;
7798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			cp += j;
7808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (!DesEncrypt(clear, cipher)) {
7818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				dbglog("no DES here; not generating pseudonym");
7828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
7838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
7848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			BZERO(&b64, sizeof (b64));
7858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			outp++;		/* space for pseudonym length */
7868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			outp += b64enc(&b64, cipher, 8, outp);
7878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			while (i >= 8) {
7888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				(void) DesEncrypt(cp, cipher);
7898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				outp += b64enc(&b64, cipher, 8, outp);
7908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				cp += 8;
7918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				i -= 8;
7928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
7938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (i > 0) {
7948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				BCOPY(cp, clear, i);
7958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				cp += i;
7968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				while (i < 8) {
7978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					*cp++ = drand48() * 0x100;
7988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					i++;
7998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
8008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				(void) DesEncrypt(clear, cipher);
8018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				outp += b64enc(&b64, cipher, 8, outp);
8028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
8038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			outp += b64flush(&b64, outp);
8048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* Set length and pad out to next 20 octet boundary */
8068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			i = outp - optr - 1;
8078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			*optr = i;
8088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			i %= SHA_DIGESTSIZE;
8098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (i != 0) {
8108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				while (i < SHA_DIGESTSIZE) {
8118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					*outp++ = drand48() * 0x100;
8128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					i++;
8138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
8148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
8158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* Obscure the pseudonym with SHA1 hash */
8178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			SHA1Init(&ctxt);
8188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
8198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			SHA1Update(&ctxt, esp->es_server.ea_skey,
8208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    SESSION_KEY_LEN);
8218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			SHA1Update(&ctxt, esp->es_server.ea_peer,
8228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    esp->es_server.ea_peerlen);
8238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			while (optr < outp) {
8248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				SHA1Final(dig, &ctxt);
8258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				cp = dig;
8268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				while (cp < dig + SHA_DIGESTSIZE)
8278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					*optr++ ^= *cp++;
8288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				SHA1Init(&ctxt);
8298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
8308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				SHA1Update(&ctxt, esp->es_server.ea_skey,
8318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    SESSION_KEY_LEN);
8328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,
8338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    SHA_DIGESTSIZE);
8348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
8358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
8368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
8378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case eapSRP4:
8398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(EAPT_SRP, outp);
8408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
8418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		challen = MIN_CHALLENGE_LENGTH +
8428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48());
8438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		esp->es_challen = challen;
8448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ptr = esp->es_challenge;
8458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		while (--challen >= 0)
8468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			*ptr++ = drand48() * 0x100;
8478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		BCOPY(esp->es_challenge, outp, esp->es_challen);
8488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		INCPTR(esp->es_challen, outp);
8498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
8508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_SRP */
8518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	default:
8538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return;
8548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
8558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	outlen = (outp - outpacket_buf) - PPP_HDRLEN;
8578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTSHORT(outlen, lenloc);
8588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
8608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_requests++;
8628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (esp->es_server.ea_timeout > 0)
8648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
8658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
8668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
8688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * eap_authpeer - Authenticate our peer (behave as server).
8698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
8708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Start server state and send first request.  This is called only
8718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * after eap_lowerup.
8728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
8738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
8748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_authpeer(unit, localname)
8758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint unit;
8768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar *localname;
8778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
8788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_state *esp = &eap_states[unit];
8798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Save the name we're given. */
8818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_name = localname;
8828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_namelen = strlen(localname);
8838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_savedtime = esp->es_server.ea_timeout;
8858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Lower layer up yet? */
8878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (esp->es_server.ea_state == eapInitial ||
8888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    esp->es_server.ea_state == eapPending) {
8898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		esp->es_server.ea_state = eapPending;
8908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return;
8918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
8928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_state = eapPending;
8948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* ID number not updated here intentionally; hashed into M1 */
8968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_send_request(esp);
8978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
8988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
9008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * eap_server_timeout - Retransmission timer for sending Requests
9018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * expired.
9028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
9038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
9048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_server_timeout(arg)
9058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid *arg;
9068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
9078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_state *esp = (eap_state *) arg;
9088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!eap_server_active(esp))
9108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return;
9118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* EAP ID number must not change on timeout. */
9138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_send_request(esp);
9148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
9158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
9178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * When it's time to send rechallenge the peer, this timeout is
9188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * called.  Once the rechallenge is successful, the response handler
9198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * will restart the timer.  If it fails, then the link is dropped.
9208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
9218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
9228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_rechallenge(arg)
9238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid *arg;
9248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
9258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_state *esp = (eap_state *)arg;
9268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (esp->es_server.ea_state != eapOpen &&
9288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    esp->es_server.ea_state != eapSRP4)
9298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return;
9308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_requests = 0;
9328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_state = eapIdentify;
9338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_figure_next_state(esp, 0);
9348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_id++;
9358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_send_request(esp);
9368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
9378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
9398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsrp_lwrechallenge(arg)
9408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid *arg;
9418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
9428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_state *esp = (eap_state *)arg;
9438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (esp->es_server.ea_state != eapOpen ||
9458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    esp->es_server.ea_type != EAPT_SRP)
9468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return;
9478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_requests = 0;
9498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_state = eapSRP4;
9508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_id++;
9518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_send_request(esp);
9528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
9538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
9558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * eap_lowerup - The lower layer is now up.
9568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
9578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This is called before either eap_authpeer or eap_authwithpeer.  See
9588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * link_established() in auth.c.  All that's necessary here is to
9598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * return to closed state so that those two routines will do the right
9608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * thing.
9618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
9628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
9638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_lowerup(unit)
9648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint unit;
9658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
9668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_state *esp = &eap_states[unit];
9678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Discard any (possibly authenticated) peer name. */
9698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (esp->es_server.ea_peer != NULL &&
9708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    esp->es_server.ea_peer != remote_name)
9718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		free(esp->es_server.ea_peer);
9728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_peer = NULL;
9738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (esp->es_client.ea_peer != NULL)
9748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		free(esp->es_client.ea_peer);
9758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_peer = NULL;
9768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_state = eapClosed;
9788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_state = eapClosed;
9798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
9808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
9828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * eap_lowerdown - The lower layer is now down.
9838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
9848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Cancel all timeouts and return to initial state.
9858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
9868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
9878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_lowerdown(unit)
9888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint unit;
9898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
9908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_state *esp = &eap_states[unit];
9918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) {
9938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		UNTIMEOUT(eap_client_timeout, (void *)esp);
9948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
9958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (eap_server_active(esp)) {
9968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (esp->es_server.ea_timeout > 0) {
9978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			UNTIMEOUT(eap_server_timeout, (void *)esp);
9988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
9998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else {
10008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if ((esp->es_server.ea_state == eapOpen ||
10018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    esp->es_server.ea_state == eapSRP4) &&
10028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    esp->es_rechallenge > 0) {
10038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			UNTIMEOUT(eap_rechallenge, (void *)esp);
10048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
10058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (esp->es_server.ea_state == eapOpen &&
10068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    esp->es_lwrechallenge > 0) {
10078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			UNTIMEOUT(srp_lwrechallenge, (void *)esp);
10088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
10098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
10108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_state = esp->es_server.ea_state = eapInitial;
10128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_requests = esp->es_server.ea_requests = 0;
10138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
10148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
10168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * eap_protrej - Peer doesn't speak this protocol.
10178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
10188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This shouldn't happen.  If it does, it represents authentication
10198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * failure.
10208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
10218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
10228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_protrej(unit)
10238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint unit;
10248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
10258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_state *esp = &eap_states[unit];
10268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (eap_client_active(esp)) {
10288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("EAP authentication failed due to Protocol-Reject");
10298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		auth_withpeer_fail(unit, PPP_EAP);
10308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
10318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (eap_server_active(esp)) {
10328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("EAP authentication of peer failed on Protocol-Reject");
10338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		auth_peer_fail(unit, PPP_EAP);
10348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
10358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_lowerdown(unit);
10368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
10378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
10398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Format and send a regular EAP Response message.
10408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
10418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
10428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_send_response(esp, id, typenum, str, lenstr)
10438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_state *esp;
10448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char id;
10458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char typenum;
10468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *str;
10478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint lenstr;
10488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
10498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char *outp;
10508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int msglen;
10518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	outp = outpacket_buf;
10538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	MAKEHEADER(outp, PPP_EAP);
10558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(EAP_RESPONSE, outp);
10578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(id, outp);
10588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_id = id;
10598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr;
10608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTSHORT(msglen, outp);
10618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(typenum, outp);
10628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (lenstr > 0) {
10638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		BCOPY(str, outp, lenstr);
10648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
10658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
10678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
10688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
10708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Format and send an MD5-Challenge EAP Response message.
10718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
10728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
10738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_chap_response(esp, id, hash, name, namelen)
10748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_state *esp;
10758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char id;
10768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *hash;
10778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar *name;
10788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint namelen;
10798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
10808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char *outp;
10818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int msglen;
10828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	outp = outpacket_buf;
10848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	MAKEHEADER(outp, PPP_EAP);
10868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(EAP_RESPONSE, outp);
10888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(id, outp);
10898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_id = id;
10908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE +
10918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    namelen;
10928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTSHORT(msglen, outp);
10938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(EAPT_MD5CHAP, outp);
10948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(MD5_SIGNATURE_SIZE, outp);
10958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	BCOPY(hash, outp, MD5_SIGNATURE_SIZE);
10968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(MD5_SIGNATURE_SIZE, outp);
10978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (namelen > 0) {
10988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		BCOPY(name, outp, namelen);
10998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
11008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
11028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
11038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
11058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
11068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Format and send a SRP EAP Response message.
11078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
11088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
11098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_srp_response(esp, id, subtypenum, str, lenstr)
11108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_state *esp;
11118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char id;
11128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char subtypenum;
11138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *str;
11148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint lenstr;
11158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
11168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char *outp;
11178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int msglen;
11188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	outp = outpacket_buf;
11208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	MAKEHEADER(outp, PPP_EAP);
11228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(EAP_RESPONSE, outp);
11248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(id, outp);
11258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_id = id;
11268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr;
11278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTSHORT(msglen, outp);
11288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(EAPT_SRP, outp);
11298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(subtypenum, outp);
11308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (lenstr > 0) {
11318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		BCOPY(str, outp, lenstr);
11328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
11338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
11358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
11368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
11388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Format and send a SRP EAP Client Validator Response message.
11398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
11408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
11418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_srpval_response(esp, id, flags, str)
11428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_state *esp;
11438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char id;
11448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_int32_t flags;
11458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *str;
11468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
11478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char *outp;
11488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int msglen;
11498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	outp = outpacket_buf;
11518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	MAKEHEADER(outp, PPP_EAP);
11538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(EAP_RESPONSE, outp);
11558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(id, outp);
11568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_id = id;
11578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) +
11588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    SHA_DIGESTSIZE;
11598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTSHORT(msglen, outp);
11608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(EAPT_SRP, outp);
11618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(EAPSRP_CVALIDATOR, outp);
11628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTLONG(flags, outp);
11638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	BCOPY(str, outp, SHA_DIGESTSIZE);
11648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
11668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
11678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_SRP */
11688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
11708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_send_nak(esp, id, type)
11718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_state *esp;
11728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char id;
11738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char type;
11748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
11758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char *outp;
11768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int msglen;
11778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	outp = outpacket_buf;
11798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	MAKEHEADER(outp, PPP_EAP);
11818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(EAP_RESPONSE, outp);
11838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(id, outp);
11848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_id = id;
11858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	msglen = EAP_HEADERLEN + 2 * sizeof (u_char);
11868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTSHORT(msglen, outp);
11878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(EAPT_NAK, outp);
11888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	PUTCHAR(type, outp);
11898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
11918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
11928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
11948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char *
11958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectname_of_pn_file()
11968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
11978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	char *user, *path, *file;
11988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	struct passwd *pw;
11998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	size_t pl;
12008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	static bool pnlogged = 0;
12018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	pw = getpwuid(getuid());
12038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
12048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		errno = EINVAL;
12058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return (NULL);
12068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
12078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	file = _PATH_PSEUDONYM;
12088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	pl = strlen(user) + strlen(file) + 2;
12098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	path = malloc(pl);
12108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (path == NULL)
12118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return (NULL);
12128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	(void) slprintf(path, pl, "%s/%s", user, file);
12138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!pnlogged) {
12148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		dbglog("pseudonym file: %s", path);
12158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		pnlogged = 1;
12168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
12178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return (path);
12188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
12198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
12218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectopen_pn_file(modebits)
12228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectmode_t modebits;
12238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
12248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	char *path;
12258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int fd, err;
12268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((path = name_of_pn_file()) == NULL)
12288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return (-1);
12298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fd = open(path, modebits, S_IRUSR | S_IWUSR);
12308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	err = errno;
12318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	free(path);
12328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	errno = err;
12338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return (fd);
12348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
12358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
12378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectremove_pn_file()
12388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
12398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	char *path;
12408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((path = name_of_pn_file()) != NULL) {
12428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		(void) unlink(path);
12438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		(void) free(path);
12448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
12458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
12468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
12488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectwrite_pseudonym(esp, inp, len, id)
12498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_state *esp;
12508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *inp;
12518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint len, id;
12528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
12538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char val;
12548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char *datp, *digp;
12558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	SHA1_CTX ctxt;
12568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char dig[SHA_DIGESTSIZE];
12578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int dsize, fd, olen = len;
12588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
12608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Do the decoding by working backwards.  This eliminates the need
12618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * to save the decoded output in a separate buffer.
12628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
12638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	val = id;
12648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	while (len > 0) {
12658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if ((dsize = len % SHA_DIGESTSIZE) == 0)
12668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			dsize = SHA_DIGESTSIZE;
12678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		len -= dsize;
12688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		datp = inp + len;
12698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		SHA1Init(&ctxt);
12708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		SHA1Update(&ctxt, &val, 1);
12718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		SHA1Update(&ctxt, esp->es_client.ea_skey, SESSION_KEY_LEN);
12728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (len > 0) {
12738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			SHA1Update(&ctxt, datp, SHA_DIGESTSIZE);
12748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else {
12758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			SHA1Update(&ctxt, esp->es_client.ea_name,
12768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    esp->es_client.ea_namelen);
12778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
12788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		SHA1Final(dig, &ctxt);
12798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++)
12808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			*datp++ ^= *digp;
12818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
12828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Now check that the result is sane */
12848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (olen <= 0 || *inp + 1 > olen) {
12858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp);
12868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return;
12878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
12888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Save it away */
12908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
12918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (fd < 0) {
12928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		dbglog("EAP: error saving pseudonym: %m");
12938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return;
12948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
12958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len = write(fd, inp + 1, *inp);
12968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (close(fd) != -1 && len == *inp) {
12978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		dbglog("EAP: saved pseudonym");
12988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		esp->es_usedpseudo = 0;
12998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else {
13008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		dbglog("EAP: failed to save pseudonym");
13018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		remove_pn_file();
13028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
13038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_SRP */
13058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
13078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * eap_request - Receive EAP Request message (client mode).
13088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
13098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
13108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_request(esp, inp, id, len)
13118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_state *esp;
13128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *inp;
13138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint id;
13148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint len;
13158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
13168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char typenum;
13178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char vallen;
13188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int secret_len;
13198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	char secret[MAXWORDLEN];
13208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	char rhostname[256];
13218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	MD5_CTX mdContext;
13228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char hash[MD5_SIGNATURE_SIZE];
13238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
13248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	struct t_client *tc;
13258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	struct t_num sval, gval, Nval, *Ap, Bval;
13268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char vals[2];
13278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	SHA1_CTX ctxt;
13288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char dig[SHA_DIGESTSIZE];
13298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int fd;
13308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_SRP */
13318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
13338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Note: we update es_client.ea_id *only if* a Response
13348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * message is being generated.  Otherwise, we leave it the
13358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * same for duplicate detection purposes.
13368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
13378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_requests++;
13398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (esp->es_client.ea_maxrequests != 0 &&
13408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    esp->es_client.ea_requests > esp->es_client.ea_maxrequests) {
13418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		info("EAP: received too many Request messages");
13428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (esp->es_client.ea_timeout > 0) {
13438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			UNTIMEOUT(eap_client_timeout, (void *)esp);
13448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
13458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		auth_withpeer_fail(esp->es_unit, PPP_EAP);
13468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return;
13478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
13488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len <= 0) {
13508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("EAP: empty Request message discarded");
13518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return;
13528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
13538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(typenum, inp);
13558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len--;
13568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	switch (typenum) {
13588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EAPT_IDENTITY:
13598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (len > 0)
13608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			info("EAP: Identity prompt \"%.*q\"", len, inp);
13618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
13628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (esp->es_usepseudo &&
13638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    (esp->es_usedpseudo == 0 ||
13648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			(esp->es_usedpseudo == 1 &&
13658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    id == esp->es_client.ea_id))) {
13668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_usedpseudo = 1;
13678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* Try to get a pseudonym */
13688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if ((fd = open_pn_file(O_RDONLY)) >= 0) {
13698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				strcpy(rhostname, SRP_PSEUDO_ID);
13708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len = read(fd, rhostname + SRP_PSEUDO_LEN,
13718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    sizeof (rhostname) - SRP_PSEUDO_LEN);
13728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				/* XXX NAI unsupported */
13738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (len > 0) {
13748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					eap_send_response(esp, id, typenum,
13758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					    rhostname, len + SRP_PSEUDO_LEN);
13768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
13778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				(void) close(fd);
13788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (len > 0)
13798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					break;
13808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
13818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
13828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* Stop using pseudonym now. */
13838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (esp->es_usepseudo && esp->es_usedpseudo != 2) {
13848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			remove_pn_file();
13858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_usedpseudo = 2;
13868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
13878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_SRP */
13888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		eap_send_response(esp, id, typenum, esp->es_client.ea_name,
13898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    esp->es_client.ea_namelen);
13908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
13918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EAPT_NOTIFICATION:
13938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (len > 0)
13948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			info("EAP: Notification \"%.*q\"", len, inp);
13958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		eap_send_response(esp, id, typenum, NULL, 0);
13968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
13978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EAPT_NAK:
13998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/*
14008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * Avoid the temptation to send Response Nak in reply
14018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * to Request Nak here.  It can only lead to trouble.
14028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 */
14038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		warn("EAP: unexpected Nak in Request; ignored");
14048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* Return because we're waiting for something real. */
14058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return;
14068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EAPT_MD5CHAP:
14088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (len < 1) {
14098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			error("EAP: received MD5-Challenge with no data");
14108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* Bogus request; wait for something real. */
14118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			return;
14128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
14138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		GETCHAR(vallen, inp);
14148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		len--;
14158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (vallen < 8 || vallen > len) {
14168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			error("EAP: MD5-Challenge with bad length %d (8..%d)",
14178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    vallen, len);
14188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* Try something better. */
14198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_send_nak(esp, id, EAPT_SRP);
14208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
14218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
14228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* Not so likely to happen. */
14248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (vallen >= len + sizeof (rhostname)) {
14258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			dbglog("EAP: trimming really long peer name down");
14268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
14278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			rhostname[sizeof (rhostname) - 1] = '\0';
14288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else {
14298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			BCOPY(inp + vallen, rhostname, len - vallen);
14308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			rhostname[len - vallen] = '\0';
14318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
14328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* In case the remote doesn't give us his name. */
14348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (explicit_remote ||
14358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    (remote_name[0] != '\0' && vallen == len))
14368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			strlcpy(rhostname, remote_name, sizeof (rhostname));
14378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/*
14398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * Get the secret for authenticating ourselves with
14408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * the specified host.
14418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 */
14428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (!get_secret(esp->es_unit, esp->es_client.ea_name,
14438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    rhostname, secret, &secret_len, 0)) {
14448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			dbglog("EAP: no MD5 secret for auth to %q", rhostname);
14458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_send_nak(esp, id, EAPT_SRP);
14468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
14478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
14488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		MD5_Init(&mdContext);
14498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		typenum = id;
14508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		MD5_Update(&mdContext, &typenum, 1);
14518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		MD5_Update(&mdContext, secret, secret_len);
14528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		BZERO(secret, sizeof (secret));
14538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		MD5_Update(&mdContext, inp, vallen);
14548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		MD5_Final(hash, &mdContext);
14558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		eap_chap_response(esp, id, hash, esp->es_client.ea_name,
14568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    esp->es_client.ea_namelen);
14578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
14588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
14608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EAPT_SRP:
14618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (len < 1) {
14628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			error("EAP: received empty SRP Request");
14638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* Bogus request; wait for something real. */
14648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			return;
14658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
14668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* Get subtype */
14688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		GETCHAR(vallen, inp);
14698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		len--;
14708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		switch (vallen) {
14718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		case EAPSRP_CHALLENGE:
14728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			tc = NULL;
14738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (esp->es_client.ea_session != NULL) {
14748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				tc = (struct t_client *)esp->es_client.
14758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    ea_session;
14768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				/*
14778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 * If this is a new challenge, then start
14788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 * over with a new client session context.
14798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 * Otherwise, just resend last response.
14808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 */
14818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (id != esp->es_client.ea_id) {
14828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					t_clientclose(tc);
14838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					esp->es_client.ea_session = NULL;
14848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					tc = NULL;
14858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
14868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
14878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* No session key just yet */
14888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_client.ea_skey = NULL;
14898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (tc == NULL) {
14908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				GETCHAR(vallen, inp);
14918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len--;
14928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (vallen >= len) {
14938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					error("EAP: badly-formed SRP Challenge"
14948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					    " (name)");
14958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					/* Ignore badly-formed messages */
14968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					return;
14978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
14988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				BCOPY(inp, rhostname, vallen);
14998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				rhostname[vallen] = '\0';
15008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				INCPTR(vallen, inp);
15018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len -= vallen;
15028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				/*
15048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 * In case the remote doesn't give us his name,
15058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 * use configured name.
15068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 */
15078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (explicit_remote ||
15088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    (remote_name[0] != '\0' && vallen == 0)) {
15098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					strlcpy(rhostname, remote_name,
15108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					    sizeof (rhostname));
15118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
15128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (esp->es_client.ea_peer != NULL)
15148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					free(esp->es_client.ea_peer);
15158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				esp->es_client.ea_peer = strdup(rhostname);
15168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				esp->es_client.ea_peerlen = strlen(rhostname);
15178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				GETCHAR(vallen, inp);
15198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len--;
15208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (vallen >= len) {
15218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					error("EAP: badly-formed SRP Challenge"
15228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					    " (s)");
15238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					/* Ignore badly-formed messages */
15248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					return;
15258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
15268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				sval.data = inp;
15278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				sval.len = vallen;
15288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				INCPTR(vallen, inp);
15298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len -= vallen;
15308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				GETCHAR(vallen, inp);
15328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len--;
15338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (vallen > len) {
15348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					error("EAP: badly-formed SRP Challenge"
15358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					    " (g)");
15368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					/* Ignore badly-formed messages */
15378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					return;
15388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
15398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				/* If no generator present, then use value 2 */
15408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (vallen == 0) {
15418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					gval.data = (u_char *)"\002";
15428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					gval.len = 1;
15438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				} else {
15448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					gval.data = inp;
15458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					gval.len = vallen;
15468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
15478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				INCPTR(vallen, inp);
15488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len -= vallen;
15498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				/*
15518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 * If no modulus present, then use well-known
15528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 * value.
15538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 */
15548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (len == 0) {
15558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					Nval.data = (u_char *)wkmodulus;
15568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					Nval.len = sizeof (wkmodulus);
15578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				} else {
15588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					Nval.data = inp;
15598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					Nval.len = len;
15608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
15618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				tc = t_clientopen(esp->es_client.ea_name,
15628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    &Nval, &gval, &sval);
15638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (tc == NULL) {
15648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					eap_send_nak(esp, id, EAPT_MD5CHAP);
15658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					break;
15668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
15678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				esp->es_client.ea_session = (void *)tc;
15688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				/* Add Challenge ID & type to verifier */
15708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				vals[0] = id;
15718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				vals[1] = EAPT_SRP;
15728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				t_clientaddexdata(tc, vals, 2);
15738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
15748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			Ap = t_clientgenexp(tc);
15758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data,
15768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    Ap->len);
15778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
15788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		case EAPSRP_SKEY:
15808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			tc = (struct t_client *)esp->es_client.ea_session;
15818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (tc == NULL) {
15828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				warn("EAP: peer sent Subtype 2 without 1");
15838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				eap_send_nak(esp, id, EAPT_MD5CHAP);
15848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
15858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
15868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (esp->es_client.ea_skey != NULL) {
15878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				/*
15888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 * ID number should not change here.  Warn
15898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 * if it does (but otherwise ignore).
15908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 */
15918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (id != esp->es_client.ea_id) {
15928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					warn("EAP: ID changed from %d to %d "
15938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					    "in SRP Subtype 2 rexmit",
15948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					    esp->es_client.ea_id, id);
15958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
15968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			} else {
15978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (get_srp_secret(esp->es_unit,
15988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    esp->es_client.ea_name,
15998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    esp->es_client.ea_peer, secret, 0) == 0) {
16008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					/*
16018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					 * Can't work with this peer because
16028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					 * the secret is missing.  Just give
16038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					 * up.
16048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					 */
16058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					eap_send_nak(esp, id, EAPT_MD5CHAP);
16068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					break;
16078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
16088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				Bval.data = inp;
16098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				Bval.len = len;
16108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				t_clientpasswd(tc, secret);
16118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				BZERO(secret, sizeof (secret));
16128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				esp->es_client.ea_skey =
16138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    t_clientgetkey(tc, &Bval);
16148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (esp->es_client.ea_skey == NULL) {
16158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					/* Server is rogue; stop now */
16168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					error("EAP: SRP server is rogue");
16178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					goto client_failure;
16188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
16198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
16208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_srpval_response(esp, id, SRPVAL_EBIT,
16218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    t_clientresponse(tc));
16228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
16238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		case EAPSRP_SVALIDATOR:
16258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			tc = (struct t_client *)esp->es_client.ea_session;
16268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (tc == NULL || esp->es_client.ea_skey == NULL) {
16278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				warn("EAP: peer sent Subtype 3 without 1/2");
16288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				eap_send_nak(esp, id, EAPT_MD5CHAP);
16298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
16308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
16318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/*
16328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			 * If we're already open, then this ought to be a
16338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			 * duplicate.  Otherwise, check that the server is
16348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			 * who we think it is.
16358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			 */
16368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (esp->es_client.ea_state == eapOpen) {
16378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (id != esp->es_client.ea_id) {
16388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					warn("EAP: ID changed from %d to %d "
16398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					    "in SRP Subtype 3 rexmit",
16408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					    esp->es_client.ea_id, id);
16418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
16428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			} else {
16438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len -= sizeof (u_int32_t) + SHA_DIGESTSIZE;
16448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (len < 0 || t_clientverify(tc, inp +
16458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					sizeof (u_int32_t)) != 0) {
16468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					error("EAP: SRP server verification "
16478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					    "failed");
16488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					goto client_failure;
16498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
16508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				GETLONG(esp->es_client.ea_keyflags, inp);
16518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				/* Save pseudonym if user wants it. */
16528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (len > 0 && esp->es_usepseudo) {
16538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					INCPTR(SHA_DIGESTSIZE, inp);
16548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					write_pseudonym(esp, inp, len, id);
16558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
16568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
16578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/*
16588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			 * We've verified our peer.  We're now mostly done,
16598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			 * except for waiting on the regular EAP Success
16608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			 * message.
16618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			 */
16628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0);
16638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
16648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		case EAPSRP_LWRECHALLENGE:
16668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (len < 4) {
16678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				warn("EAP: malformed Lightweight rechallenge");
16688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				return;
16698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
16708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			SHA1Init(&ctxt);
16718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			vals[0] = id;
16728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			SHA1Update(&ctxt, vals, 1);
16738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			SHA1Update(&ctxt, esp->es_client.ea_skey,
16748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    SESSION_KEY_LEN);
16758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			SHA1Update(&ctxt, inp, len);
16768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			SHA1Update(&ctxt, esp->es_client.ea_name,
16778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    esp->es_client.ea_namelen);
16788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			SHA1Final(dig, &ctxt);
16798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
16808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    SHA_DIGESTSIZE);
16818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
16828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		default:
16848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			error("EAP: unknown SRP Subtype %d", vallen);
16858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_send_nak(esp, id, EAPT_MD5CHAP);
16868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
16878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
16888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
16898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_SRP */
16908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	default:
16928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		info("EAP: unknown authentication type %d; Naking", typenum);
16938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		eap_send_nak(esp, id, EAPT_SRP);
16948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
16958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
16968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (esp->es_client.ea_timeout > 0) {
16988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		UNTIMEOUT(eap_client_timeout, (void *)esp);
16998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		TIMEOUT(eap_client_timeout, (void *)esp,
17008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    esp->es_client.ea_timeout);
17018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
17028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
17038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
17058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectclient_failure:
17068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_state = eapBadAuth;
17078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (esp->es_client.ea_timeout > 0) {
17088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		UNTIMEOUT(eap_client_timeout, (void *)esp);
17098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
17108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_session = NULL;
17118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	t_clientclose(tc);
17128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	auth_withpeer_fail(esp->es_unit, PPP_EAP);
17138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_SRP */
17148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
17158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
17178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * eap_response - Receive EAP Response message (server mode).
17188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
17198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
17208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_response(esp, inp, id, len)
17218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_state *esp;
17228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *inp;
17238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint id;
17248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint len;
17258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
17268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char typenum;
17278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char vallen;
17288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int secret_len;
17298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	char secret[MAXSECRETLEN];
17308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	char rhostname[256];
17318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	MD5_CTX mdContext;
17328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char hash[MD5_SIGNATURE_SIZE];
17338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
17348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	struct t_server *ts;
17358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	struct t_num A;
17368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	SHA1_CTX ctxt;
17378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char dig[SHA_DIGESTSIZE];
17388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_SRP */
17398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (esp->es_server.ea_id != id) {
17418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		dbglog("EAP: discarding Response %d; expected ID %d", id,
17428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    esp->es_server.ea_id);
17438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return;
17448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
17458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_server.ea_responses++;
17478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len <= 0) {
17498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("EAP: empty Response message discarded");
17508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return;
17518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
17528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(typenum, inp);
17548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len--;
17558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	switch (typenum) {
17578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EAPT_IDENTITY:
17588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (esp->es_server.ea_state != eapIdentify) {
17598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			dbglog("EAP discarding unwanted Identify \"%.q\"", len,
17608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    inp);
17618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
17628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
17638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		info("EAP: unauthenticated peer name \"%.*q\"", len, inp);
17648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (esp->es_server.ea_peer != NULL &&
17658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    esp->es_server.ea_peer != remote_name)
17668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			free(esp->es_server.ea_peer);
17678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		esp->es_server.ea_peer = malloc(len + 1);
17688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (esp->es_server.ea_peer == NULL) {
17698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_peerlen = 0;
17708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_figure_next_state(esp, 1);
17718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
17728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
17738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		BCOPY(inp, esp->es_server.ea_peer, len);
17748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		esp->es_server.ea_peer[len] = '\0';
17758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		esp->es_server.ea_peerlen = len;
17768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		eap_figure_next_state(esp, 0);
17778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
17788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EAPT_NOTIFICATION:
17808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		dbglog("EAP unexpected Notification; response discarded");
17818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
17828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EAPT_NAK:
17848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (len < 1) {
17858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			info("EAP: Nak Response with no suggested protocol");
17868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_figure_next_state(esp, 1);
17878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
17888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
17898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		GETCHAR(vallen, inp);
17918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		len--;
17928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (!explicit_remote && esp->es_server.ea_state == eapIdentify){
17948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* Peer cannot Nak Identify Request */
17958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_figure_next_state(esp, 1);
17968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
17978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
17988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		switch (vallen) {
18008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		case EAPT_SRP:
18018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			/* Run through SRP validator selection again. */
18028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_state = eapIdentify;
18038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_figure_next_state(esp, 0);
18048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
18058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		case EAPT_MD5CHAP:
18078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_state = eapMD5Chall;
18088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
18098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		default:
18118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			dbglog("EAP: peer requesting unknown Type %d", vallen);
18128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			switch (esp->es_server.ea_state) {
18138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			case eapSRP1:
18148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			case eapSRP2:
18158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			case eapSRP3:
18168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				esp->es_server.ea_state = eapMD5Chall;
18178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
18188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			case eapMD5Chall:
18198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			case eapSRP4:
18208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				esp->es_server.ea_state = eapIdentify;
18218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				eap_figure_next_state(esp, 0);
18228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
18238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			default:
18248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
18258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
18268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
18278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
18288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
18298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EAPT_MD5CHAP:
18318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (esp->es_server.ea_state != eapMD5Chall) {
18328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			error("EAP: unexpected MD5-Response");
18338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_figure_next_state(esp, 1);
18348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
18358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
18368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (len < 1) {
18378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			error("EAP: received MD5-Response with no data");
18388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_figure_next_state(esp, 1);
18398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
18408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
18418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		GETCHAR(vallen, inp);
18428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		len--;
18438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (vallen != 16 || vallen > len) {
18448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			error("EAP: MD5-Response with bad length %d", vallen);
18458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_figure_next_state(esp, 1);
18468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
18478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
18488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* Not so likely to happen. */
18508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (vallen >= len + sizeof (rhostname)) {
18518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			dbglog("EAP: trimming really long peer name down");
18528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
18538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			rhostname[sizeof (rhostname) - 1] = '\0';
18548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else {
18558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			BCOPY(inp + vallen, rhostname, len - vallen);
18568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			rhostname[len - vallen] = '\0';
18578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
18588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* In case the remote doesn't give us his name. */
18608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (explicit_remote ||
18618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    (remote_name[0] != '\0' && vallen == len))
18628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			strlcpy(rhostname, remote_name, sizeof (rhostname));
18638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/*
18658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * Get the secret for authenticating the specified
18668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 * host.
18678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 */
18688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (!get_secret(esp->es_unit, rhostname,
18698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    esp->es_server.ea_name, secret, &secret_len, 1)) {
18708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			dbglog("EAP: no MD5 secret for auth of %q", rhostname);
18718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_send_failure(esp);
18728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
18738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
18748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		MD5_Init(&mdContext);
18758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		MD5_Update(&mdContext, &esp->es_server.ea_id, 1);
18768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		MD5_Update(&mdContext, secret, secret_len);
18778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		BZERO(secret, sizeof (secret));
18788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		MD5_Update(&mdContext, esp->es_challenge, esp->es_challen);
18798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		MD5_Final(hash, &mdContext);
18808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) {
18818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_send_failure(esp);
18828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
18838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
18848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		esp->es_server.ea_type = EAPT_MD5CHAP;
18858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		eap_send_success(esp);
18868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		eap_figure_next_state(esp, 0);
18878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (esp->es_rechallenge != 0)
18888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
18898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
18908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_SRP
18928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EAPT_SRP:
18938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (len < 1) {
18948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			error("EAP: empty SRP Response");
18958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_figure_next_state(esp, 1);
18968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
18978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
18988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		GETCHAR(typenum, inp);
18998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		len--;
19008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		switch (typenum) {
19018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		case EAPSRP_CKEY:
19028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (esp->es_server.ea_state != eapSRP1) {
19038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				error("EAP: unexpected SRP Subtype 1 Response");
19048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				eap_figure_next_state(esp, 1);
19058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
19068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
19078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			A.data = inp;
19088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			A.len = len;
19098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			ts = (struct t_server *)esp->es_server.ea_session;
19108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			assert(ts != NULL);
19118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_skey = t_servergetkey(ts, &A);
19128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (esp->es_server.ea_skey == NULL) {
19138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				/* Client's A value is bogus; terminate now */
19148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				error("EAP: bogus A value from client");
19158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				eap_send_failure(esp);
19168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			} else {
19178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				eap_figure_next_state(esp, 0);
19188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
19198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
19208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		case EAPSRP_CVALIDATOR:
19228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (esp->es_server.ea_state != eapSRP2) {
19238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				error("EAP: unexpected SRP Subtype 2 Response");
19248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				eap_figure_next_state(esp, 1);
19258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
19268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
19278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (len < sizeof (u_int32_t) + SHA_DIGESTSIZE) {
19288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				error("EAP: M1 length %d < %d", len,
19298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    sizeof (u_int32_t) + SHA_DIGESTSIZE);
19308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				eap_figure_next_state(esp, 1);
19318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
19328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
19338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			GETLONG(esp->es_server.ea_keyflags, inp);
19348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			ts = (struct t_server *)esp->es_server.ea_session;
19358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			assert(ts != NULL);
19368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (t_serververify(ts, inp)) {
19378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				info("EAP: unable to validate client identity");
19388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				eap_send_failure(esp);
19398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
19408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
19418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_figure_next_state(esp, 0);
19428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
19438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		case EAPSRP_ACK:
19458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (esp->es_server.ea_state != eapSRP3) {
19468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				error("EAP: unexpected SRP Subtype 3 Response");
19478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				eap_send_failure(esp);
19488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
19498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
19508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_type = EAPT_SRP;
19518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_send_success(esp);
19528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			eap_figure_next_state(esp, 0);
19538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (esp->es_rechallenge != 0)
19548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				TIMEOUT(eap_rechallenge, esp,
19558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    esp->es_rechallenge);
19568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (esp->es_lwrechallenge != 0)
19578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				TIMEOUT(srp_lwrechallenge, esp,
19588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    esp->es_lwrechallenge);
19598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
19608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		case EAPSRP_LWRECHALLENGE:
19628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (esp->es_server.ea_state != eapSRP4) {
19638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				info("EAP: unexpected SRP Subtype 4 Response");
19648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				return;
19658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
19668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (len != SHA_DIGESTSIZE) {
19678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				error("EAP: bad Lightweight rechallenge "
19688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    "response");
19698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				return;
19708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
19718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			SHA1Init(&ctxt);
19728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			vallen = id;
19738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			SHA1Update(&ctxt, &vallen, 1);
19748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			SHA1Update(&ctxt, esp->es_server.ea_skey,
19758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    SESSION_KEY_LEN);
19768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			SHA1Update(&ctxt, esp->es_challenge, esp->es_challen);
19778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			SHA1Update(&ctxt, esp->es_server.ea_peer,
19788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    esp->es_server.ea_peerlen);
19798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			SHA1Final(dig, &ctxt);
19808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
19818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				error("EAP: failed Lightweight rechallenge");
19828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				eap_send_failure(esp);
19838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
19848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
19858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			esp->es_server.ea_state = eapOpen;
19868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (esp->es_lwrechallenge != 0)
19878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				TIMEOUT(srp_lwrechallenge, esp,
19888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    esp->es_lwrechallenge);
19898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
19908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
19918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
19928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_SRP */
19938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	default:
19958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* This can't happen. */
19968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("EAP: unknown Response type %d; ignored", typenum);
19978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return;
19988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
19998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (esp->es_server.ea_timeout > 0) {
20018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		UNTIMEOUT(eap_server_timeout, (void *)esp);
20028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
20038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (esp->es_server.ea_state != eapBadAuth &&
20058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    esp->es_server.ea_state != eapOpen) {
20068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		esp->es_server.ea_id++;
20078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		eap_send_request(esp);
20088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
20098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
20108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
20128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * eap_success - Receive EAP Success message (client mode).
20138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
20148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
20158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_success(esp, inp, id, len)
20168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_state *esp;
20178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *inp;
20188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint id;
20198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint len;
20208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
20218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)) {
20228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		dbglog("EAP unexpected success message in state %s (%d)",
20238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    eap_state_name(esp->es_client.ea_state),
20248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    esp->es_client.ea_state);
20258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return;
20268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
20278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (esp->es_client.ea_timeout > 0) {
20298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		UNTIMEOUT(eap_client_timeout, (void *)esp);
20308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
20318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len > 0) {
20338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* This is odd.  The spec doesn't allow for this. */
20348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PRINTMSG(inp, len);
20358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
20368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_state = eapOpen;
20388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	auth_withpeer_success(esp->es_unit, PPP_EAP, 0);
20398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
20408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
20428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * eap_failure - Receive EAP Failure message (client mode).
20438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
20448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
20458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_failure(esp, inp, id, len)
20468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_state *esp;
20478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *inp;
20488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint id;
20498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint len;
20508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
20518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!eap_client_active(esp)) {
20528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		dbglog("EAP unexpected failure message in state %s (%d)",
20538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    eap_state_name(esp->es_client.ea_state),
20548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    esp->es_client.ea_state);
20558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
20568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (esp->es_client.ea_timeout > 0) {
20588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		UNTIMEOUT(eap_client_timeout, (void *)esp);
20598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
20608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len > 0) {
20628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* This is odd.  The spec doesn't allow for this. */
20638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		PRINTMSG(inp, len);
20648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
20658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	esp->es_client.ea_state = eapBadAuth;
20678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("EAP: peer reports authentication failure");
20698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	auth_withpeer_fail(esp->es_unit, PPP_EAP);
20708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
20718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
20738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * eap_input - Handle received EAP message.
20748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
20758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
20768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_input(unit, inp, inlen)
20778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint unit;
20788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *inp;
20798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint inlen;
20808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
20818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eap_state *esp = &eap_states[unit];
20828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char code, id;
20838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int len;
20848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
20868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Parse header (code, id and length).  If packet too short,
20878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * drop it.
20888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
20898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (inlen < EAP_HEADERLEN) {
20908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
20918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return;
20928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
20938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(code, inp);
20948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(id, inp);
20958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(len, inp);
20968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len < EAP_HEADERLEN || len > inlen) {
20978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("EAP: packet has illegal length field %d (%d..%d)", len,
20988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    EAP_HEADERLEN, inlen);
20998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return;
21008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
21018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= EAP_HEADERLEN;
21028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Dispatch based on message code */
21048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	switch (code) {
21058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EAP_REQUEST:
21068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		eap_request(esp, inp, id, len);
21078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
21088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EAP_RESPONSE:
21108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		eap_response(esp, inp, id, len);
21118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
21128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EAP_SUCCESS:
21148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		eap_success(esp, inp, id, len);
21158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
21168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EAP_FAILURE:
21188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		eap_failure(esp, inp, id, len);
21198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
21208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	default:				/* XXX Need code reject */
21228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* Note: it's not legal to send EAP Nak here. */
21238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		warn("EAP: unknown code %d received", code);
21248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
21258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
21268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
21278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
21298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * eap_printpkt - print the contents of an EAP packet.
21308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
21318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char *eap_codenames[] = {
21328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	"Request", "Response", "Success", "Failure"
21338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
21348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char *eap_typenames[] = {
21368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	"Identity", "Notification", "Nak", "MD5-Challenge",
21378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	"OTP", "Generic-Token", NULL, NULL,
21388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	"RSA", "DSS", "KEA", "KEA-Validate",
21398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	"TLS", "Defender", "Windows 2000", "Arcot",
21408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	"Cisco", "Nokia", "SRP"
21418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
21428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
21448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecteap_printpkt(inp, inlen, printer, arg)
21458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_char *inp;
21468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint inlen;
21478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid (*printer) __P((void *, char *, ...));
21488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid *arg;
21498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
21508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int code, id, len, rtype, vallen;
21518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char *pstart;
21528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_int32_t uval;
21538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (inlen < EAP_HEADERLEN)
21558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return (0);
21568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	pstart = inp;
21578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(code, inp);
21588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETCHAR(id, inp);
21598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	GETSHORT(len, inp);
21608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len < EAP_HEADERLEN || len > inlen)
21618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return (0);
21628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *))
21648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		printer(arg, " %s", eap_codenames[code-1]);
21658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	else
21668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		printer(arg, " code=0x%x", code);
21678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	printer(arg, " id=0x%x", id);
21688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len -= EAP_HEADERLEN;
21698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	switch (code) {
21708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EAP_REQUEST:
21718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (len < 1) {
21728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, " <missing type>");
21738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
21748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
21758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		GETCHAR(rtype, inp);
21768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		len--;
21778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (rtype >= 1 &&
21788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    rtype <= sizeof (eap_typenames) / sizeof (char *))
21798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, " %s", eap_typenames[rtype-1]);
21808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		else
21818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, " type=0x%x", rtype);
21828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		switch (rtype) {
21838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		case EAPT_IDENTITY:
21848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		case EAPT_NOTIFICATION:
21858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (len > 0) {
21868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " <Message ");
21878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				print_string((char *)inp, len, printer, arg);
21888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, ">");
21898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				INCPTR(len, inp);
21908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len = 0;
21918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			} else {
21928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " <No message>");
21938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
21948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
21958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		case EAPT_MD5CHAP:
21978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (len <= 0)
21988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
21998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			GETCHAR(vallen, inp);
22008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			len--;
22018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (vallen > len)
22028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				goto truncated;
22038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, " <Value%.*B>", vallen, inp);
22048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			INCPTR(vallen, inp);
22058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			len -= vallen;
22068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (len > 0) {
22078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " <Name ");
22088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				print_string((char *)inp, len, printer, arg);
22098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, ">");
22108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				INCPTR(len, inp);
22118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len = 0;
22128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			} else {
22138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " <No name>");
22148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
22158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
22168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		case EAPT_SRP:
22188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (len < 3)
22198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				goto truncated;
22208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			GETCHAR(vallen, inp);
22218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			len--;
22228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, "-%d", vallen);
22238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			switch (vallen) {
22248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			case EAPSRP_CHALLENGE:
22258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				GETCHAR(vallen, inp);
22268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len--;
22278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (vallen >= len)
22288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					goto truncated;
22298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (vallen > 0) {
22308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					printer(arg, " <Name ");
22318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					print_string((char *)inp, vallen, printer,
22328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					    arg);
22338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					printer(arg, ">");
22348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				} else {
22358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					printer(arg, " <No name>");
22368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
22378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				INCPTR(vallen, inp);
22388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len -= vallen;
22398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				GETCHAR(vallen, inp);
22408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len--;
22418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (vallen >= len)
22428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					goto truncated;
22438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " <s%.*B>", vallen, inp);
22448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				INCPTR(vallen, inp);
22458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len -= vallen;
22468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				GETCHAR(vallen, inp);
22478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len--;
22488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (vallen > len)
22498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					goto truncated;
22508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (vallen == 0) {
22518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					printer(arg, " <Default g=2>");
22528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				} else {
22538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					printer(arg, " <g%.*B>", vallen, inp);
22548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
22558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				INCPTR(vallen, inp);
22568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len -= vallen;
22578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (len == 0) {
22588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					printer(arg, " <Default N>");
22598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				} else {
22608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					printer(arg, " <N%.*B>", len, inp);
22618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					INCPTR(len, inp);
22628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					len = 0;
22638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
22648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
22658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			case EAPSRP_SKEY:
22678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " <B%.*B>", len, inp);
22688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				INCPTR(len, inp);
22698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len = 0;
22708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
22718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			case EAPSRP_SVALIDATOR:
22738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (len < sizeof (u_int32_t))
22748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					break;
22758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				GETLONG(uval, inp);
22768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len -= sizeof (u_int32_t);
22778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (uval & SRPVAL_EBIT) {
22788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					printer(arg, " E");
22798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					uval &= ~SRPVAL_EBIT;
22808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
22818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (uval != 0) {
22828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					printer(arg, " f<%X>", uval);
22838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
22848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if ((vallen = len) > SHA_DIGESTSIZE)
22858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					vallen = SHA_DIGESTSIZE;
22868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " <M2%.*B%s>", len, inp,
22878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    len < SHA_DIGESTSIZE ? "?" : "");
22888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				INCPTR(vallen, inp);
22898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len -= vallen;
22908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (len > 0) {
22918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					printer(arg, " <PN%.*B>", len, inp);
22928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					INCPTR(len, inp);
22938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					len = 0;
22948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
22958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
22968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			case EAPSRP_LWRECHALLENGE:
22988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " <Challenge%.*B>", len, inp);
22998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				INCPTR(len, inp);
23008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len = 0;
23018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
23028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
23038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
23048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
23058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
23068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EAP_RESPONSE:
23088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (len < 1)
23098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
23108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		GETCHAR(rtype, inp);
23118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		len--;
23128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (rtype >= 1 &&
23138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    rtype <= sizeof (eap_typenames) / sizeof (char *))
23148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, " %s", eap_typenames[rtype-1]);
23158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		else
23168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, " type=0x%x", rtype);
23178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		switch (rtype) {
23188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		case EAPT_IDENTITY:
23198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (len > 0) {
23208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " <Name ");
23218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				print_string((char *)inp, len, printer, arg);
23228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, ">");
23238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				INCPTR(len, inp);
23248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len = 0;
23258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
23268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
23278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		case EAPT_NAK:
23298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (len <= 0) {
23308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " <missing hint>");
23318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
23328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
23338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			GETCHAR(rtype, inp);
23348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			len--;
23358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, " <Suggested-type %02X", rtype);
23368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (rtype >= 1 &&
23378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    rtype < sizeof (eap_typenames) / sizeof (char *))
23388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " (%s)", eap_typenames[rtype-1]);
23398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, ">");
23408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
23418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		case EAPT_MD5CHAP:
23438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (len <= 0) {
23448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " <missing length>");
23458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
23468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
23478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			GETCHAR(vallen, inp);
23488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			len--;
23498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (vallen > len)
23508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				goto truncated;
23518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, " <Value%.*B>", vallen, inp);
23528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			INCPTR(vallen, inp);
23538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			len -= vallen;
23548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (len > 0) {
23558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " <Name ");
23568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				print_string((char *)inp, len, printer, arg);
23578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, ">");
23588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				INCPTR(len, inp);
23598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len = 0;
23608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			} else {
23618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " <No name>");
23628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
23638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
23648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		case EAPT_SRP:
23668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (len < 1)
23678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				goto truncated;
23688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			GETCHAR(vallen, inp);
23698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			len--;
23708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			printer(arg, "-%d", vallen);
23718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			switch (vallen) {
23728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			case EAPSRP_CKEY:
23738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " <A%.*B>", len, inp);
23748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				INCPTR(len, inp);
23758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len = 0;
23768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
23778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			case EAPSRP_CVALIDATOR:
23798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (len < sizeof (u_int32_t))
23808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					break;
23818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				GETLONG(uval, inp);
23828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len -= sizeof (u_int32_t);
23838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (uval & SRPVAL_EBIT) {
23848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					printer(arg, " E");
23858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					uval &= ~SRPVAL_EBIT;
23868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
23878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if (uval != 0) {
23888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					printer(arg, " f<%X>", uval);
23898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				}
23908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " <M1%.*B%s>", len, inp,
23918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    len == SHA_DIGESTSIZE ? "" : "?");
23928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				INCPTR(len, inp);
23938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len = 0;
23948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
23958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			case EAPSRP_ACK:
23978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
23988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			case EAPSRP_LWRECHALLENGE:
24008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				printer(arg, " <Response%.*B%s>", len, inp,
24018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				    len == SHA_DIGESTSIZE ? "" : "?");
24028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				if ((vallen = len) > SHA_DIGESTSIZE)
24038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project					vallen = SHA_DIGESTSIZE;
24048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				INCPTR(vallen, inp);
24058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				len -= vallen;
24068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				break;
24078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
24088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
24098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
24108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
24118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
24128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EAP_SUCCESS:	/* No payload expected for these! */
24138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EAP_FAILURE:
24148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
24158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
24168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	truncated:
24178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		printer(arg, " <truncated>");
24188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
24198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
24208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
24218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len > 8)
24228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		printer(arg, "%8B...", inp);
24238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	else if (len > 0)
24248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		printer(arg, "%.*B", len, inp);
24258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	INCPTR(len, inp);
24268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
24278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return (inp - pstart);
24288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2429