]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/auth.c
First large MPPE patch from Frank Cusack.
[ppp.git] / pppd / auth.c
index a5fc1bd6bc32dfaaea6af37ada412400df08c572..67f12782584c279b21fc705f05e3fbac0393db50 100644 (file)
@@ -32,7 +32,7 @@
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define RCSID  "$Id: auth.c,v 1.73 2002/01/22 16:02:58 dfs Exp $"
+#define RCSID  "$Id: auth.c,v 1.76 2002/04/02 13:54:59 dfs Exp $"
 
 #include <stdio.h>
 #include <stddef.h>
@@ -91,6 +91,9 @@ char peer_authname[MAXNAMELEN];
 /* Records which authentication operations haven't completed yet. */
 static int auth_pending[NUM_PPP];
 
+/* Records which authentication operations have been completed. */
+int auth_done[NUM_PPP];
+
 /* Set if we have successfully called plogin() */
 static int logged_in;
 
@@ -169,6 +172,13 @@ bool uselogin = 0;         /* Use /etc/passwd for checking PAP */
 bool cryptpap = 0;             /* Passwords in pap-secrets are encrypted */
 bool refuse_pap = 0;           /* Don't wanna auth. ourselves with PAP */
 bool refuse_chap = 0;          /* Don't wanna auth. ourselves with CHAP */
+#ifdef CHAPMS
+bool refuse_mschap = 0;                /* Don't wanna auth. ourselves with MS-CHAP */
+bool refuse_mschap_v2 = 0;     /* Don't wanna auth. ourselves with MS-CHAPv2 */
+#else
+bool refuse_mschap = 1;                /* Don't wanna auth. ourselves with MS-CHAP */
+bool refuse_mschap_v2 = 1;     /* Don't wanna auth. ourselves with MS-CHAPv2 */
+#endif
 bool usehostname = 0;          /* Use hostname for our_name */
 bool auth_required = 0;                /* Always require authentication from peer */
 bool allow_any_ip = 0;         /* Allow peer to use any IP address */
@@ -177,12 +187,6 @@ char remote_name[MAXNAMELEN];      /* Peer's name for authentication */
 
 static char *uafname;          /* name of most recent +ua file */
 
-/* Bits in auth_pending[] */
-#define PAP_WITHPEER   1
-#define PAP_PEER       2
-#define CHAP_WITHPEER  4
-#define CHAP_PEER      8
-
 extern char *crypt __P((const char *, const char *));
 
 /* Prototypes for procedures local to this file. */
@@ -218,30 +222,68 @@ option_t auth_options[] = {
     { "auth", o_bool, &auth_required,
       "Require authentication from peer", OPT_PRIO | 1 },
     { "noauth", o_bool, &auth_required,
-      "Don't require peer to authenticate", OPT_PRIOSUB | OPT_PRIV,
+      "Don't require peer to authenticate", OPT_PRIOSUB | OPT_PRIV | OPT_A2COPY,
       &allow_any_ip },
     { "require-pap", o_bool, &lcp_wantoptions[0].neg_upap,
       "Require PAP authentication from peer",
-      OPT_PRIOSUB | 1, &auth_required },
+      OPT_PRIOSUB | OPT_A2COPY | 1, &auth_required },
     { "+pap", o_bool, &lcp_wantoptions[0].neg_upap,
       "Require PAP authentication from peer",
-      OPT_ALIAS | OPT_PRIOSUB | 1, &auth_required },
+      OPT_ALIAS | OPT_PRIOSUB | OPT_A2COPY | 1, &auth_required },
     { "require-chap", o_bool, &lcp_wantoptions[0].neg_chap,
       "Require CHAP authentication from peer",
-      OPT_PRIOSUB | 1, &auth_required },
+      OPT_PRIOSUB | OPT_A2COPY | OPT_A3OR | MDTYPE_MD5,
+      &auth_required, 0, 0, NULL, 0, 0, &lcp_wantoptions[0].chap_mdtype },
     { "+chap", o_bool, &lcp_wantoptions[0].neg_chap,
       "Require CHAP authentication from peer",
-      OPT_ALIAS | OPT_PRIOSUB | 1, &auth_required },
+      OPT_ALIAS | OPT_PRIOSUB | OPT_A2COPY | OPT_A3OR | MDTYPE_MD5,
+      &auth_required, 0, 0, NULL, 0, 0, &lcp_wantoptions[0].chap_mdtype },
+#ifdef CHAPMS
+    { "require-mschap", o_bool, &lcp_wantoptions[0].neg_chap,
+      "Require MS-CHAP authentication from peer",
+      OPT_PRIOSUB | OPT_A2COPY | OPT_A3OR | MDTYPE_MICROSOFT,
+      &auth_required, 0, 0, NULL, 0, 0, &lcp_wantoptions[0].chap_mdtype },
+    { "+mschap", o_bool, &lcp_wantoptions[0].neg_chap,
+      "Require MS-CHAP authentication from peer",
+      OPT_ALIAS | OPT_PRIOSUB | OPT_A2COPY | OPT_A3OR | MDTYPE_MICROSOFT,
+      &auth_required, 0, 0, NULL, 0, 0, &lcp_wantoptions[0].chap_mdtype },
+    { "require-mschap-v2", o_bool, &lcp_wantoptions[0].neg_chap,
+      "Require MS-CHAPv2 authentication from peer",
+      OPT_PRIOSUB | OPT_A2COPY | OPT_A3OR | MDTYPE_MICROSOFT_V2,
+      &auth_required, 0, 0, NULL, 0, 0, &lcp_wantoptions[0].chap_mdtype },
+    { "+mschap-v2", o_bool, &lcp_wantoptions[0].neg_chap,
+      "Require MS-CHAPv2 authentication from peer",
+      OPT_ALIAS | OPT_PRIOSUB | OPT_A2COPY | OPT_A3OR | MDTYPE_MICROSOFT_V2,
+      &auth_required, 0, 0, NULL, 0, 0, &lcp_wantoptions[0].chap_mdtype },
+#endif
 
     { "refuse-pap", o_bool, &refuse_pap,
       "Don't agree to auth to peer with PAP", 1 },
     { "-pap", o_bool, &refuse_pap,
       "Don't allow PAP authentication with peer", OPT_ALIAS | 1 },
-
     { "refuse-chap", o_bool, &refuse_chap,
-      "Don't agree to auth to peer with CHAP", 1 },
+      "Don't agree to auth to peer with CHAP", OPT_A2CLRB | MDTYPE_MD5,
+      &lcp_allowoptions[0].chap_mdtype },
     { "-chap", o_bool, &refuse_chap,
-      "Don't allow CHAP authentication with peer", OPT_ALIAS | 1 },
+      "Don't allow CHAP authentication with peer",
+      OPT_ALIAS | OPT_A2CLRB | MDTYPE_MD5,
+      &lcp_allowoptions[0].chap_mdtype },
+#ifdef CHAPMS
+    { "refuse-mschap", o_bool, &refuse_mschap,
+      "Don't agree to auth to peer with MS-CHAP",
+      OPT_A2CLRB | MDTYPE_MICROSOFT, &lcp_allowoptions[0].chap_mdtype },
+    { "-mschap", o_bool, &refuse_mschap,
+      "Don't allow MS-CHAP authentication with peer",
+      OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT,
+      &lcp_allowoptions[0].chap_mdtype },
+    { "refuse-mschap-v2", o_bool, &refuse_mschap_v2,
+      "Don't agree to auth to peer with MS-CHAPv2",
+      OPT_A2CLRB | MDTYPE_MICROSOFT_V2, &lcp_allowoptions[0].chap_mdtype },
+    { "-mschap-v2", o_bool, &refuse_mschap_v2,
+      "Don't allow MS-CHAPv2 authentication with peer",
+      OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT_V2,
+      &lcp_allowoptions[0].chap_mdtype },
+#endif
 
     { "name", o_string, our_name,
       "Set local name for authentication",
@@ -466,12 +508,12 @@ link_established(unit)
            && protp->lowerup != NULL)
            (*protp->lowerup)(unit);
 
-    if (auth_required && !(go->neg_chap || go->neg_upap)) {
+    if (auth_required && !(go->neg_upap || go->neg_chap)) {
        /*
         * We wanted the peer to authenticate itself, and it refused:
         * if we have some address(es) it can use without auth, fine,
         * otherwise treat it as though it authenticated with PAP using
-        * a username of "" and a password of "".  If that's not OK,
+        * a username of "" and a password of "".  If that's not OK,
         * boot it out.
         */
        if (noauth_addrs != NULL) {
@@ -488,14 +530,14 @@ link_established(unit)
     used_login = 0;
     auth = 0;
     if (go->neg_chap) {
-       ChapAuthPeer(unit, our_name, go->chap_mdtype);
+       ChapAuthPeer(unit, our_name, CHAP_DIGEST(go->chap_mdtype));
        auth |= CHAP_PEER;
     } else if (go->neg_upap) {
        upap_authpeer(unit);
        auth |= PAP_PEER;
     }
     if (ho->neg_chap) {
-       ChapAuthWithPeer(unit, user, ho->chap_mdtype);
+       ChapAuthWithPeer(unit, user, CHAP_DIGEST(ho->chap_mdtype));
        auth |= CHAP_WITHPEER;
     } else if (ho->neg_upap) {
        if (passwd[0] == 0) {
@@ -507,6 +549,7 @@ link_established(unit)
        auth |= PAP_WITHPEER;
     }
     auth_pending[unit] = auth;
+    auth_done[unit] = 0;
 
     if (!auth)
        network_phase(unit);
@@ -608,8 +651,8 @@ auth_peer_fail(unit, protocol)
  * The peer has been successfully authenticated using `protocol'.
  */
 void
-auth_peer_success(unit, protocol, name, namelen)
-    int unit, protocol;
+auth_peer_success(unit, protocol, prot_flavor, name, namelen)
+    int unit, protocol, prot_flavor;
     char *name;
     int namelen;
 {
@@ -618,6 +661,19 @@ auth_peer_success(unit, protocol, name, namelen)
     switch (protocol) {
     case PPP_CHAP:
        bit = CHAP_PEER;
+       switch (prot_flavor) {
+       case CHAP_DIGEST_MD5:
+           bit |= CHAP_MD5_PEER;
+           break;
+#ifdef CHAPMS
+       case CHAP_MICROSOFT:
+           bit |= CHAP_MS_PEER;
+           break;
+       case CHAP_MICROSOFT_V2:
+           bit |= CHAP_MS2_PEER;
+           break;
+#endif
+       }
        break;
     case PPP_PAP:
        bit = PAP_PEER;
@@ -636,6 +692,9 @@ auth_peer_success(unit, protocol, name, namelen)
     peer_authname[namelen] = 0;
     script_setenv("PEERNAME", peer_authname, 0);
 
+    /* Save the authentication method for later. */
+    auth_done[unit] |= bit;
+
     /*
      * If there is no more authentication still to be done,
      * proceed to the network (or callback) phase.
@@ -667,14 +726,27 @@ auth_withpeer_fail(unit, protocol)
  * We have successfully authenticated ourselves with the peer using `protocol'.
  */
 void
-auth_withpeer_success(unit, protocol)
-    int unit, protocol;
+auth_withpeer_success(unit, protocol, prot_flavor)
+    int unit, protocol, prot_flavor;
 {
     int bit;
 
     switch (protocol) {
     case PPP_CHAP:
        bit = CHAP_WITHPEER;
+       switch (prot_flavor) {
+       case CHAP_DIGEST_MD5:
+           bit |= CHAP_MD5_WITHPEER;
+           break;
+#ifdef CHAPMS
+       case CHAP_MICROSOFT:
+           bit |= CHAP_MS_WITHPEER;
+           break;
+       case CHAP_MICROSOFT_V2:
+           bit |= CHAP_MS2_WITHPEER;
+           break;
+#endif
+       }
        break;
     case PPP_PAP:
        if (passwd_from_file)
@@ -686,6 +758,9 @@ auth_withpeer_success(unit, protocol)
        bit = 0;
     }
 
+    /* Save the authentication method for later. */
+    auth_done[unit] |= bit;
+
     /*
      * If there is no more authentication still being done,
      * proceed to the network (or callback) phase.
@@ -834,11 +909,11 @@ auth_check_options()
     if (auth_required) {
        allow_any_ip = 0;
        if (!wo->neg_chap && !wo->neg_upap) {
-           wo->neg_chap = 1;
+           wo->neg_chap = 1; wo->chap_mdtype = MDTYPE_ALL;
            wo->neg_upap = 1;
        }
     } else {
-       wo->neg_chap = 0;
+       wo->neg_chap = 0; wo->chap_mdtype = MDTYPE_NONE;
        wo->neg_upap = 0;
     }
 
@@ -848,7 +923,7 @@ auth_check_options()
      */
     lacks_ip = 0;
     can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip));
-    if (!can_auth && wo->neg_chap) {
+    if (!can_auth && (wo->neg_chap)) {
        can_auth = have_chap_secret((explicit_remote? remote_name: NULL),
                                    our_name, 1, &lacks_ip);
     }
@@ -889,7 +964,7 @@ auth_reset(unit)
     lcp_options *ao = &lcp_allowoptions[0];
 
     ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL));
-    ao->neg_chap = !refuse_chap
+    ao->neg_chap = (!refuse_chap || !refuse_mschap || !refuse_mschap_v2)
        && (passwd[0] != 0
            || have_chap_secret(user, (explicit_remote? remote_name: NULL),
                                0, NULL));