18ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 28ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * chap-new.c - New CHAP implementation. 38ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 48ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Copyright (c) 2003 Paul Mackerras. All rights reserved. 58ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 68ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Redistribution and use in source and binary forms, with or without 78ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * modification, are permitted provided that the following conditions 88ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * are met: 98ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * notice, this list of conditions and the following disclaimer. 128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 2. The name(s) of the authors of this software must not be used to 148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * endorse or promote products derived from this software without 158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * prior written permission. 168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 3. Redistributions of any form whatsoever must retain the following 188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * acknowledgment: 198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * "This product includes software developed by Paul Mackerras 208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * <paulus@samba.org>". 218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO 238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 311286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley#define RCSID "$Id: chap-new.c,v 1.9 2007/06/19 02:08:35 carlsonj Exp $" 328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdlib.h> 348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <string.h> 358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "pppd.h" 361286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley#include "session.h" 378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "chap-new.h" 388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "chap-md5.h" 391286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley#if defined(__ANDROID__) 40e7f221f12403dcb4081d08e28c54d3b2a1ab05eeChung-yih Wang#include "openssl-hash.h" 41e7f221f12403dcb4081d08e28c54d3b2a1ab05eeChung-yih Wang#endif 428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef CHAPMS 448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "chap_ms.h" 458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define MDTYPE_ALL (MDTYPE_MICROSOFT_V2 | MDTYPE_MICROSOFT | MDTYPE_MD5) 468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#else 478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define MDTYPE_ALL (MDTYPE_MD5) 488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint chap_mdtype_all = MDTYPE_ALL; 518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* Hook for a plugin to validate CHAP challenge */ 538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint (*chap_verify_hook)(char *name, char *ourname, int id, 548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct chap_digest_type *digest, 558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *challenge, unsigned char *response, 568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char *message, int message_space) = NULL; 578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Option variables. 608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint chap_timeout_time = 3; 628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint chap_max_transmits = 10; 638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint chap_rechallenge_time = 0; 648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Command-line options. 678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic option_t chap_option_list[] = { 698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "chap-restart", o_int, &chap_timeout_time, 708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Set timeout for CHAP", OPT_PRIO }, 718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "chap-max-challenge", o_int, &chap_max_transmits, 728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Set max #xmits for challenge", OPT_PRIO }, 738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "chap-interval", o_int, &chap_rechallenge_time, 748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Set interval for rechallenge", OPT_PRIO }, 758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { NULL } 768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}; 778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Internal state. 808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic struct chap_client_state { 828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int flags; 838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char *name; 848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct chap_digest_type *digest; 858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char priv[64]; /* private area for digest's use */ 868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} client; 878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * These limits apply to challenge and response packets we send. 908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * The +4 is the +1 that we actually need rounded up. 918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define CHAL_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_CHALLENGE_LEN + MAXNAMELEN) 938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define RESP_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_RESPONSE_LEN + MAXNAMELEN) 948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic struct chap_server_state { 968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int flags; 978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int id; 988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char *name; 998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct chap_digest_type *digest; 1008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int challenge_xmits; 1018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int challenge_pktlen; 1028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char challenge[CHAL_MAX_PKTLEN]; 1031286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley char message[256]; 1048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} server; 1058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* Values for flags in chap_client_state and chap_server_state */ 1078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define LOWERUP 1 1088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define AUTH_STARTED 2 1098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define AUTH_DONE 4 1108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define AUTH_FAILED 8 1118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define TIMEOUT_PENDING 0x10 1128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define CHALLENGE_VALID 0x20 1138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 1158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Prototypes. 1168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 1178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void chap_init(int unit); 1188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void chap_lowerup(int unit); 1198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void chap_lowerdown(int unit); 1208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void chap_timeout(void *arg); 1218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void chap_generate_challenge(struct chap_server_state *ss); 1228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void chap_handle_response(struct chap_server_state *ss, int code, 1238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *pkt, int len); 1248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int chap_verify_response(char *name, char *ourname, int id, 1258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct chap_digest_type *digest, 1268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *challenge, unsigned char *response, 1278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char *message, int message_space); 1288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void chap_respond(struct chap_client_state *cs, int id, 1298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *pkt, int len); 1308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void chap_handle_status(struct chap_client_state *cs, int code, int id, 1318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *pkt, int len); 1328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void chap_protrej(int unit); 1338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void chap_input(int unit, unsigned char *pkt, int pktlen); 1348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int chap_print_pkt(unsigned char *p, int plen, 1358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project void (*printer) __P((void *, char *, ...)), void *arg); 1368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* List of digest types that we know about */ 1388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic struct chap_digest_type *chap_digests; 1398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 1418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * chap_init - reset to initial state. 1428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 1438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 1448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchap_init(int unit) 1458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 1468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset(&client, 0, sizeof(client)); 1478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset(&server, 0, sizeof(server)); 1488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project chap_md5_init(); 1508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef CHAPMS 1518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project chapms_init(); 1528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 1538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 1548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 1568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Add a new digest type to the list. 1578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 1588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 1598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchap_register_digest(struct chap_digest_type *dp) 1608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 1618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dp->next = chap_digests; 1628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project chap_digests = dp; 1638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 1648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 1668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * chap_lowerup - we can start doing stuff now. 1678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 1688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 1698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchap_lowerup(int unit) 1708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 1718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct chap_client_state *cs = &client; 1728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct chap_server_state *ss = &server; 1738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project cs->flags |= LOWERUP; 1758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->flags |= LOWERUP; 1768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ss->flags & AUTH_STARTED) 1778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project chap_timeout(ss); 1788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 1798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 1818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchap_lowerdown(int unit) 1828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 1838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct chap_client_state *cs = &client; 1848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct chap_server_state *ss = &server; 1858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project cs->flags = 0; 1878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ss->flags & TIMEOUT_PENDING) 1888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project UNTIMEOUT(chap_timeout, ss); 1898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->flags = 0; 1908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 1918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 1938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * chap_auth_peer - Start authenticating the peer. 1948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * If the lower layer is already up, we start sending challenges, 1958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * otherwise we wait for the lower layer to come up. 1968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 1978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 1988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchap_auth_peer(int unit, char *our_name, int digest_code) 1998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 2008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct chap_server_state *ss = &server; 2018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct chap_digest_type *dp; 2028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ss->flags & AUTH_STARTED) { 2048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("CHAP: peer authentication already started!"); 2058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 2068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (dp = chap_digests; dp != NULL; dp = dp->next) 2088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (dp->code == digest_code) 2098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 2108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (dp == NULL) 2118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatal("CHAP digest 0x%x requested but not available", 2128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project digest_code); 2138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->digest = dp; 2158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->name = our_name; 2168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Start with a random ID value */ 2178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->id = (unsigned char)(drand48() * 256); 2188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->flags |= AUTH_STARTED; 2198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ss->flags & LOWERUP) 2208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project chap_timeout(ss); 2218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 2228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 2248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * chap_auth_with_peer - Prepare to authenticate ourselves to the peer. 2258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * There isn't much to do until we receive a challenge. 2268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 2278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 2288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchap_auth_with_peer(int unit, char *our_name, int digest_code) 2298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 2308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct chap_client_state *cs = &client; 2318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct chap_digest_type *dp; 2328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (cs->flags & AUTH_STARTED) { 2348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("CHAP: authentication with peer already started!"); 2358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 2368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (dp = chap_digests; dp != NULL; dp = dp->next) 2388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (dp->code == digest_code) 2398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 2408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (dp == NULL) 2418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatal("CHAP digest 0x%x requested but not available", 2428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project digest_code); 2438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project cs->digest = dp; 2458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project cs->name = our_name; 2468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project cs->flags |= AUTH_STARTED; 2478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 2488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 2508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * chap_timeout - It's time to send another challenge to the peer. 2518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This could be either a retransmission of a previous challenge, 2528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * or a new challenge to start re-authentication. 2538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 2548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 2558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchap_timeout(void *arg) 2568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 2578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct chap_server_state *ss = arg; 2588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->flags &= ~TIMEOUT_PENDING; 2608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((ss->flags & CHALLENGE_VALID) == 0) { 2618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->challenge_xmits = 0; 2628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project chap_generate_challenge(ss); 2638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->flags |= CHALLENGE_VALID; 2648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else if (ss->challenge_xmits >= chap_max_transmits) { 2658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->flags &= ~CHALLENGE_VALID; 2668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->flags |= AUTH_DONE | AUTH_FAILED; 2678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project auth_peer_fail(0, PPP_CHAP); 2688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 2698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project output(0, ss->challenge, ss->challenge_pktlen); 2728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ++ss->challenge_xmits; 2738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->flags |= TIMEOUT_PENDING; 2748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project TIMEOUT(chap_timeout, arg, chap_timeout_time); 2758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 2768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 2788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * chap_generate_challenge - generate a challenge string and format 2798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the challenge packet in ss->challenge_pkt. 2808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 2818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 2828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchap_generate_challenge(struct chap_server_state *ss) 2838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 2848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int clen = 1, nlen, len; 2858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *p; 2868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p = ss->challenge; 2888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project MAKEHEADER(p, PPP_CHAP); 2898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p += CHAP_HDRLEN; 2908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->digest->generate_challenge(p); 2918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project clen = *p; 2928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project nlen = strlen(ss->name); 2938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(p + 1 + clen, ss->name, nlen); 2948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project len = CHAP_HDRLEN + 1 + clen + nlen; 2968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->challenge_pktlen = PPP_HDRLEN + len; 2978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p = ss->challenge + PPP_HDRLEN; 2998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p[0] = CHAP_CHALLENGE; 3008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p[1] = ++ss->id; 3018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p[2] = len >> 8; 3028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p[3] = len; 3038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 3048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 3068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * chap_handle_response - check the response to our challenge. 3078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 3088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 3098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchap_handle_response(struct chap_server_state *ss, int id, 3108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *pkt, int len) 3118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 3128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int response_len, ok, mlen; 3138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *response, *p; 3148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char *name = NULL; /* initialized to shut gcc up */ 3158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int (*verifier)(char *, char *, int, struct chap_digest_type *, 3168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *, unsigned char *, char *, int); 3178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char rname[MAXNAMELEN+1]; 3188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((ss->flags & LOWERUP) == 0) 3208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 3218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (id != ss->challenge[PPP_HDRLEN+1] || len < 2) 3228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 3231286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley if (ss->flags & CHALLENGE_VALID) { 3248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project response = pkt; 3258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project GETCHAR(response_len, pkt); 3268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project len -= response_len + 1; /* length of name */ 3278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project name = (char *)pkt + response_len; 3288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (len < 0) 3298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 3308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ss->flags & TIMEOUT_PENDING) { 3328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->flags &= ~TIMEOUT_PENDING; 3338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project UNTIMEOUT(chap_timeout, ss); 3348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (explicit_remote) { 3378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project name = remote_name; 3388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { 3398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Null terminate and clean remote name. */ 3408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project slprintf(rname, sizeof(rname), "%.*v", len, name); 3418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project name = rname; 3428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (chap_verify_hook) 3458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project verifier = chap_verify_hook; 3468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project else 3478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project verifier = chap_verify_response; 3488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ok = (*verifier)(name, ss->name, id, ss->digest, 3498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->challenge + PPP_HDRLEN + CHAP_HDRLEN, 3501286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley response, ss->message, sizeof(ss->message)); 3518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!ok || !auth_number()) { 3528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->flags |= AUTH_FAILED; 3538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project warn("Peer %q failed CHAP authentication", name); 3548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3551286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley } else if ((ss->flags & AUTH_DONE) == 0) 3561286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley return; 3578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* send the response */ 3598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p = outpacket_buf; 3608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project MAKEHEADER(p, PPP_CHAP); 3611286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley mlen = strlen(ss->message); 3628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project len = CHAP_HDRLEN + mlen; 3638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p[0] = (ss->flags & AUTH_FAILED)? CHAP_FAILURE: CHAP_SUCCESS; 3648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p[1] = id; 3658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p[2] = len >> 8; 3668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p[3] = len; 3678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (mlen > 0) 3681286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley memcpy(p + CHAP_HDRLEN, ss->message, mlen); 3698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project output(0, outpacket_buf, PPP_HDRLEN + len); 3708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3711286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley if (ss->flags & CHALLENGE_VALID) { 3721286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley ss->flags &= ~CHALLENGE_VALID; 3731286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley if (!(ss->flags & AUTH_DONE) && !(ss->flags & AUTH_FAILED)) { 3741286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley /* 3751286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley * Auth is OK, so now we need to check session restrictions 3761286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley * to ensure everything is OK, but only if we used a 3771286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley * plugin, and only if we're configured to check. This 3781286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley * allows us to do PAM checks on PPP servers that 3791286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley * authenticate against ActiveDirectory, and use AD for 3801286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley * account info (like when using Winbind integrated with 3811286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley * PAM). 3821286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley */ 3831286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley if (session_mgmt && 3841286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley session_check(name, NULL, devnam, NULL) == 0) { 3851286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley ss->flags |= AUTH_FAILED; 3861286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley warn("Peer %q failed CHAP Session verification", name); 3871286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley } 3881286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley } 3898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ss->flags & AUTH_FAILED) { 3908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project auth_peer_fail(0, PPP_CHAP); 3918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { 3921286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley if ((ss->flags & AUTH_DONE) == 0) 3931286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley auth_peer_success(0, PPP_CHAP, 3941286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley ss->digest->code, 3951286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley name, strlen(name)); 3968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (chap_rechallenge_time) { 3978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->flags |= TIMEOUT_PENDING; 3988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project TIMEOUT(chap_timeout, ss, 3998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project chap_rechallenge_time); 4008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4021286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley ss->flags |= AUTH_DONE; 4038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 4058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 4078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * chap_verify_response - check whether the peer's response matches 4088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * what we think it should be. Returns 1 if it does (authentication 4098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * succeeded), or 0 if it doesn't. 4108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 4118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int 4128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchap_verify_response(char *name, char *ourname, int id, 4138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct chap_digest_type *digest, 4148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *challenge, unsigned char *response, 4158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char *message, int message_space) 4168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 4178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int ok; 4188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char secret[MAXSECRETLEN]; 4198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int secret_len; 4208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Get the secret that the peer is supposed to know */ 4228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) { 4238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("No CHAP secret found for authenticating %q", name); 4248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 4258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ok = digest->verify_response(id, name, secret, secret_len, challenge, 4288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project response, message, message_space); 4298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset(secret, 0, sizeof(secret)); 4308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return ok; 4328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 4338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 4358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * chap_respond - Generate and send a response to a challenge. 4368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 4378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 4388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchap_respond(struct chap_client_state *cs, int id, 4398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *pkt, int len) 4408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 4418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int clen, nlen; 4428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int secret_len; 4438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *p; 4448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char response[RESP_MAX_PKTLEN]; 4458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char rname[MAXNAMELEN+1]; 4468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char secret[MAXSECRETLEN+1]; 4478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((cs->flags & (LOWERUP | AUTH_STARTED)) != (LOWERUP | AUTH_STARTED)) 4498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; /* not ready */ 4508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (len < 2 || len < pkt[0] + 1) 4518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; /* too short */ 4528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project clen = pkt[0]; 4538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project nlen = len - (clen + 1); 4548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Null terminate and clean remote name. */ 4568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1); 4578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Microsoft doesn't send their name back in the PPP packet */ 4598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (explicit_remote || (remote_name[0] != 0 && rname[0] == 0)) 4608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strlcpy(rname, remote_name, sizeof(rname)); 4618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* get secret for authenticating ourselves with the specified host */ 4638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!get_secret(0, cs->name, rname, secret, &secret_len, 0)) { 4648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project secret_len = 0; /* assume null secret if can't find one */ 4658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project warn("No CHAP secret found for authenticating us to %q", rname); 4668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p = response; 4698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project MAKEHEADER(p, PPP_CHAP); 4708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p += CHAP_HDRLEN; 4718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project cs->digest->make_response(p, id, cs->name, pkt, 4738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project secret, secret_len, cs->priv); 4748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset(secret, 0, secret_len); 4758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project clen = *p; 4778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project nlen = strlen(cs->name); 4788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(p + clen + 1, cs->name, nlen); 4798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p = response + PPP_HDRLEN; 4818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project len = CHAP_HDRLEN + clen + 1 + nlen; 4828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p[0] = CHAP_RESPONSE; 4838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p[1] = id; 4848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p[2] = len >> 8; 4858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p[3] = len; 4868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project output(0, response, PPP_HDRLEN + len); 4888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 4898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 4918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchap_handle_status(struct chap_client_state *cs, int code, int id, 4928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *pkt, int len) 4938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 4948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project const char *msg = NULL; 4958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((cs->flags & (AUTH_DONE|AUTH_STARTED|LOWERUP)) 4978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project != (AUTH_STARTED|LOWERUP)) 4988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 4998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project cs->flags |= AUTH_DONE; 5008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (code == CHAP_SUCCESS) { 5028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* used for MS-CHAP v2 mutual auth, yuck */ 5038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (cs->digest->check_success != NULL) { 5041286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley if (!(*cs->digest->check_success)(id, pkt, len)) 5058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project code = CHAP_FAILURE; 5068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else 5078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project msg = "CHAP authentication succeeded"; 5088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { 5098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (cs->digest->handle_failure != NULL) 5108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (*cs->digest->handle_failure)(pkt, len); 5118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project else 5128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project msg = "CHAP authentication failed"; 5138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (msg) { 5158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (len > 0) 5168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info("%s: %.*v", msg, len, pkt); 5178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project else 5188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info("%s", msg); 5198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (code == CHAP_SUCCESS) 5218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project auth_withpeer_success(0, PPP_CHAP, cs->digest->code); 5228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project else { 5238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project cs->flags |= AUTH_FAILED; 5241286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley error("CHAP authentication failed"); 5258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project auth_withpeer_fail(0, PPP_CHAP); 5268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 5288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 5308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchap_input(int unit, unsigned char *pkt, int pktlen) 5318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 5328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct chap_client_state *cs = &client; 5338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct chap_server_state *ss = &server; 5348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char code, id; 5358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int len; 5368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (pktlen < CHAP_HDRLEN) 5388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 5398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project GETCHAR(code, pkt); 5408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project GETCHAR(id, pkt); 5418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project GETSHORT(len, pkt); 5428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (len < CHAP_HDRLEN || len > pktlen) 5438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 5448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project len -= CHAP_HDRLEN; 5458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project switch (code) { 5478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case CHAP_CHALLENGE: 5488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project chap_respond(cs, id, pkt, len); 5498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 5508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case CHAP_RESPONSE: 5518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project chap_handle_response(ss, id, pkt, len); 5528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 5538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case CHAP_FAILURE: 5548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case CHAP_SUCCESS: 5558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project chap_handle_status(cs, code, id, pkt, len); 5568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 5578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 5598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 5618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchap_protrej(int unit) 5628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 5638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct chap_client_state *cs = &client; 5648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct chap_server_state *ss = &server; 5658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ss->flags & TIMEOUT_PENDING) { 5678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->flags &= ~TIMEOUT_PENDING; 5688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project UNTIMEOUT(chap_timeout, ss); 5698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ss->flags & AUTH_STARTED) { 5718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ss->flags = 0; 5728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project auth_peer_fail(0, PPP_CHAP); 5738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((cs->flags & (AUTH_STARTED|AUTH_DONE)) == AUTH_STARTED) { 5758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project cs->flags &= ~AUTH_STARTED; 5761286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley error("CHAP authentication failed due to protocol-reject"); 5778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project auth_withpeer_fail(0, PPP_CHAP); 5788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 5808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 5828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * chap_print_pkt - print the contents of a CHAP packet. 5838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 5848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char *chap_code_names[] = { 5858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Challenge", "Response", "Success", "Failure" 5868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}; 5878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int 5898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchap_print_pkt(unsigned char *p, int plen, 5908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project void (*printer) __P((void *, char *, ...)), void *arg) 5918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 5928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int code, id, len; 5938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int clen, nlen; 5948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char x; 5958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (plen < CHAP_HDRLEN) 5978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 5988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project GETCHAR(code, p); 5998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project GETCHAR(id, p); 6008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project GETSHORT(len, p); 6018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (len < CHAP_HDRLEN || len > plen) 6028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 6038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 6048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (code >= 1 && code <= sizeof(chap_code_names) / sizeof(char *)) 6058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project printer(arg, " %s", chap_code_names[code-1]); 6068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project else 6078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project printer(arg, " code=0x%x", code); 6088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project printer(arg, " id=0x%x", id); 6098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project len -= CHAP_HDRLEN; 6108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project switch (code) { 6118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case CHAP_CHALLENGE: 6128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case CHAP_RESPONSE: 6138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (len < 1) 6148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 6158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project clen = p[0]; 6168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (len < clen + 1) 6178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 6188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ++p; 6198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project nlen = len - clen - 1; 6208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project printer(arg, " <"); 6218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (; clen > 0; --clen) { 6228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project GETCHAR(x, p); 6238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project printer(arg, "%.2x", x); 6248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project printer(arg, ">, name = "); 6268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project print_string((char *)p, nlen, printer, arg); 6278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 6288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case CHAP_FAILURE: 6298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case CHAP_SUCCESS: 6308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project printer(arg, " "); 6318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project print_string((char *)p, len, printer, arg); 6328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 6338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project default: 6348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (clen = len; clen > 0; --clen) { 6358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project GETCHAR(x, p); 6368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project printer(arg, " %.2x", x); 6378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 6408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return len + CHAP_HDRLEN; 6418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 6428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 6438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstruct protent chap_protent = { 6448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project PPP_CHAP, 6458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project chap_init, 6468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project chap_input, 6478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project chap_protrej, 6488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project chap_lowerup, 6498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project chap_lowerdown, 6508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project NULL, /* open */ 6518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project NULL, /* close */ 6528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project chap_print_pkt, 6538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project NULL, /* datainput */ 6548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1, /* enabled_flag */ 6558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "CHAP", /* name */ 6568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project NULL, /* data_name */ 6578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project chap_option_list, 6588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project NULL, /* check_options */ 6598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}; 660