PPP, changed all the code enclosed between PPP_SERVER #if macro to our PPP PCB structure, making it easier to support PPP server in the future

This commit is contained in:
Sylvain Rochet 2012-09-27 23:53:20 +02:00
parent 7fb874ad28
commit e81f092520
9 changed files with 143 additions and 137 deletions

View File

@ -64,6 +64,13 @@
#define MAX_CHALLENGE_LEN 64 #define MAX_CHALLENGE_LEN 64
#define MAX_RESPONSE_LEN 64 #define MAX_RESPONSE_LEN 64
/*
* These limits apply to challenge and response packets we send.
* The +4 is the +1 that we actually need rounded up.
*/
#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)
/* bitmask of supported algorithms */ /* bitmask of supported algorithms */
#if MSCHAP_SUPPORT #if MSCHAP_SUPPORT
#define MDTYPE_MICROSOFT_V2 0x1 #define MDTYPE_MICROSOFT_V2 0x1
@ -152,7 +159,7 @@ typedef struct chap_client_state {
} chap_client_state; } chap_client_state;
#if PPP_SERVER #if PPP_SERVER
static struct chap_server_state { typedef struct chap_server_state {
u8_t flags; u8_t flags;
int id; int id;
char *name; char *name;

View File

@ -158,8 +158,9 @@ typedef struct ppp_settings_s {
#if PPP_SERVER #if PPP_SERVER
unsigned int auth_required : 1; /* Peer is required to authenticate */ unsigned int auth_required : 1; /* Peer is required to authenticate */
unsigned int null_login : 1; /* Username of "" and a password of "" are acceptable */
#else #else
unsigned int :1; /* 1 bit of padding */ unsigned int :2; /* 2 bits of padding */
#endif /* PPP_SERVER */ #endif /* PPP_SERVER */
#if PPP_REMOTENAME #if PPP_REMOTENAME
unsigned int explicit_remote : 1; /* remote_name specified with remotename opt */ unsigned int explicit_remote : 1; /* remote_name specified with remotename opt */
@ -202,7 +203,7 @@ typedef struct ppp_settings_s {
#else #else
unsigned int :1; /* 1 bit of padding */ unsigned int :1; /* 1 bit of padding */
#endif #endif
unsigned int :2; /* 2 bits of padding to round out to 16 bits */ unsigned int :1; /* 1 bit of padding to round out to 16 bits */
u16_t listen_time; /* time to listen first (ms), waiting for peer to send LCP packet */ u16_t listen_time; /* time to listen first (ms), waiting for peer to send LCP packet */

View File

@ -104,7 +104,7 @@ typedef struct upap_state {
u8_t us_passwdlen; /* Password length */ u8_t us_passwdlen; /* Password length */
u8_t us_clientstate; /* Client state */ u8_t us_clientstate; /* Client state */
#if PPP_SERVER #if PPP_SERVER
u8_t us_serverstate /* Server state */ u8_t us_serverstate; /* Server state */
#endif /* PPP_SERVER */ #endif /* PPP_SERVER */
u8_t us_id; /* Current id */ u8_t us_id; /* Current id */
u8_t us_timeouttime; /* Timeout (seconds) for auth-req retrans. */ u8_t us_timeouttime; /* Timeout (seconds) for auth-req retrans. */

View File

@ -729,15 +729,16 @@ void upper_layers_down(ppp_pcb *pcb) {
*/ */
void link_established(ppp_pcb *pcb) { void link_established(ppp_pcb *pcb) {
int auth; int auth;
#if 0 /* UNUSED */
lcp_options *wo = &lcp_wantoptions[pcb->unit];
#endif /* UNUSED */
#if PPP_SERVER #if PPP_SERVER
lcp_options *go = &lcp_gotoptions[pcb->unit]; lcp_options *wo = &pcb->lcp_wantoptions;
#endif /* #if PPP_SERVER */ lcp_options *go = &pcb->lcp_gotoptions;
#endif /* PPP_SERVER */
lcp_options *ho = &pcb->lcp_hisoptions; lcp_options *ho = &pcb->lcp_hisoptions;
int i; int i;
struct protent *protp; struct protent *protp;
#if PPP_SERVER
int errcode;
#endif /* PPP_SERVER */
/* /*
* Tell higher-level protocols that LCP is up. * Tell higher-level protocols that LCP is up.
@ -749,13 +750,13 @@ void link_established(ppp_pcb *pcb) {
(*protp->lowerup)(pcb); (*protp->lowerup)(pcb);
} }
#if 0 /* UNUSED */ #if PPP_SERVER
#if PPP_ALLOWED_ADDRS #if PPP_ALLOWED_ADDRS
if (!auth_required && noauth_addrs != NULL) if (!auth_required && noauth_addrs != NULL)
set_allowed_addrs(unit, NULL, NULL); set_allowed_addrs(unit, NULL, NULL);
#endif /* PPP_ALLOWED_ADDRS */ #endif /* PPP_ALLOWED_ADDRS */
if (auth_required && !(0 if (pcb->settings.auth_required && !(0
#if PAP_SUPPORT #if PAP_SUPPORT
|| go->neg_upap || go->neg_upap
#endif /* PAP_SUPPORT */ #endif /* PAP_SUPPORT */
@ -779,14 +780,18 @@ void link_established(ppp_pcb *pcb) {
set_allowed_addrs(unit, NULL, NULL); set_allowed_addrs(unit, NULL, NULL);
} else } else
#endif /* PPP_ALLOWED_ADDRS */ #endif /* PPP_ALLOWED_ADDRS */
if (!wo->neg_upap || uselogin || !null_login(unit)) { if (!wo->neg_upap || !pcb->settings.null_login) {
ppp_warn("peer refused to authenticate: terminating link"); ppp_warn("peer refused to authenticate: terminating link");
#if 0 /* UNUSED */
status = EXIT_PEER_AUTH_FAILED; status = EXIT_PEER_AUTH_FAILED;
#endif /* UNUSED */
errcode = PPPERR_AUTHFAIL;
ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode);
lcp_close(pcb, "peer refused to authenticate"); lcp_close(pcb, "peer refused to authenticate");
return; return;
} }
} }
#endif /* UNUSED */ #endif /* PPP_SERVER */
new_phase(pcb, PHASE_AUTHENTICATE); new_phase(pcb, PHASE_AUTHENTICATE);
auth = 0; auth = 0;
@ -997,10 +1002,14 @@ void continue_networks(ppp_pcb *pcb) {
* The peer has failed to authenticate himself using `protocol'. * The peer has failed to authenticate himself using `protocol'.
*/ */
void auth_peer_fail(ppp_pcb *pcb, int protocol) { void auth_peer_fail(ppp_pcb *pcb, int protocol) {
int errcode = PPPERR_AUTHFAIL;
/* /*
* Authentication failure: take the link down * Authentication failure: take the link down
*/ */
#if 0 /* UNUSED */
status = EXIT_PEER_AUTH_FAILED; status = EXIT_PEER_AUTH_FAILED;
#endif /* UNUSED */
ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode);
lcp_close(pcb, "Authentication failed"); lcp_close(pcb, "Authentication failed");
} }
@ -1064,7 +1073,7 @@ void auth_peer_success(ppp_pcb *pcb, int protocol, int prot_flavor, char *name,
* proceed to the network (or callback) phase. * proceed to the network (or callback) phase.
*/ */
if ((pcb->auth_pending &= ~bit) == 0) if ((pcb->auth_pending &= ~bit) == 0)
network_phase(unit); network_phase(pcb);
} }
#endif /* PPP_SERVER */ #endif /* PPP_SERVER */

View File

@ -83,11 +83,11 @@ static int chap_md5_verify_response(int id, char *name,
/* Test if our hash matches the peer's response */ /* Test if our hash matches the peer's response */
if (memcmp(hash, response, MD5_HASH_SIZE) == 0) { if (memcmp(hash, response, MD5_HASH_SIZE) == 0) {
slprintf(message, message_space, "Access granted"); ppp_slprintf(message, message_space, "Access granted");
return 1; return 1;
} }
} }
slprintf(message, message_space, "Access denied"); ppp_slprintf(message, message_space, "Access denied");
return 0; return 0;
} }
#endif /* PPP_SERVER */ #endif /* PPP_SERVER */

View File

@ -69,12 +69,6 @@ static option_t chap_option_list[] = {
}; };
#endif /* PPP_OPTIONS */ #endif /* PPP_OPTIONS */
/*
* These limits apply to challenge and response packets we send.
* The +4 is the +1 that we actually need rounded up.
*/
#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)
/* Values for flags in chap_client_state and chap_server_state */ /* Values for flags in chap_client_state and chap_server_state */
#define LOWERUP 1 #define LOWERUP 1
@ -168,7 +162,7 @@ static void chap_lowerdown(ppp_pcb *pcb) {
* otherwise we wait for the lower layer to come up. * otherwise we wait for the lower layer to come up.
*/ */
void chap_auth_peer(ppp_pcb *pcb, char *our_name, int digest_code) { void chap_auth_peer(ppp_pcb *pcb, char *our_name, int digest_code) {
struct chap_server_state *ss = &server; struct chap_server_state *ss = &pcb->chap_server;
struct chap_digest_type *dp; struct chap_digest_type *dp;
if (pcb->chap_server.flags & AUTH_STARTED) { if (pcb->chap_server.flags & AUTH_STARTED) {
@ -309,10 +303,12 @@ static void chap_handle_response(ppp_pcb *pcb, int id,
pcb->chap_server.flags &= ~TIMEOUT_PENDING; pcb->chap_server.flags &= ~TIMEOUT_PENDING;
UNTIMEOUT(chap_timeout, pcb); UNTIMEOUT(chap_timeout, pcb);
} }
#if PPP_REMOTENAME
if (explicit_remote) { if (pcb->settings.explicit_remote) {
name = remote_name; name = pcb->remote_name;
} else { } else
#endif /* PPP_REMOTENAME */
{
/* Null terminate and clean remote name. */ /* Null terminate and clean remote name. */
ppp_slprintf(rname, sizeof(rname), "%.*v", len, name); ppp_slprintf(rname, sizeof(rname), "%.*v", len, name);
name = rname; name = rname;
@ -409,12 +405,14 @@ static int chap_verify_response(char *name, char *ourname, int id,
unsigned char secret[MAXSECRETLEN]; unsigned char secret[MAXSECRETLEN];
int secret_len; int secret_len;
/* FIXME: we need a way to check peer secret */
#if 0
/* Get the secret that the peer is supposed to know */ /* Get the secret that the peer is supposed to know */
if (!get_secret(pcb, name, ourname, (char *)secret, &secret_len, 1)) { if (!get_secret(pcb, name, ourname, (char *)secret, &secret_len, 1)) {
ppp_error("No CHAP secret found for authenticating %q", name); ppp_error("No CHAP secret found for authenticating %q", name);
return 0; return 0;
} }
#endif
ok = digest->verify_response(id, name, secret, secret_len, challenge, ok = digest->verify_response(id, name, secret, secret_len, challenge,
response, message, message_space); response, message, message_space);
memset(secret, 0, sizeof(secret)); memset(secret, 0, sizeof(secret));

View File

@ -217,7 +217,7 @@ static int chapms_verify_response(int id, char *name,
#ifndef MSLANMAN #ifndef MSLANMAN
if (!response[MS_CHAP_USENT]) { if (!response[MS_CHAP_USENT]) {
/* Should really propagate this into the error packet. */ /* Should really propagate this into the error packet. */
notice("Peer request for LANMAN auth not supported"); ppp_notice("Peer request for LANMAN auth not supported");
goto bad; goto bad;
} }
#endif #endif
@ -236,13 +236,13 @@ static int chapms_verify_response(int id, char *name,
MS_CHAP_NTRESP_LEN); MS_CHAP_NTRESP_LEN);
if (diff == 0) { if (diff == 0) {
slprintf(message, message_space, "Access granted"); ppp_slprintf(message, message_space, "Access granted");
return 1; return 1;
} }
bad: bad:
/* See comments below for MS-CHAP V2 */ /* See comments below for MS-CHAP V2 */
slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0", ppp_slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0",
challenge_len, challenge); challenge_len, challenge);
return 0; return 0;
} }
@ -288,9 +288,9 @@ static int chapms2_verify_response(int id, char *name,
if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP], if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP],
MS_CHAP2_NTRESP_LEN) == 0) { MS_CHAP2_NTRESP_LEN) == 0) {
if (response[MS_CHAP2_FLAGS]) if (response[MS_CHAP2_FLAGS])
slprintf(message, message_space, "S=%s", saresponse); ppp_slprintf(message, message_space, "S=%s", saresponse);
else else
slprintf(message, message_space, "S=%s M=%s", ppp_slprintf(message, message_space, "S=%s M=%s",
saresponse, "Access granted"); saresponse, "Access granted");
return 1; return 1;
} }
@ -317,7 +317,7 @@ static int chapms2_verify_response(int id, char *name,
* Basically, this whole bit is useless code, even the small * Basically, this whole bit is useless code, even the small
* implementation here is only because of overspecification. * implementation here is only because of overspecification.
*/ */
slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s", ppp_slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s",
challenge_len, challenge, "Access denied"); challenge_len, challenge, "Access denied");
return 0; return 0;
} }

View File

@ -258,11 +258,7 @@ void eap_authwithpeer(ppp_pcb *pcb, char *localname) {
* Format a standard EAP Failure message and send it to the peer. * Format a standard EAP Failure message and send it to the peer.
* (Server operation) * (Server operation)
*/ */
static void static void eap_send_failure(ppp_pcb *pcb) {
eap_send_failure(esp)
eap_state *esp;
{
ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit];
struct pbuf *p; struct pbuf *p;
u_char *outp; u_char *outp;
@ -293,11 +289,7 @@ eap_state *esp;
* Format a standard EAP Success message and send it to the peer. * Format a standard EAP Success message and send it to the peer.
* (Server operation) * (Server operation)
*/ */
static void static void eap_send_success(ppp_pcb *pcb) {
eap_send_success(esp)
eap_state *esp;
{
ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit];
struct pbuf *p; struct pbuf *p;
u_char *outp; u_char *outp;
@ -441,11 +433,7 @@ u_char *outp;
* indicates if there was an error in handling the last query. It is * indicates if there was an error in handling the last query. It is
* 0 for success and non-zero for failure. * 0 for success and non-zero for failure.
*/ */
static void static void eap_figure_next_state(ppp_pcb *pcb, int status) {
eap_figure_next_state(esp, status)
eap_state *esp;
int status;
{
#ifdef USE_SRP #ifdef USE_SRP
unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp; unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp;
struct t_pw tpw; struct t_pw tpw;
@ -651,18 +639,14 @@ int status;
break; break;
} }
if (pcb->eap.es_server.ea_state == eapBadAuth) if (pcb->eap.es_server.ea_state == eapBadAuth)
eap_send_failure(esp); eap_send_failure(pcb);
} }
/* /*
* Format an EAP Request message and send it to the peer. Message * Format an EAP Request message and send it to the peer. Message
* type depends on current state. (Server operation) * type depends on current state. (Server operation)
*/ */
static void static void eap_send_request(ppp_pcb *pcb) {
eap_send_request(esp)
eap_state *esp;
{
ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit];
struct pbuf *p; struct pbuf *p;
u_char *outp; u_char *outp;
u_char *lenloc; u_char *lenloc;
@ -682,16 +666,18 @@ eap_state *esp;
if (pcb->eap.es_server.ea_state < eapIdentify && if (pcb->eap.es_server.ea_state < eapIdentify &&
pcb->eap.es_server.ea_state != eapInitial) { pcb->eap.es_server.ea_state != eapInitial) {
pcb->eap.es_server.ea_state = eapIdentify; pcb->eap.es_server.ea_state = eapIdentify;
if (explicit_remote) { #if PPP_REMOTENAME
if (pcb->settings.explicit_remote) {
/* /*
* If we already know the peer's * If we already know the peer's
* unauthenticated name, then there's no * unauthenticated name, then there's no
* reason to ask. Go to next state instead. * reason to ask. Go to next state instead.
*/ */
pcb->eap.es_server.ea_peer = remote_name; pcb->eap.es_server.ea_peer = pcb->remote_name;
pcb->eap.es_server.ea_peerlen = strlen(remote_name); pcb->eap.es_server.ea_peerlen = strlen(pcb->remote_name);
eap_figure_next_state(esp, 0); eap_figure_next_state(pcb, 0);
} }
#endif /* PPP_REMOTENAME */
} }
if (pcb->eap.es_server.ea_maxrequests > 0 && if (pcb->eap.es_server.ea_maxrequests > 0 &&
@ -700,7 +686,7 @@ eap_state *esp;
ppp_error("EAP: too many Requests sent"); ppp_error("EAP: too many Requests sent");
else else
ppp_error("EAP: no response to Requests"); ppp_error("EAP: no response to Requests");
eap_send_failure(esp); eap_send_failure(pcb);
return; return;
} }
@ -888,7 +874,7 @@ eap_state *esp;
return; return;
} }
outlen = (outp - p->payload) - PPP_HDRLEN; outlen = (outp - (unsigned char*)p->payload) - PPP_HDRLEN;
PUTSHORT(outlen, lenloc); PUTSHORT(outlen, lenloc);
pbuf_realloc(p, outlen + PPP_HDRLEN); pbuf_realloc(p, outlen + PPP_HDRLEN);
@ -907,7 +893,6 @@ eap_state *esp;
* after eap_lowerup. * after eap_lowerup.
*/ */
void eap_authpeer(ppp_pcb *pcb, char *localname) { void eap_authpeer(ppp_pcb *pcb, char *localname) {
eap_state *esp = &eap_states[unit];
/* Save the name we're given. */ /* Save the name we're given. */
pcb->eap.es_server.ea_name = localname; pcb->eap.es_server.ea_name = localname;
@ -925,7 +910,7 @@ void eap_authpeer(ppp_pcb *pcb, char *localname) {
pcb->eap.es_server.ea_state = eapPending; pcb->eap.es_server.ea_state = eapPending;
/* ID number not updated here intentionally; hashed into M1 */ /* ID number not updated here intentionally; hashed into M1 */
eap_send_request(esp); eap_send_request(pcb);
} }
/* /*
@ -935,11 +920,11 @@ void eap_authpeer(ppp_pcb *pcb, char *localname) {
static void eap_server_timeout(void *arg) { static void eap_server_timeout(void *arg) {
ppp_pcb *pcb = (ppp_pcb*)arg; ppp_pcb *pcb = (ppp_pcb*)arg;
if (!eap_server_active(esp)) if (!eap_server_active(pcb))
return; return;
/* EAP ID number must not change on timeout. */ /* EAP ID number must not change on timeout. */
eap_send_request(esp); eap_send_request(pcb);
} }
/* /*
@ -947,11 +932,8 @@ static void eap_server_timeout(void *arg) {
* called. Once the rechallenge is successful, the response handler * called. Once the rechallenge is successful, the response handler
* will restart the timer. If it fails, then the link is dropped. * will restart the timer. If it fails, then the link is dropped.
*/ */
static void static void eap_rechallenge(void *arg) {
eap_rechallenge(arg) ppp_pcb *pcb = (ppp_pcb*)arg;
void *arg;
{
eap_state *esp = (eap_state *)arg;
if (pcb->eap.es_server.ea_state != eapOpen && if (pcb->eap.es_server.ea_state != eapOpen &&
pcb->eap.es_server.ea_state != eapSRP4) pcb->eap.es_server.ea_state != eapSRP4)
@ -959,16 +941,13 @@ void *arg;
pcb->eap.es_server.ea_requests = 0; pcb->eap.es_server.ea_requests = 0;
pcb->eap.es_server.ea_state = eapIdentify; pcb->eap.es_server.ea_state = eapIdentify;
eap_figure_next_state(esp, 0); eap_figure_next_state(pcb, 0);
pcb->eap.es_server.ea_id++; pcb->eap.es_server.ea_id++;
eap_send_request(esp); eap_send_request(pcb);
} }
static void static void srp_lwrechallenge(void *arg) {
srp_lwrechallenge(arg) ppp_pcb *pcb = (ppp_pcb*)arg;
void *arg;
{
eap_state *esp = (eap_state *)arg;
if (pcb->eap.es_server.ea_state != eapOpen || if (pcb->eap.es_server.ea_state != eapOpen ||
pcb->eap.es_server.ea_type != EAPT_SRP) pcb->eap.es_server.ea_type != EAPT_SRP)
@ -977,7 +956,7 @@ void *arg;
pcb->eap.es_server.ea_requests = 0; pcb->eap.es_server.ea_requests = 0;
pcb->eap.es_server.ea_state = eapSRP4; pcb->eap.es_server.ea_state = eapSRP4;
pcb->eap.es_server.ea_id++; pcb->eap.es_server.ea_id++;
eap_send_request(esp); eap_send_request(pcb);
} }
#endif /* PPP_SERVER */ #endif /* PPP_SERVER */
@ -993,8 +972,11 @@ static void eap_lowerup(ppp_pcb *pcb) {
/* Discard any (possibly authenticated) peer name. */ /* Discard any (possibly authenticated) peer name. */
#if PPP_SERVER #if PPP_SERVER
if (pcb->eap.es_server.ea_peer != NULL && if (pcb->eap.es_server.ea_peer != NULL
pcb->eap.es_server.ea_peer != remote_name) #if PPP_REMOTENAME
&& pcb->eap.es_server.ea_peer != pcb->remote_name
#endif /* PPP_REMOTENAME */
)
free(pcb->eap.es_server.ea_peer); free(pcb->eap.es_server.ea_peer);
pcb->eap.es_server.ea_peer = NULL; pcb->eap.es_server.ea_peer = NULL;
#endif /* PPP_SERVER */ #endif /* PPP_SERVER */
@ -1019,7 +1001,7 @@ static void eap_lowerdown(ppp_pcb *pcb) {
UNTIMEOUT(eap_client_timeout, pcb); UNTIMEOUT(eap_client_timeout, pcb);
} }
#if PPP_SERVER #if PPP_SERVER
if (eap_server_active(esp)) { if (eap_server_active(pcb)) {
if (pcb->eap.es_server.ea_timeout > 0) { if (pcb->eap.es_server.ea_timeout > 0) {
UNTIMEOUT(eap_server_timeout, pcb); UNTIMEOUT(eap_server_timeout, pcb);
} }
@ -1027,11 +1009,11 @@ static void eap_lowerdown(ppp_pcb *pcb) {
if ((pcb->eap.es_server.ea_state == eapOpen || if ((pcb->eap.es_server.ea_state == eapOpen ||
pcb->eap.es_server.ea_state == eapSRP4) && pcb->eap.es_server.ea_state == eapSRP4) &&
pcb->eap.es_rechallenge > 0) { pcb->eap.es_rechallenge > 0) {
UNTIMEOUT(eap_rechallenge, (void *)esp); UNTIMEOUT(eap_rechallenge, (void *)pcb);
} }
if (pcb->eap.es_server.ea_state == eapOpen && if (pcb->eap.es_server.ea_state == eapOpen &&
pcb->eap.es_lwrechallenge > 0) { pcb->eap.es_lwrechallenge > 0) {
UNTIMEOUT(srp_lwrechallenge, (void *)esp); UNTIMEOUT(srp_lwrechallenge, (void *)pcb);
} }
} }
@ -1053,7 +1035,7 @@ static void eap_protrej(ppp_pcb *pcb) {
auth_withpeer_fail(pcb, PPP_EAP); auth_withpeer_fail(pcb, PPP_EAP);
} }
#if PPP_SERVER #if PPP_SERVER
if (eap_server_active(esp)) { if (eap_server_active(pcb)) {
ppp_error("EAP authentication of peer failed on Protocol-Reject"); ppp_error("EAP authentication of peer failed on Protocol-Reject");
auth_peer_fail(pcb, PPP_EAP); auth_peer_fail(pcb, PPP_EAP);
} }
@ -1807,19 +1789,22 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) {
break; break;
} }
ppp_info("EAP: unauthenticated peer name \"%.*q\"", len, inp); ppp_info("EAP: unauthenticated peer name \"%.*q\"", len, inp);
if (pcb->eap.es_server.ea_peer != NULL && if (pcb->eap.es_server.ea_peer != NULL
pcb->eap.es_server.ea_peer != remote_name) #if PPP_REMOTENAME
&& pcb->eap.es_server.ea_peer != pcb->remote_name
#endif /* PPP_REMOTENAME */
)
free(pcb->eap.es_server.ea_peer); free(pcb->eap.es_server.ea_peer);
pcb->eap.es_server.ea_peer = malloc(len + 1); pcb->eap.es_server.ea_peer = malloc(len + 1);
if (pcb->eap.es_server.ea_peer == NULL) { if (pcb->eap.es_server.ea_peer == NULL) {
pcb->eap.es_server.ea_peerlen = 0; pcb->eap.es_server.ea_peerlen = 0;
eap_figure_next_state(esp, 1); eap_figure_next_state(pcb, 1);
break; break;
} }
MEMCPY(pcb->eap.es_server.ea_peer, inp, len); MEMCPY(pcb->eap.es_server.ea_peer, inp, len);
pcb->eap.es_server.ea_peer[len] = '\0'; pcb->eap.es_server.ea_peer[len] = '\0';
pcb->eap.es_server.ea_peerlen = len; pcb->eap.es_server.ea_peerlen = len;
eap_figure_next_state(esp, 0); eap_figure_next_state(pcb, 0);
break; break;
case EAPT_NOTIFICATION: case EAPT_NOTIFICATION:
@ -1829,16 +1814,20 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) {
case EAPT_NAK: case EAPT_NAK:
if (len < 1) { if (len < 1) {
ppp_info("EAP: Nak Response with no suggested protocol"); ppp_info("EAP: Nak Response with no suggested protocol");
eap_figure_next_state(esp, 1); eap_figure_next_state(pcb, 1);
break; break;
} }
GETCHAR(vallen, inp); GETCHAR(vallen, inp);
len--; len--;
if (!explicit_remote && pcb->eap.es_server.ea_state == eapIdentify){ if (
#if PPP_REMOTENAME
!pcb->explicit_remote &&
#endif /* PPP_REMOTENAME */
pcb->eap.es_server.ea_state == eapIdentify){
/* Peer cannot Nak Identify Request */ /* Peer cannot Nak Identify Request */
eap_figure_next_state(esp, 1); eap_figure_next_state(pcb, 1);
break; break;
} }
@ -1846,7 +1835,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) {
case EAPT_SRP: case EAPT_SRP:
/* Run through SRP validator selection again. */ /* Run through SRP validator selection again. */
pcb->eap.es_server.ea_state = eapIdentify; pcb->eap.es_server.ea_state = eapIdentify;
eap_figure_next_state(esp, 0); eap_figure_next_state(pcb, 0);
break; break;
case EAPT_MD5CHAP: case EAPT_MD5CHAP:
@ -1864,7 +1853,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) {
case eapMD5Chall: case eapMD5Chall:
case eapSRP4: case eapSRP4:
pcb->eap.es_server.ea_state = eapIdentify; pcb->eap.es_server.ea_state = eapIdentify;
eap_figure_next_state(esp, 0); eap_figure_next_state(pcb, 0);
break; break;
default: default:
break; break;
@ -1876,19 +1865,19 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) {
case EAPT_MD5CHAP: case EAPT_MD5CHAP:
if (pcb->eap.es_server.ea_state != eapMD5Chall) { if (pcb->eap.es_server.ea_state != eapMD5Chall) {
ppp_error("EAP: unexpected MD5-Response"); ppp_error("EAP: unexpected MD5-Response");
eap_figure_next_state(esp, 1); eap_figure_next_state(pcb, 1);
break; break;
} }
if (len < 1) { if (len < 1) {
ppp_error("EAP: received MD5-Response with no data"); ppp_error("EAP: received MD5-Response with no data");
eap_figure_next_state(esp, 1); eap_figure_next_state(pcb, 1);
break; break;
} }
GETCHAR(vallen, inp); GETCHAR(vallen, inp);
len--; len--;
if (vallen != 16 || vallen > len) { if (vallen != 16 || vallen > len) {
ppp_error("EAP: MD5-Response with bad length %d", vallen); ppp_error("EAP: MD5-Response with bad length %d", vallen);
eap_figure_next_state(esp, 1); eap_figure_next_state(pcb, 1);
break; break;
} }
@ -1902,10 +1891,12 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) {
rhostname[len - vallen] = '\0'; rhostname[len - vallen] = '\0';
} }
#if PPP_REMOTENAME
/* In case the remote doesn't give us his name. */ /* In case the remote doesn't give us his name. */
if (explicit_remote || if (explicit_remote ||
(remote_name[0] != '\0' && vallen == len)) (remote_name[0] != '\0' && vallen == len))
strlcpy(rhostname, remote_name, sizeof (rhostname)); strlcpy(rhostname, remote_name, sizeof (rhostname));
#endif /* PPP_REMOTENAME */
/* /*
* Get the secret for authenticating the specified * Get the secret for authenticating the specified
@ -1914,7 +1905,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) {
if (!get_secret(pcb, rhostname, if (!get_secret(pcb, rhostname,
pcb->eap.es_server.ea_name, secret, &secret_len, 1)) { pcb->eap.es_server.ea_name, secret, &secret_len, 1)) {
ppp_dbglog("EAP: no MD5 secret for auth of %q", rhostname); ppp_dbglog("EAP: no MD5 secret for auth of %q", rhostname);
eap_send_failure(esp); eap_send_failure(pcb);
break; break;
} }
md5_starts(&mdContext); md5_starts(&mdContext);
@ -1924,21 +1915,21 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) {
md5_update(&mdContext, pcb->eap.es_challenge, pcb->eap.es_challen); md5_update(&mdContext, pcb->eap.es_challenge, pcb->eap.es_challen);
md5_finish(&mdContext, hash); md5_finish(&mdContext, hash);
if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) { if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) {
eap_send_failure(esp); eap_send_failure(pcb);
break; break;
} }
pcb->eap.es_server.ea_type = EAPT_MD5CHAP; pcb->eap.es_server.ea_type = EAPT_MD5CHAP;
eap_send_success(esp); eap_send_success(pcb);
eap_figure_next_state(esp, 0); eap_figure_next_state(pcb, 0);
if (pcb->eap.es_rechallenge != 0) if (pcb->eap.es_rechallenge != 0)
TIMEOUT(eap_rechallenge, esp, pcb->eap.es_rechallenge); TIMEOUT(eap_rechallenge, pcb, pcb->eap.es_rechallenge);
break; break;
#ifdef USE_SRP #ifdef USE_SRP
case EAPT_SRP: case EAPT_SRP:
if (len < 1) { if (len < 1) {
ppp_error("EAP: empty SRP Response"); ppp_error("EAP: empty SRP Response");
eap_figure_next_state(esp, 1); eap_figure_next_state(pcb, 1);
break; break;
} }
GETCHAR(typenum, inp); GETCHAR(typenum, inp);
@ -1947,7 +1938,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) {
case EAPSRP_CKEY: case EAPSRP_CKEY:
if (pcb->eap.es_server.ea_state != eapSRP1) { if (pcb->eap.es_server.ea_state != eapSRP1) {
ppp_error("EAP: unexpected SRP Subtype 1 Response"); ppp_error("EAP: unexpected SRP Subtype 1 Response");
eap_figure_next_state(esp, 1); eap_figure_next_state(pcb, 1);
break; break;
} }
A.data = inp; A.data = inp;
@ -1958,22 +1949,22 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) {
if (pcb->eap.es_server.ea_skey == NULL) { if (pcb->eap.es_server.ea_skey == NULL) {
/* Client's A value is bogus; terminate now */ /* Client's A value is bogus; terminate now */
ppp_error("EAP: bogus A value from client"); ppp_error("EAP: bogus A value from client");
eap_send_failure(esp); eap_send_failure(pcb);
} else { } else {
eap_figure_next_state(esp, 0); eap_figure_next_state(pcb, 0);
} }
break; break;
case EAPSRP_CVALIDATOR: case EAPSRP_CVALIDATOR:
if (pcb->eap.es_server.ea_state != eapSRP2) { if (pcb->eap.es_server.ea_state != eapSRP2) {
ppp_error("EAP: unexpected SRP Subtype 2 Response"); ppp_error("EAP: unexpected SRP Subtype 2 Response");
eap_figure_next_state(esp, 1); eap_figure_next_state(pcb, 1);
break; break;
} }
if (len < sizeof (u32_t) + SHA_DIGESTSIZE) { if (len < sizeof (u32_t) + SHA_DIGESTSIZE) {
ppp_error("EAP: M1 length %d < %d", len, ppp_error("EAP: M1 length %d < %d", len,
sizeof (u32_t) + SHA_DIGESTSIZE); sizeof (u32_t) + SHA_DIGESTSIZE);
eap_figure_next_state(esp, 1); eap_figure_next_state(pcb, 1);
break; break;
} }
GETLONG(pcb->eap.es_server.ea_keyflags, inp); GETLONG(pcb->eap.es_server.ea_keyflags, inp);
@ -1981,10 +1972,10 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) {
assert(ts != NULL); assert(ts != NULL);
if (t_serververify(ts, inp)) { if (t_serververify(ts, inp)) {
ppp_info("EAP: unable to validate client identity"); ppp_info("EAP: unable to validate client identity");
eap_send_failure(esp); eap_send_failure(pcb);
break; break;
} }
eap_figure_next_state(esp, 0); eap_figure_next_state(pcb, 0);
break; break;
case EAPSRP_ACK: case EAPSRP_ACK:
@ -1994,13 +1985,13 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) {
break; break;
} }
pcb->eap.es_server.ea_type = EAPT_SRP; pcb->eap.es_server.ea_type = EAPT_SRP;
eap_send_success(esp); eap_send_success(pcb, esp);
eap_figure_next_state(esp, 0); eap_figure_next_state(pcb, 0);
if (pcb->eap.es_rechallenge != 0) if (pcb->eap.es_rechallenge != 0)
TIMEOUT(eap_rechallenge, esp, TIMEOUT(eap_rechallenge, pcb,
pcb->eap.es_rechallenge); pcb->eap.es_rechallenge);
if (pcb->eap.es_lwrechallenge != 0) if (pcb->eap.es_lwrechallenge != 0)
TIMEOUT(srp_lwrechallenge, esp, TIMEOUT(srp_lwrechallenge, pcb,
pcb->eap.es_lwrechallenge); pcb->eap.es_lwrechallenge);
break; break;
@ -2025,7 +2016,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) {
SHA1Final(dig, &ctxt); SHA1Final(dig, &ctxt);
if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) { if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
ppp_error("EAP: failed Lightweight rechallenge"); ppp_error("EAP: failed Lightweight rechallenge");
eap_send_failure(esp); eap_send_failure(pcb);
break; break;
} }
pcb->eap.es_server.ea_state = eapOpen; pcb->eap.es_server.ea_state = eapOpen;
@ -2050,7 +2041,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) {
if (pcb->eap.es_server.ea_state != eapBadAuth && if (pcb->eap.es_server.ea_state != eapBadAuth &&
pcb->eap.es_server.ea_state != eapOpen) { pcb->eap.es_server.ea_state != eapOpen) {
pcb->eap.es_server.ea_id++; pcb->eap.es_server.ea_id++;
eap_send_request(esp); eap_send_request(pcb);
} }
} }
#endif /* PPP_SERVER */ #endif /* PPP_SERVER */

View File

@ -120,16 +120,14 @@ struct protent pap_protent = {
static void upap_timeout(void *arg); static void upap_timeout(void *arg);
#if PPP_SERVER #if PPP_SERVER
static void upap_reqtimeout(void *arg); static void upap_reqtimeout(void *arg);
#endif /* PPP_SERVER */
#if 0 /* UNUSED */
static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len); static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len);
#endif /* UNUSED */ #endif /* PPP_SERVER */
static void upap_rauthack(ppp_pcb *pcb, u_char *inp, int id, int len); static void upap_rauthack(ppp_pcb *pcb, u_char *inp, int id, int len);
static void upap_rauthnak(ppp_pcb *pcb, u_char *inp, int id, int len); static void upap_rauthnak(ppp_pcb *pcb, u_char *inp, int id, int len);
static void upap_sauthreq(ppp_pcb *pcb); static void upap_sauthreq(ppp_pcb *pcb);
#if 0 /* UNUSED */ #if PPP_SERVER
static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, char *msg, int msglen); static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, char *msg, int msglen);
#endif /* UNUSED */ #endif /* PPP_SERVER */
/* /*
@ -255,7 +253,7 @@ static void upap_lowerup(ppp_pcb *pcb) {
else if (pcb->upap.us_serverstate == UPAPSS_PENDING) { else if (pcb->upap.us_serverstate == UPAPSS_PENDING) {
pcb->upap.us_serverstate = UPAPSS_LISTEN; pcb->upap.us_serverstate = UPAPSS_LISTEN;
if (pcb->upap.us_reqtimeout > 0) if (pcb->upap.us_reqtimeout > 0)
TIMEOUT(upap_reqtimeout, u, pcb->upap.us_reqtimeout); TIMEOUT(upap_reqtimeout, pcb, pcb->upap.us_reqtimeout);
} }
#endif /* PPP_SERVER */ #endif /* PPP_SERVER */
} }
@ -272,7 +270,7 @@ static void upap_lowerdown(ppp_pcb *pcb) {
UNTIMEOUT(upap_timeout, pcb); /* Cancel timeout */ UNTIMEOUT(upap_timeout, pcb); /* Cancel timeout */
#if PPP_SERVER #if PPP_SERVER
if (pcb->upap.us_serverstate == UPAPSS_LISTEN && pcb->upap.us_reqtimeout > 0) if (pcb->upap.us_serverstate == UPAPSS_LISTEN && pcb->upap.us_reqtimeout > 0)
UNTIMEOUT(upap_reqtimeout, u); UNTIMEOUT(upap_reqtimeout, pcb);
#endif /* PPP_SERVER */ #endif /* PPP_SERVER */
pcb->upap.us_clientstate = UPAPCS_INITIAL; pcb->upap.us_clientstate = UPAPCS_INITIAL;
@ -338,9 +336,9 @@ static void upap_input(ppp_pcb *pcb, u_char *inpacket, int l) {
*/ */
switch (code) { switch (code) {
case UPAP_AUTHREQ: case UPAP_AUTHREQ:
#if 0 /* UNUSED */ #if PPP_SERVER
upap_rauthreq(pcb, inp, id, len); upap_rauthreq(pcb, inp, id, len);
#endif /* UNUSED */ #endif /* PPP_SERVER */
break; break;
case UPAP_AUTHACK: case UPAP_AUTHACK:
@ -356,7 +354,7 @@ static void upap_input(ppp_pcb *pcb, u_char *inpacket, int l) {
} }
} }
#if 0 /* UNUSED */ #if PPP_SERVER
/* /*
* upap_rauth - Receive Authenticate. * upap_rauth - Receive Authenticate.
*/ */
@ -376,11 +374,11 @@ static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len) {
* supposed to return the same status as for the first request. * supposed to return the same status as for the first request.
*/ */
if (pcb->upap.us_serverstate == UPAPSS_OPEN) { if (pcb->upap.us_serverstate == UPAPSS_OPEN) {
upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */ upap_sresp(pcb, UPAP_AUTHACK, id, "", 0); /* return auth-ack */
return; return;
} }
if (pcb->upap.us_serverstate == UPAPSS_BADAUTH) { if (pcb->upap.us_serverstate == UPAPSS_BADAUTH) {
upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */ upap_sresp(pcb, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */
return; return;
} }
@ -404,16 +402,18 @@ static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len) {
UPAPDEBUG(("pap_rauth: rcvd short packet.")); UPAPDEBUG(("pap_rauth: rcvd short packet."));
return; return;
} }
/* FIXME: we need a way to check peer secret */
rpasswd = (char *) inp; rpasswd = (char *) inp;
/* /*
* Check the username and password given. * Check the username and password given.
*/ */
#if 0
retcode = check_passwd(pcb->upap.us_unit, ruser, ruserlen, rpasswd, retcode = check_passwd(pcb->upap.us_unit, ruser, ruserlen, rpasswd,
rpasswdlen, &msg); rpasswdlen, &msg);
BZERO(rpasswd, rpasswdlen); BZERO(rpasswd, rpasswdlen);
#if 0 /* UNUSED */
/* /*
* Check remote number authorization. A plugin may have filled in * Check remote number authorization. A plugin may have filled in
* the remote number or added an allowed number, and rather than * the remote number or added an allowed number, and rather than
@ -426,30 +426,30 @@ static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len) {
warn("calling number %q is not authorized", remote_number); warn("calling number %q is not authorized", remote_number);
} }
} }
#endif /* UNUSED */ #endif
msglen = strlen(msg); msglen = strlen(msg);
if (msglen > 255) if (msglen > 255)
msglen = 255; msglen = 255;
upap_sresp(u, retcode, id, msg, msglen); upap_sresp(pcb, retcode, id, msg, msglen);
/* Null terminate and clean remote name. */ /* Null terminate and clean remote name. */
slprintf(rhostname, sizeof(rhostname), "%.*v", ruserlen, ruser); ppp_slprintf(rhostname, sizeof(rhostname), "%.*v", ruserlen, ruser);
if (retcode == UPAP_AUTHACK) { if (retcode == UPAP_AUTHACK) {
pcb->upap.us_serverstate = UPAPSS_OPEN; pcb->upap.us_serverstate = UPAPSS_OPEN;
notice("PAP peer authentication succeeded for %q", rhostname); ppp_notice("PAP peer authentication succeeded for %q", rhostname);
auth_peer_success(pcb, PPP_PAP, 0, ruser, ruserlen); auth_peer_success(pcb, PPP_PAP, 0, ruser, ruserlen);
} else { } else {
pcb->upap.us_serverstate = UPAPSS_BADAUTH; pcb->upap.us_serverstate = UPAPSS_BADAUTH;
warn("PAP peer authentication failed for %q", rhostname); ppp_warn("PAP peer authentication failed for %q", rhostname);
auth_peer_fail(pcb, PPP_PAP); auth_peer_fail(pcb, PPP_PAP);
} }
if (pcb->upap.us_reqtimeout > 0) if (pcb->upap.us_reqtimeout > 0)
UNTIMEOUT(upap_reqtimeout, u); UNTIMEOUT(upap_reqtimeout, pcb);
} }
#endif /* UNUSED */ #endif /* PPP_SERVER */
/* /*
* upap_rauthack - Receive Authenticate-Ack. * upap_rauthack - Receive Authenticate-Ack.
@ -557,7 +557,7 @@ static void upap_sauthreq(ppp_pcb *pcb) {
pcb->upap.us_clientstate = UPAPCS_AUTHREQ; pcb->upap.us_clientstate = UPAPCS_AUTHREQ;
} }
#if 0 /* UNUSED */ #if PPP_SERVER
/* /*
* upap_sresp - Send a response (ack or nak). * upap_sresp - Send a response (ack or nak).
*/ */
@ -586,7 +586,7 @@ static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, char *msg, int msgl
ppp_write(pcb, p); ppp_write(pcb, p);
} }
#endif /* UNUSED */ #endif /* PPP_SERVER */
#if PRINTPKT_SUPPORT #if PRINTPKT_SUPPORT
/* /*