]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/chap-new.c
Merge branch 'chap-timeout' of https://github.com/nomis/ppp
[ppp.git] / pppd / chap-new.c
index ba906eaf3d8172f5230a378ce42b2c1220f884bb..0b1bb86e77c0d35a03b6e58629ace81748ec36e5 100644 (file)
@@ -55,20 +55,23 @@ int (*chap_verify_hook)(char *name, char *ourname, int id,
 /*
  * Option variables.
  */
 /*
  * 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_max_transmits = 10;
 int chap_rechallenge_time = 0;
+int chap_client_timeout_time = 60;
 
 /*
  * Command-line options.
  */
 static option_t chap_option_list[] = {
 
 /*
  * 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-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 }
 };
 
        { NULL }
 };
 
@@ -114,7 +117,8 @@ static struct chap_server_state {
 static void chap_init(int unit);
 static void chap_lowerup(int unit);
 static void chap_lowerdown(int unit);
 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);
 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);
@@ -171,7 +175,7 @@ chap_lowerup(int unit)
        cs->flags |= LOWERUP;
        ss->flags |= LOWERUP;
        if (ss->flags & AUTH_STARTED)
        cs->flags |= LOWERUP;
        ss->flags |= LOWERUP;
        if (ss->flags & AUTH_STARTED)
-               chap_timeout(ss);
+               chap_server_timeout(ss);
 }
 
 static void
 }
 
 static void
@@ -180,9 +184,11 @@ chap_lowerdown(int unit)
        struct chap_client_state *cs = &client;
        struct chap_server_state *ss = &server;
 
        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)
        cs->flags = 0;
        if (ss->flags & TIMEOUT_PENDING)
-               UNTIMEOUT(chap_timeout, ss);
+               UNTIMEOUT(chap_server_timeout, ss);
        ss->flags = 0;
 }
 
        ss->flags = 0;
 }
 
@@ -214,7 +220,7 @@ chap_auth_peer(int unit, char *our_name, int digest_code)
        ss->id = (unsigned char)(drand48() * 256);
        ss->flags |= AUTH_STARTED;
        if (ss->flags & LOWERUP)
        ss->id = (unsigned char)(drand48() * 256);
        ss->flags |= AUTH_STARTED;
        if (ss->flags & LOWERUP)
-               chap_timeout(ss);
+               chap_server_timeout(ss);
 }
 
 /*
 }
 
 /*
@@ -240,16 +246,17 @@ chap_auth_with_peer(int unit, char *our_name, int digest_code)
 
        cs->digest = dp;
        cs->name = our_name;
 
        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
  * 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;
 
 {
        struct chap_server_state *ss = arg;
 
@@ -268,7 +275,19 @@ chap_timeout(void *arg)
        output(0, ss->challenge, ss->challenge_pktlen);
        ++ss->challenge_xmits;
        ss->flags |= TIMEOUT_PENDING;
        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);
 }
 
 /*
 }
 
 /*
@@ -327,7 +346,7 @@ chap_handle_response(struct chap_server_state *ss, int id,
 
                if (ss->flags & TIMEOUT_PENDING) {
                        ss->flags &= ~TIMEOUT_PENDING;
 
                if (ss->flags & TIMEOUT_PENDING) {
                        ss->flags &= ~TIMEOUT_PENDING;
-                       UNTIMEOUT(chap_timeout, ss);
+                       UNTIMEOUT(chap_server_timeout, ss);
                }
 
                if (explicit_remote) {
                }
 
                if (explicit_remote) {
@@ -392,7 +411,7 @@ chap_handle_response(struct chap_server_state *ss, int id,
                                                  name, strlen(name));
                        if (chap_rechallenge_time) {
                                ss->flags |= TIMEOUT_PENDING;
                                                  name, strlen(name));
                        if (chap_rechallenge_time) {
                                ss->flags |= TIMEOUT_PENDING;
-                               TIMEOUT(chap_timeout, ss,
+                               TIMEOUT(chap_server_timeout, ss,
                                        chap_rechallenge_time);
                        }
                }
                                        chap_rechallenge_time);
                        }
                }
@@ -495,6 +514,9 @@ chap_handle_status(struct chap_client_state *cs, int code, int id,
                return;
        cs->flags |= AUTH_DONE;
 
                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 (code == CHAP_SUCCESS) {
                /* used for MS-CHAP v2 mutual auth, yuck */
                if (cs->digest->check_success != NULL) {
@@ -562,7 +584,7 @@ chap_protrej(int unit)
 
        if (ss->flags & TIMEOUT_PENDING) {
                ss->flags &= ~TIMEOUT_PENDING;
 
        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;
        }
        if (ss->flags & AUTH_STARTED) {
                ss->flags = 0;