PPP server support is now optional (disabled by default, not working until PPP have a "listen" support)

This commit is contained in:
Sylvain Rochet 2012-06-07 22:22:57 +02:00
parent 2fe778507a
commit e5355cc45f
9 changed files with 90 additions and 2 deletions

View File

@ -761,7 +761,9 @@ link_established(unit)
#if 0 /* UNUSED */
lcp_options *wo = &lcp_wantoptions[unit];
#endif /* UNUSED */
#if PPP_SERVER
lcp_options *go = &lcp_gotoptions[unit];
#endif /* #if PPP_SERVER */
lcp_options *ho = &lcp_hisoptions[unit];
int i;
struct protent *protp;
@ -817,6 +819,7 @@ link_established(unit)
new_phase(PHASE_AUTHENTICATE);
auth = 0;
#if PPP_SERVER
#if EAP_SUPPORT
if (go->neg_eap) {
eap_authpeer(unit, our_name);
@ -836,6 +839,7 @@ link_established(unit)
} else
#endif /* PAP_SUPPORT */
{}
#endif /* PPP_SERVER */
#if EAP_SUPPORT
if (ho->neg_eap) {
@ -1022,6 +1026,7 @@ continue_networks(unit)
lcp_close(0, "No network protocols running");
}
#if PPP_SERVER
/*
* The peer has failed to authenticate himself using `protocol'.
*/
@ -1103,6 +1108,7 @@ auth_peer_success(unit, protocol, prot_flavor, name, namelen)
if ((auth_pending[unit] &= ~bit) == 0)
network_phase(unit);
}
#endif /* PPP_SERVER */
/*
* We have failed to authenticate ourselves to the peer using `protocol'.

View File

@ -47,6 +47,7 @@
#define MD5_MIN_CHALLENGE 16
#define MD5_MAX_CHALLENGE 24
#if PPP_SERVER
static void
chap_md5_generate_challenge(unsigned char *cp)
{
@ -88,6 +89,7 @@ chap_md5_verify_response(int id, char *name,
slprintf(message, message_space, "Access denied");
return 0;
}
#endif /* PPP_SERVER */
static void
chap_md5_make_response(unsigned char *response, int id, char *our_name,
@ -108,8 +110,10 @@ chap_md5_make_response(unsigned char *response, int id, char *our_name,
static struct chap_digest_type md5_digest = {
CHAP_MD5, /* code */
#if PPP_SERVER
chap_md5_generate_challenge,
chap_md5_verify_response,
#endif /* PPP_SERVER */
chap_md5_make_response,
NULL, /* check_success */
NULL, /* handle_failure */

View File

@ -85,6 +85,7 @@ static option_t chap_option_list[] = {
/*
* Internal state.
*/
/* FIXME: one client struct per ppp session */
static struct chap_client_state {
int flags;
char *name;
@ -99,6 +100,8 @@ static struct chap_client_state {
#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 PPP_SERVER
/* FIXME: one server struct per ppp session */
static struct chap_server_state {
int flags;
int id;
@ -109,6 +112,7 @@ static struct chap_server_state {
unsigned char challenge[CHAL_MAX_PKTLEN];
char message[256];
} server;
#endif /* PPP_SERVER */
/* Values for flags in chap_client_state and chap_server_state */
#define LOWERUP 1
@ -124,6 +128,7 @@ static struct chap_server_state {
static void chap_init(int unit);
static void chap_lowerup(int unit);
static void chap_lowerdown(int unit);
#if PPP_SERVER
static void chap_timeout(void *arg);
static void chap_generate_challenge(struct chap_server_state *ss);
static void chap_handle_response(struct chap_server_state *ss, int code,
@ -132,6 +137,7 @@ static int chap_verify_response(char *name, char *ourname, int id,
struct chap_digest_type *digest,
unsigned char *challenge, unsigned char *response,
char *message, int message_space);
#endif /* PPP_SERVER */
static void chap_respond(struct chap_client_state *cs, int id,
unsigned char *pkt, int len);
static void chap_handle_status(struct chap_client_state *cs, int code, int id,
@ -153,7 +159,9 @@ static void
chap_init(int unit)
{
memset(&client, 0, sizeof(client));
#if PPP_SERVER
memset(&server, 0, sizeof(server));
#endif /* PPP_SERVER */
chap_md5_init();
#if MSCHAP_SUPPORT
@ -178,26 +186,35 @@ static void
chap_lowerup(int unit)
{
struct chap_client_state *cs = &client;
#if PPP_SERVER
struct chap_server_state *ss = &server;
#endif /* PPP_SERVER */
cs->flags |= LOWERUP;
#if PPP_SERVER
ss->flags |= LOWERUP;
if (ss->flags & AUTH_STARTED)
chap_timeout(ss);
#endif /* PPP_SERVER */
}
static void
chap_lowerdown(int unit)
{
struct chap_client_state *cs = &client;
#if PPP_SERVER
struct chap_server_state *ss = &server;
#endif /* PPP_SERVER */
cs->flags = 0;
#if PPP_SERVER
if (ss->flags & TIMEOUT_PENDING)
UNTIMEOUT(chap_timeout, ss);
ss->flags = 0;
#endif /* PPP_SERVER */
}
#if PPP_SERVER
/*
* chap_auth_peer - Start authenticating the peer.
* If the lower layer is already up, we start sending challenges,
@ -228,6 +245,7 @@ chap_auth_peer(int unit, char *our_name, int digest_code)
if (ss->flags & LOWERUP)
chap_timeout(ss);
}
#endif /* PPP_SERVER */
/*
* chap_auth_with_peer - Prepare to authenticate ourselves to the peer.
@ -255,6 +273,7 @@ chap_auth_with_peer(int unit, char *our_name, int digest_code)
cs->flags |= AUTH_STARTED;
}
# if PPP_SERVER
/*
* chap_timeout - It's time to send another challenge to the peer.
* This could be either a retransmission of a previous challenge,
@ -446,6 +465,7 @@ chap_verify_response(char *name, char *ourname, int id,
return ok;
}
#endif /* PPP_SERVER */
/*
* chap_respond - Generate and send a response to a challenge.
@ -546,7 +566,10 @@ static void
chap_input(int unit, unsigned char *pkt, int pktlen)
{
struct chap_client_state *cs = &client;
#if PPP_SERVER
struct chap_server_state *ss = &server;
#endif /* PPP_SERVER */
unsigned char code, id;
int len;
@ -563,9 +586,11 @@ chap_input(int unit, unsigned char *pkt, int pktlen)
case CHAP_CHALLENGE:
chap_respond(cs, id, pkt, len);
break;
#if PPP_SERVER
case CHAP_RESPONSE:
chap_handle_response(ss, id, pkt, len);
break;
#endif /* PPP_SERVER */
case CHAP_FAILURE:
case CHAP_SUCCESS:
chap_handle_status(cs, code, id, pkt, len);
@ -577,6 +602,7 @@ static void
chap_protrej(int unit)
{
struct chap_client_state *cs = &client;
#if PPP_SERVER
struct chap_server_state *ss = &server;
if (ss->flags & TIMEOUT_PENDING) {
@ -587,6 +613,7 @@ chap_protrej(int unit)
ss->flags = 0;
auth_peer_fail(0, PPP_CHAP);
}
#endif /* PPP_SERVER */
if ((cs->flags & (AUTH_STARTED|AUTH_DONE)) == AUTH_STARTED) {
cs->flags &= ~AUTH_STARTED;
error("CHAP authentication failed due to protocol-reject");

View File

@ -118,6 +118,7 @@ extern int chap_mdtype_all;
struct chap_digest_type {
int code;
#if PPP_SERVER
/*
* Note: challenge and response arguments below are formatted as
* a length byte followed by the actual challenge/response data.
@ -127,6 +128,7 @@ struct chap_digest_type {
unsigned char *secret, int secret_len,
unsigned char *challenge, unsigned char *response,
char *message, int message_space);
#endif /* PPP_SERVER */
void (*make_response)(unsigned char *response, int id, char *our_name,
unsigned char *challenge, char *secret, int secret_len,
unsigned char *priv);
@ -147,8 +149,10 @@ extern int (*chap_verify_hook)(char *name, char *ourname, int id,
/* Called by digest code to register a digest type */
extern void chap_register_digest(struct chap_digest_type *);
#if PPP_SERVER
/* Called by authentication code to start authenticating the peer. */
extern void chap_auth_peer(int unit, char *our_name, int digest_code);
#endif /* PPP_SERVER */
/* Called by auth. code to start authenticating us to the peer. */
extern void chap_auth_with_peer(int unit, char *our_name, int digest_code);

View File

@ -159,6 +159,7 @@ static option_t chapms_option_list[] = {
};
#endif /* PPP_OPTIONS */
#if PPP_SERVER
/*
* chapms_generate_challenge - generate a challenge for MS-CHAP.
* For MS-CHAP the challenge length is fixed at 8 bytes.
@ -313,6 +314,7 @@ chapms2_verify_response(int id, char *name,
challenge_len, challenge, "Access denied");
return 0;
}
#endif /* PPP_SERVER */
static void
chapms_make_response(unsigned char *response, int id, char *our_name,
@ -919,8 +921,10 @@ set_mppe_enc_types(int policy, int types)
static struct chap_digest_type chapms_digest = {
CHAP_MICROSOFT, /* code */
#if PPP_SERVER
chapms_generate_challenge,
chapms_verify_response,
#endif /* PPP_SERVER */
chapms_make_response,
NULL, /* check_success */
chapms_handle_failure,
@ -928,8 +932,10 @@ static struct chap_digest_type chapms_digest = {
static struct chap_digest_type chapms2_digest = {
CHAP_MICROSOFT_V2, /* code */
#if PPP_SERVER
chapms2_generate_challenge,
chapms2_verify_response,
#endif /* PPP_SERVER */
chapms2_make_response,
chapms2_check_success,
chapms_handle_failure,

View File

@ -175,8 +175,10 @@ static const u_char wkmodulus[] = {
};
#endif
#if PPP_SERVER
/* Local forward declarations. */
static void eap_server_timeout (void *arg);
#endif /* PPP_SERVER */
/*
* Convert EAP state code to printable string for debug.
@ -202,9 +204,11 @@ int unit;
BZERO(esp, sizeof (*esp));
esp->es_unit = unit;
#if PPP_SERVER
esp->es_server.ea_timeout = EAP_DEFTIMEOUT;
esp->es_server.ea_maxrequests = EAP_DEFTRANSMITS;
esp->es_server.ea_id = (u_char)(drand48() * 0x100);
#endif /* PPP_SERVER */
esp->es_client.ea_timeout = EAP_DEFREQTIME;
esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
}
@ -255,6 +259,7 @@ char *localname;
esp->es_client.ea_timeout);
}
#if PPP_SERVER
/*
* Format a standard EAP Failure message and send it to the peer.
* (Server operation)
@ -304,6 +309,7 @@ eap_state *esp;
auth_peer_success(esp->es_unit, PPP_EAP, 0,
esp->es_server.ea_peer, esp->es_server.ea_peerlen);
}
#endif /* PPP_SERVER */
#ifdef USE_SRP
/*
@ -414,6 +420,7 @@ u_char *outp;
}
#endif /* USE_SRP */
#if PPP_SERVER
/*
* Assume that current waiting server state is complete and figure
* next state to use based on available authentication data. 'status'
@ -954,6 +961,7 @@ void *arg;
esp->es_server.ea_id++;
eap_send_request(esp);
}
#endif /* PPP_SERVER */
/*
* eap_lowerup - The lower layer is now up.
@ -970,16 +978,20 @@ int unit;
eap_state *esp = &eap_states[unit];
/* Discard any (possibly authenticated) peer name. */
#if PPP_SERVER
if (esp->es_server.ea_peer != NULL &&
esp->es_server.ea_peer != remote_name)
free(esp->es_server.ea_peer);
esp->es_server.ea_peer = NULL;
#endif /* PPP_SERVER */
if (esp->es_client.ea_peer != NULL)
free(esp->es_client.ea_peer);
esp->es_client.ea_peer = NULL;
esp->es_client.ea_state = eapClosed;
#if PPP_SERVER
esp->es_server.ea_state = eapClosed;
#endif /* PPP_SERVER */
}
/*
@ -996,6 +1008,7 @@ int unit;
if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) {
UNTIMEOUT(eap_client_timeout, (void *)esp);
}
#if PPP_SERVER
if (eap_server_active(esp)) {
if (esp->es_server.ea_timeout > 0) {
UNTIMEOUT(eap_server_timeout, (void *)esp);
@ -1014,6 +1027,7 @@ int unit;
esp->es_client.ea_state = esp->es_server.ea_state = eapInitial;
esp->es_client.ea_requests = esp->es_server.ea_requests = 0;
#endif /* PPP_SERVER */
}
/*
@ -1032,10 +1046,12 @@ int unit;
error("EAP authentication failed due to Protocol-Reject");
auth_withpeer_fail(unit, PPP_EAP);
}
#if PPP_SERVER
if (eap_server_active(esp)) {
error("EAP authentication of peer failed on Protocol-Reject");
auth_peer_fail(unit, PPP_EAP);
}
#endif /* PPP_SERVER */
eap_lowerdown(unit);
}
@ -1717,6 +1733,8 @@ client_failure:
#endif /* USE_SRP */
}
#if PPP_SERVER
/* FIXME: remove malloc() and free() */
/*
* eap_response - Receive EAP Response message (server mode).
*/
@ -2011,6 +2029,7 @@ int len;
eap_send_request(esp);
}
}
#endif /* PPP_SERVER */
/*
* eap_success - Receive EAP Success message (client mode).
@ -2110,9 +2129,11 @@ int inlen;
eap_request(esp, inp, id, len);
break;
#if PPP_SERVER
case EAP_RESPONSE:
eap_response(esp, inp, id, len);
break;
#endif /* PPP_SERVER */
case EAP_SUCCESS:
eap_success(esp, inp, id, len);

View File

@ -101,9 +101,11 @@ enum eap_state_code {
"SRP1", "SRP2", "SRP3", "MD5Chall", "Open", "SRP4", "BadAuth"
#define eap_client_active(esp) ((esp)->es_client.ea_state == eapListen)
#if PPP_SERVER
#define eap_server_active(esp) \
((esp)->es_server.ea_state >= eapIdentify && \
(esp)->es_server.ea_state <= eapMD5Chall)
#endif /* PPP_SERVER */
struct eap_auth {
char *ea_name; /* Our name */
@ -128,7 +130,9 @@ struct eap_auth {
typedef struct eap_state {
int es_unit; /* Interface unit number */
struct eap_auth es_client; /* Client (authenticatee) data */
#if PPP_SERVER
struct eap_auth es_server; /* Server (authenticator) data */
#endif /* PPP_SERVER */
int es_savedtime; /* Saved timeout */
int es_rechallenge; /* EAP rechallenge interval */
int es_lwrechallenge; /* SRP lightweight rechallenge inter */

View File

@ -125,7 +125,9 @@ struct protent pap_protent = {
upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */
static void upap_timeout (void *);
#if PPP_SERVER
static void upap_reqtimeout (void *);
#endif /* PPP_SERVER */
#if 0 /* UNUSED */
static void upap_rauthreq (upap_state *, u_char *, int, int);
#endif /* UNUSED */
@ -152,7 +154,9 @@ upap_init(unit)
u->us_passwd = NULL;
u->us_passwdlen = 0;
u->us_clientstate = UPAPCS_INITIAL;
#if PPP_SERVER
u->us_serverstate = UPAPSS_INITIAL;
#endif /* PPP_SERVER */
u->us_id = 0;
u->us_timeouttime = UPAP_DEFTIMEOUT;
u->us_maxtransmits = 10;
@ -189,7 +193,7 @@ upap_authwithpeer(unit, user, password)
upap_sauthreq(u); /* Start protocol */
}
#if PPP_SERVER
/*
* upap_authpeer - Authenticate our peer (start server).
*
@ -212,7 +216,7 @@ upap_authpeer(unit)
if (u->us_reqtimeout > 0)
TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
}
#endif /* PPP_SERVER */
/*
* upap_timeout - Retransmission timer for sending auth-reqs expired.
@ -238,6 +242,7 @@ upap_timeout(arg)
}
#if PPP_SERVER
/*
* upap_reqtimeout - Give up waiting for the peer to send an auth-req.
*/
@ -253,6 +258,7 @@ upap_reqtimeout(arg)
auth_peer_fail(u->us_unit, PPP_PAP);
u->us_serverstate = UPAPSS_BADAUTH;
}
#endif /* PPP_SERVER */
/*
@ -272,6 +278,7 @@ upap_lowerup(unit)
upap_sauthreq(u); /* send an auth-request */
}
#if PPP_SERVER
if (u->us_serverstate == UPAPSS_INITIAL)
u->us_serverstate = UPAPSS_CLOSED;
else if (u->us_serverstate == UPAPSS_PENDING) {
@ -279,6 +286,7 @@ upap_lowerup(unit)
if (u->us_reqtimeout > 0)
TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
}
#endif /* PPP_SERVER */
}
@ -295,11 +303,15 @@ upap_lowerdown(unit)
if (u->us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */
UNTIMEOUT(upap_timeout, u); /* Cancel timeout */
#if PPP_SERVER
if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0)
UNTIMEOUT(upap_reqtimeout, u);
#endif /* PPP_SERVER */
u->us_clientstate = UPAPCS_INITIAL;
#if PPP_SERVER
u->us_serverstate = UPAPSS_INITIAL;
#endif /* PPP_SERVER */
}
@ -318,10 +330,12 @@ upap_protrej(unit)
error("PAP authentication failed due to protocol-reject");
auth_withpeer_fail(unit, PPP_PAP);
}
#if PPP_SERVER
if (u->us_serverstate == UPAPSS_LISTEN) {
error("PAP authentication of peer failed (protocol-reject)");
auth_peer_fail(unit, PPP_PAP);
}
#endif /* PPP_SERVER */
upap_lowerdown(unit);
}

View File

@ -69,7 +69,9 @@ typedef struct upap_state {
char *us_passwd; /* Password */
int us_passwdlen; /* Password length */
int us_clientstate; /* Client state */
#if PPP_SERVER
int us_serverstate; /* Server state */
#endif /* PPP_SERVER */
u_char us_id; /* Current id */
int us_timeouttime; /* Timeout (seconds) for auth-req retrans. */
int us_transmits; /* Number of auth-reqs sent */