#include "netif/ppp/ppp_opts.h"
#if PPP_SUPPORT && CHAP_SUPPORT
#ifndef CHAP_H
#define CHAP_H
#include "ppp.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CHAP_HDRLEN 4
#define CHAP_CHALLENGE 1
#define CHAP_RESPONSE 2
#define CHAP_SUCCESS 3
#define CHAP_FAILURE 4
#define CHAP_MD5 5
#if MSCHAP_SUPPORT
#define CHAP_MICROSOFT 0x80
#define CHAP_MICROSOFT_V2 0x81
#endif
#define MAX_CHALLENGE_LEN 64
#define MAX_RESPONSE_LEN 64
#define CHAL_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_CHALLENGE_LEN + MAXNAMELEN)
#define RESP_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_RESPONSE_LEN + MAXNAMELEN)
#if MSCHAP_SUPPORT
#define MDTYPE_MICROSOFT_V2 0x1
#define MDTYPE_MICROSOFT 0x2
#endif
#define MDTYPE_MD5 0x4
#define MDTYPE_NONE 0
#if MSCHAP_SUPPORT
#define CHAP_DIGEST(mdtype) \
((mdtype) & MDTYPE_MD5)? CHAP_MD5: \
((mdtype) & MDTYPE_MICROSOFT_V2)? CHAP_MICROSOFT_V2: \
((mdtype) & MDTYPE_MICROSOFT)? CHAP_MICROSOFT: \
0
#else
#define CHAP_DIGEST(mdtype) \
((mdtype) & MDTYPE_MD5)? CHAP_MD5: \
0
#endif
#define CHAP_MDTYPE(mdtype) ((mdtype) ^ ((mdtype) - 1)) & (mdtype)
#if MSCHAP_SUPPORT
#define CHAP_MDTYPE_D(digest) \
((digest) == CHAP_MICROSOFT_V2)? MDTYPE_MICROSOFT_V2: \
((digest) == CHAP_MICROSOFT)? MDTYPE_MICROSOFT: \
((digest) == CHAP_MD5)? MDTYPE_MD5: \
0
#else
#define CHAP_MDTYPE_D(digest) \
((digest) == CHAP_MD5)? MDTYPE_MD5: \
0
#endif
#if MSCHAP_SUPPORT
#define CHAP_CANDIGEST(mdtype, digest) \
((digest) == CHAP_MICROSOFT_V2)? (mdtype) & MDTYPE_MICROSOFT_V2: \
((digest) == CHAP_MICROSOFT)? (mdtype) & MDTYPE_MICROSOFT: \
((digest) == CHAP_MD5)? (mdtype) & MDTYPE_MD5: \
0
#else
#define CHAP_CANDIGEST(mdtype, digest) \
((digest) == CHAP_MD5)? (mdtype) & MDTYPE_MD5: \
0
#endif
struct chap_digest_type {
int code;
#if PPP_SERVER
void (*generate_challenge)(ppp_pcb *pcb, unsigned char *challenge);
int (*verify_response)(ppp_pcb *pcb, int id, const char *name,
const unsigned char *secret, int secret_len,
const unsigned char *challenge, const unsigned char *response,
char *message, int message_space);
#endif
void (*make_response)(ppp_pcb *pcb, unsigned char *response, int id, const char *our_name,
const unsigned char *challenge, const char *secret, int secret_len,
unsigned char *priv);
int (*check_success)(ppp_pcb *pcb, unsigned char *pkt, int len, unsigned char *priv);
void (*handle_failure)(ppp_pcb *pcb, unsigned char *pkt, int len);
};
#if CHAP_SUPPORT
typedef struct chap_client_state {
u8_t flags;
const char *name;
const struct chap_digest_type *digest;
unsigned char priv[64];
} chap_client_state;
#if PPP_SERVER
typedef struct chap_server_state {
u8_t flags;
u8_t id;
const char *name;
const struct chap_digest_type *digest;
int challenge_xmits;
int challenge_pktlen;
unsigned char challenge[CHAL_MAX_PKTLEN];
} chap_server_state;
#endif
#endif
#if 0#endif
#if PPP_SERVER
extern void chap_auth_peer(ppp_pcb *pcb, const char *our_name, int digest_code);
#endif
extern void chap_auth_with_peer(ppp_pcb *pcb, const char *our_name, int digest_code);
extern const struct protent chap_protent;
#ifdef __cplusplus
}
#endif
#endif
#endif