/*
* Option variables.
*/
-int chap_timeout_time = 3;
+int chap_server_timeout_time = 3;
int chap_max_transmits = 10;
int chap_rechallenge_time = 0;
+int chap_client_timeout_time = 60;
/*
* Command-line options.
*/
static option_t chap_option_list[] = {
- { "chap-restart", o_int, &chap_timeout_time,
- "Set timeout for CHAP", OPT_PRIO },
+ { "chap-restart", o_int, &chap_server_timeout_time,
+ "Set timeout for CHAP (as server)", OPT_PRIO },
{ "chap-max-challenge", o_int, &chap_max_transmits,
"Set max #xmits for challenge", OPT_PRIO },
{ "chap-interval", o_int, &chap_rechallenge_time,
"Set interval for rechallenge", OPT_PRIO },
+ { "chap-timeout", o_int, &chap_client_timeout_time,
+ "Set timeout for CHAP (as client)", OPT_PRIO },
{ NULL }
};
static void chap_init(int unit);
static void chap_lowerup(int unit);
static void chap_lowerdown(int unit);
-static void chap_timeout(void *arg);
+static void chap_server_timeout(void *arg);
+static void chap_client_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,
unsigned char *pkt, int len);
cs->flags |= LOWERUP;
ss->flags |= LOWERUP;
if (ss->flags & AUTH_STARTED)
- chap_timeout(ss);
+ chap_server_timeout(ss);
}
static void
struct chap_client_state *cs = &client;
struct chap_server_state *ss = &server;
+ if (cs->flags & TIMEOUT_PENDING)
+ UNTIMEOUT(chap_client_timeout, cs);
cs->flags = 0;
if (ss->flags & TIMEOUT_PENDING)
- UNTIMEOUT(chap_timeout, ss);
+ UNTIMEOUT(chap_server_timeout, ss);
ss->flags = 0;
}
ss->id = (unsigned char)(drand48() * 256);
ss->flags |= AUTH_STARTED;
if (ss->flags & LOWERUP)
- chap_timeout(ss);
+ chap_server_timeout(ss);
}
/*
cs->digest = dp;
cs->name = our_name;
- cs->flags |= AUTH_STARTED;
+ cs->flags |= AUTH_STARTED | TIMEOUT_PENDING;
+ TIMEOUT(chap_client_timeout, cs, chap_client_timeout_time);
}
/*
- * chap_timeout - It's time to send another challenge to the peer.
+ * chap_server_timeout - It's time to send another challenge to the peer.
* This could be either a retransmission of a previous challenge,
* or a new challenge to start re-authentication.
*/
static void
-chap_timeout(void *arg)
+chap_server_timeout(void *arg)
{
struct chap_server_state *ss = arg;
output(0, ss->challenge, ss->challenge_pktlen);
++ss->challenge_xmits;
ss->flags |= TIMEOUT_PENDING;
- TIMEOUT(chap_timeout, arg, chap_timeout_time);
+ TIMEOUT(chap_server_timeout, arg, chap_server_timeout_time);
+}
+
+/* chap_client_timeout - Authentication with peer timed out. */
+static void
+chap_client_timeout(void *arg)
+{
+ struct chap_client_state *cs = arg;
+
+ cs->flags &= ~TIMEOUT_PENDING;
+ cs->flags |= AUTH_DONE | AUTH_FAILED;
+ error("CHAP authentication timed out");
+ auth_withpeer_fail(0, PPP_CHAP);
}
/*
if (ss->flags & TIMEOUT_PENDING) {
ss->flags &= ~TIMEOUT_PENDING;
- UNTIMEOUT(chap_timeout, ss);
+ UNTIMEOUT(chap_server_timeout, ss);
}
if (explicit_remote) {
name, strlen(name));
if (chap_rechallenge_time) {
ss->flags |= TIMEOUT_PENDING;
- TIMEOUT(chap_timeout, ss,
+ TIMEOUT(chap_server_timeout, ss,
chap_rechallenge_time);
}
}
return;
cs->flags |= AUTH_DONE;
+ UNTIMEOUT(chap_client_timeout, cs);
+ cs->flags &= ~TIMEOUT_PENDING;
+
if (code == CHAP_SUCCESS) {
/* used for MS-CHAP v2 mutual auth, yuck */
if (cs->digest->check_success != NULL) {
if (ss->flags & TIMEOUT_PENDING) {
ss->flags &= ~TIMEOUT_PENDING;
- UNTIMEOUT(chap_timeout, ss);
+ UNTIMEOUT(chap_server_timeout, ss);
}
if (ss->flags & AUTH_STARTED) {
ss->flags = 0;