1*10465441SEvalZero /* 2*10465441SEvalZero * chap-new.c - New CHAP implementation. 3*10465441SEvalZero * 4*10465441SEvalZero * Copyright (c) 2003 Paul Mackerras. All rights reserved. 5*10465441SEvalZero * 6*10465441SEvalZero * Redistribution and use in source and binary forms, with or without 7*10465441SEvalZero * modification, are permitted provided that the following conditions 8*10465441SEvalZero * are met: 9*10465441SEvalZero * 10*10465441SEvalZero * 1. Redistributions of source code must retain the above copyright 11*10465441SEvalZero * notice, this list of conditions and the following disclaimer. 12*10465441SEvalZero * 13*10465441SEvalZero * 2. The name(s) of the authors of this software must not be used to 14*10465441SEvalZero * endorse or promote products derived from this software without 15*10465441SEvalZero * prior written permission. 16*10465441SEvalZero * 17*10465441SEvalZero * 3. Redistributions of any form whatsoever must retain the following 18*10465441SEvalZero * acknowledgment: 19*10465441SEvalZero * "This product includes software developed by Paul Mackerras 20*10465441SEvalZero * <[email protected]>". 21*10465441SEvalZero * 22*10465441SEvalZero * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO 23*10465441SEvalZero * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 24*10465441SEvalZero * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 25*10465441SEvalZero * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 26*10465441SEvalZero * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 27*10465441SEvalZero * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 28*10465441SEvalZero * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 29*10465441SEvalZero */ 30*10465441SEvalZero 31*10465441SEvalZero #include "netif/ppp/ppp_opts.h" 32*10465441SEvalZero #if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ 33*10465441SEvalZero 34*10465441SEvalZero #ifndef CHAP_H 35*10465441SEvalZero #define CHAP_H 36*10465441SEvalZero 37*10465441SEvalZero #include "ppp.h" 38*10465441SEvalZero 39*10465441SEvalZero /* 40*10465441SEvalZero * CHAP packets begin with a standard header with code, id, len (2 bytes). 41*10465441SEvalZero */ 42*10465441SEvalZero #define CHAP_HDRLEN 4 43*10465441SEvalZero 44*10465441SEvalZero /* 45*10465441SEvalZero * Values for the code field. 46*10465441SEvalZero */ 47*10465441SEvalZero #define CHAP_CHALLENGE 1 48*10465441SEvalZero #define CHAP_RESPONSE 2 49*10465441SEvalZero #define CHAP_SUCCESS 3 50*10465441SEvalZero #define CHAP_FAILURE 4 51*10465441SEvalZero 52*10465441SEvalZero /* 53*10465441SEvalZero * CHAP digest codes. 54*10465441SEvalZero */ 55*10465441SEvalZero #define CHAP_MD5 5 56*10465441SEvalZero #if MSCHAP_SUPPORT 57*10465441SEvalZero #define CHAP_MICROSOFT 0x80 58*10465441SEvalZero #define CHAP_MICROSOFT_V2 0x81 59*10465441SEvalZero #endif /* MSCHAP_SUPPORT */ 60*10465441SEvalZero 61*10465441SEvalZero /* 62*10465441SEvalZero * Semi-arbitrary limits on challenge and response fields. 63*10465441SEvalZero */ 64*10465441SEvalZero #define MAX_CHALLENGE_LEN 64 65*10465441SEvalZero #define MAX_RESPONSE_LEN 64 66*10465441SEvalZero 67*10465441SEvalZero /* 68*10465441SEvalZero * These limits apply to challenge and response packets we send. 69*10465441SEvalZero * The +4 is the +1 that we actually need rounded up. 70*10465441SEvalZero */ 71*10465441SEvalZero #define CHAL_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_CHALLENGE_LEN + MAXNAMELEN) 72*10465441SEvalZero #define RESP_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_RESPONSE_LEN + MAXNAMELEN) 73*10465441SEvalZero 74*10465441SEvalZero /* bitmask of supported algorithms */ 75*10465441SEvalZero #if MSCHAP_SUPPORT 76*10465441SEvalZero #define MDTYPE_MICROSOFT_V2 0x1 77*10465441SEvalZero #define MDTYPE_MICROSOFT 0x2 78*10465441SEvalZero #endif /* MSCHAP_SUPPORT */ 79*10465441SEvalZero #define MDTYPE_MD5 0x4 80*10465441SEvalZero #define MDTYPE_NONE 0 81*10465441SEvalZero 82*10465441SEvalZero #if MSCHAP_SUPPORT 83*10465441SEvalZero /* Return the digest alg. ID for the most preferred digest type. */ 84*10465441SEvalZero #define CHAP_DIGEST(mdtype) \ 85*10465441SEvalZero ((mdtype) & MDTYPE_MD5)? CHAP_MD5: \ 86*10465441SEvalZero ((mdtype) & MDTYPE_MICROSOFT_V2)? CHAP_MICROSOFT_V2: \ 87*10465441SEvalZero ((mdtype) & MDTYPE_MICROSOFT)? CHAP_MICROSOFT: \ 88*10465441SEvalZero 0 89*10465441SEvalZero #else /* !MSCHAP_SUPPORT */ 90*10465441SEvalZero #define CHAP_DIGEST(mdtype) \ 91*10465441SEvalZero ((mdtype) & MDTYPE_MD5)? CHAP_MD5: \ 92*10465441SEvalZero 0 93*10465441SEvalZero #endif /* MSCHAP_SUPPORT */ 94*10465441SEvalZero 95*10465441SEvalZero /* Return the bit flag (lsb set) for our most preferred digest type. */ 96*10465441SEvalZero #define CHAP_MDTYPE(mdtype) ((mdtype) ^ ((mdtype) - 1)) & (mdtype) 97*10465441SEvalZero 98*10465441SEvalZero /* Return the bit flag for a given digest algorithm ID. */ 99*10465441SEvalZero #if MSCHAP_SUPPORT 100*10465441SEvalZero #define CHAP_MDTYPE_D(digest) \ 101*10465441SEvalZero ((digest) == CHAP_MICROSOFT_V2)? MDTYPE_MICROSOFT_V2: \ 102*10465441SEvalZero ((digest) == CHAP_MICROSOFT)? MDTYPE_MICROSOFT: \ 103*10465441SEvalZero ((digest) == CHAP_MD5)? MDTYPE_MD5: \ 104*10465441SEvalZero 0 105*10465441SEvalZero #else /* !MSCHAP_SUPPORT */ 106*10465441SEvalZero #define CHAP_MDTYPE_D(digest) \ 107*10465441SEvalZero ((digest) == CHAP_MD5)? MDTYPE_MD5: \ 108*10465441SEvalZero 0 109*10465441SEvalZero #endif /* MSCHAP_SUPPORT */ 110*10465441SEvalZero 111*10465441SEvalZero /* Can we do the requested digest? */ 112*10465441SEvalZero #if MSCHAP_SUPPORT 113*10465441SEvalZero #define CHAP_CANDIGEST(mdtype, digest) \ 114*10465441SEvalZero ((digest) == CHAP_MICROSOFT_V2)? (mdtype) & MDTYPE_MICROSOFT_V2: \ 115*10465441SEvalZero ((digest) == CHAP_MICROSOFT)? (mdtype) & MDTYPE_MICROSOFT: \ 116*10465441SEvalZero ((digest) == CHAP_MD5)? (mdtype) & MDTYPE_MD5: \ 117*10465441SEvalZero 0 118*10465441SEvalZero #else /* !MSCHAP_SUPPORT */ 119*10465441SEvalZero #define CHAP_CANDIGEST(mdtype, digest) \ 120*10465441SEvalZero ((digest) == CHAP_MD5)? (mdtype) & MDTYPE_MD5: \ 121*10465441SEvalZero 0 122*10465441SEvalZero #endif /* MSCHAP_SUPPORT */ 123*10465441SEvalZero 124*10465441SEvalZero /* 125*10465441SEvalZero * The code for each digest type has to supply one of these. 126*10465441SEvalZero */ 127*10465441SEvalZero struct chap_digest_type { 128*10465441SEvalZero int code; 129*10465441SEvalZero 130*10465441SEvalZero #if PPP_SERVER 131*10465441SEvalZero /* 132*10465441SEvalZero * Note: challenge and response arguments below are formatted as 133*10465441SEvalZero * a length byte followed by the actual challenge/response data. 134*10465441SEvalZero */ 135*10465441SEvalZero void (*generate_challenge)(ppp_pcb *pcb, unsigned char *challenge); 136*10465441SEvalZero int (*verify_response)(ppp_pcb *pcb, int id, const char *name, 137*10465441SEvalZero const unsigned char *secret, int secret_len, 138*10465441SEvalZero const unsigned char *challenge, const unsigned char *response, 139*10465441SEvalZero char *message, int message_space); 140*10465441SEvalZero #endif /* PPP_SERVER */ 141*10465441SEvalZero void (*make_response)(ppp_pcb *pcb, unsigned char *response, int id, const char *our_name, 142*10465441SEvalZero const unsigned char *challenge, const char *secret, int secret_len, 143*10465441SEvalZero unsigned char *priv); 144*10465441SEvalZero int (*check_success)(ppp_pcb *pcb, unsigned char *pkt, int len, unsigned char *priv); 145*10465441SEvalZero void (*handle_failure)(ppp_pcb *pcb, unsigned char *pkt, int len); 146*10465441SEvalZero }; 147*10465441SEvalZero 148*10465441SEvalZero /* 149*10465441SEvalZero * Each interface is described by chap structure. 150*10465441SEvalZero */ 151*10465441SEvalZero #if CHAP_SUPPORT 152*10465441SEvalZero typedef struct chap_client_state { 153*10465441SEvalZero u8_t flags; 154*10465441SEvalZero const char *name; 155*10465441SEvalZero const struct chap_digest_type *digest; 156*10465441SEvalZero unsigned char priv[64]; /* private area for digest's use */ 157*10465441SEvalZero } chap_client_state; 158*10465441SEvalZero 159*10465441SEvalZero #if PPP_SERVER 160*10465441SEvalZero typedef struct chap_server_state { 161*10465441SEvalZero u8_t flags; 162*10465441SEvalZero u8_t id; 163*10465441SEvalZero const char *name; 164*10465441SEvalZero const struct chap_digest_type *digest; 165*10465441SEvalZero int challenge_xmits; 166*10465441SEvalZero int challenge_pktlen; 167*10465441SEvalZero unsigned char challenge[CHAL_MAX_PKTLEN]; 168*10465441SEvalZero } chap_server_state; 169*10465441SEvalZero #endif /* PPP_SERVER */ 170*10465441SEvalZero #endif /* CHAP_SUPPORT */ 171*10465441SEvalZero 172*10465441SEvalZero #if 0 /* UNUSED */ 173*10465441SEvalZero /* Hook for a plugin to validate CHAP challenge */ 174*10465441SEvalZero extern int (*chap_verify_hook)(char *name, char *ourname, int id, 175*10465441SEvalZero const struct chap_digest_type *digest, 176*10465441SEvalZero unsigned char *challenge, unsigned char *response, 177*10465441SEvalZero char *message, int message_space); 178*10465441SEvalZero #endif /* UNUSED */ 179*10465441SEvalZero 180*10465441SEvalZero #if PPP_SERVER 181*10465441SEvalZero /* Called by authentication code to start authenticating the peer. */ 182*10465441SEvalZero extern void chap_auth_peer(ppp_pcb *pcb, const char *our_name, int digest_code); 183*10465441SEvalZero #endif /* PPP_SERVER */ 184*10465441SEvalZero 185*10465441SEvalZero /* Called by auth. code to start authenticating us to the peer. */ 186*10465441SEvalZero extern void chap_auth_with_peer(ppp_pcb *pcb, const char *our_name, int digest_code); 187*10465441SEvalZero 188*10465441SEvalZero /* Represents the CHAP protocol to the main pppd code */ 189*10465441SEvalZero extern const struct protent chap_protent; 190*10465441SEvalZero 191*10465441SEvalZero #endif /* CHAP_H */ 192*10465441SEvalZero #endif /* PPP_SUPPORT && CHAP_SUPPORT */ 193