ECP patches from Frank Cusack:
authorDavid F. Skoll <dfs@roaringpenguin.com>
Tue, 21 May 2002 17:26:49 +0000 (17:26 +0000)
committerDavid F. Skoll <dfs@roaringpenguin.com>
Tue, 21 May 2002 17:26:49 +0000 (17:26 +0000)
- If encryption is required, don't bring up IP/IPv6/IPX until the
  encryption negotiation has completed.
- Shut down LCP if the peer sends an LCP ConfRej instead of CCP ConfRej
  to our MPPE offer.  This fixes a bug where the server could not enforce
  use of encryption in some cases.
- Don't send the M=<message> part of an MS-CHAPv2 success packet to peers
  that don't know how to deal with it.  This allows pre-win2k systems to
  authenticate.
- Don't shut down lcp if MPPE was present in peer's CCP offer along with
  other options.  This allows pre-win2k systems to do MPPE (they offer
  Stac LZS with MPPE).
- Add the beginnings of ecp.c.
- Other minor changes.

23 files changed:
README.MPPE
README.MSCHAP81
include/linux/ppp_defs.h
include/net/ppp_defs.h
linux/mppe/ppp_mppe_compress.c
pppd/Makefile.NeXT
pppd/Makefile.aix4
pppd/Makefile.bsd
pppd/Makefile.linux
pppd/Makefile.netbsd-1.2
pppd/Makefile.osf
pppd/Makefile.sol2
pppd/Makefile.sunos4
pppd/Makefile.svr4
pppd/Makefile.ultrix
pppd/auth.c
pppd/cbcp.c
pppd/ccp.c
pppd/chap.c
pppd/chap.h
pppd/main.c
pppd/pppd.8
pppd/pppd.h

index 7091d0344bd1c11e6c86e13028ee9185b737cdb8..cdada342f26aedff9ef5a51ead2ae5861b7e3829 100644 (file)
@@ -58,14 +58,15 @@ RADIUS support for MPPE is from Ralf Hofmann, <ralf.hofmann@elvido.net>.
 
 BUILDING THE PPPD
 
-The userland component of PPPD has no additional requirements above those
-for MS-CHAP and MS-CHAPv2.  The kernel, however, requires SHA-1 and ARCFOUR.
-Public domain implementations of these are provided.  Until such time as
-MPPE support ships with kernels, you can use the Linux-2.2 implementation
-that comes with PPPD.  Run the linux/mppe/mppeinstall.sh script, then
-rebuild your kernel.  The ppp_mppe.o module is added, and the ppp.o module
-is modified (unfortunately).  You'll need the new ppp.o since it does the
-right thing for the 4 extra bytes problem discussed above.
+The userland component of PPPD has no additional requirements above
+those for MS-CHAP and MS-CHAPv2.  The kernel, however, requires SHA-1
+and ARCFOUR.  Public domain implementations of these are provided.  Until
+such time as MPPE support ships with kernels, you can use the Linux-2.2
+implementation that comes with PPPD.  Run the linux/mppe/mppeinstall.sh
+script, then rebuild your kernel.  The ppp_mppe.o module is added, and the
+ppp.o module (2.2) or ppp_generic.o (2.4) is modified (unfortunately).
+You'll need the new ppp.o/ppp_generic.o since it does the right thing
+for the 4 extra bytes problem discussed above.
 
 
 CONFIGURATION
index c8e83f3966987afa0619386484e9295e301c76f6..91199f368bd079a491f755ed2304eba56fe5b5a7 100644 (file)
@@ -55,7 +55,7 @@ RFC 2759:
 
 You'll see these in your pppd log as a line similar to:
 
-   Remote message: No dialin permission
+   Remote message: E=649 No dialin permission
 
 Previously, pppd would log this as:
 
index e390c569bdf131359817aa0caf73ae78dc6f948d..489f84ab48b640c167fb896f08946e3eefe73990 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: ppp_defs.h,v 1.9 2000/03/27 06:03:36 paulus Exp $  */
+/*     $Id: ppp_defs.h,v 1.10 2002/05/21 17:26:48 dfs Exp $    */
 
 /*
  * ppp_defs.h - PPP definitions.
@@ -28,7 +28,7 @@
  */
 
 /*
- *  ==FILEVERSION 20000114==
+ *  ==FILEVERSION 20020521==
  *
  *  NOTE TO MAINTAINERS:
  *     If you modify this file at all, please set the above date.
@@ -80,6 +80,8 @@
 #define PPP_IPV6CP     0x8057  /* IPv6 Control Protocol */
 #define PPP_CCPFRAG    0x80fb  /* CCP at link level (below MP bundle) */
 #define PPP_CCP                0x80fd  /* Compression Control Protocol */
+#define PPP_ECPFRAG    0x8055  /* ECP at link level (below MP bundle) */
+#define PPP_ECP                0x8053  /* Encryption Control Protocol */
 #define PPP_LCP                0xc021  /* Link Control Protocol */
 #define PPP_PAP                0xc023  /* Password Authentication Protocol */
 #define PPP_LQR                0xc025  /* Link Quality Report protocol */
index 4152b069a7061c70af2c7c8ae16b2d9908a776c1..bda882ea1a285d09a8ebc5b23d12ed18b0a59e7c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: ppp_defs.h,v 1.14 1999/08/13 01:55:40 paulus Exp $ */
+/*     $Id: ppp_defs.h,v 1.15 2002/05/21 17:26:48 dfs Exp $    */
 
 /*
  * ppp_defs.h - PPP definitions.
@@ -79,6 +79,7 @@
 #define PPP_IPXCP      0x802b  /* IPX Control Protocol */
 #define PPP_IPV6CP     0x8057  /* IPv6 Control Protocol */
 #define PPP_CCP                0x80fd  /* Compression Control Protocol */
+#define PPP_ECP                0x8053  /* Encryption Control Protocol */
 #define PPP_LCP                0xc021  /* Link Control Protocol */
 #define PPP_PAP                0xc023  /* Password Authentication Protocol */
 #define PPP_LQR                0xc025  /* Link Quality Report protocol */
index efdb5d15e95af072a6f8b8a1a571760c8fdd2cb1..0a757686de4ce1c83c23b9f78c8f8154b5ad4a3d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  ==FILEVERSION 20020320==
+ *  ==FILEVERSION 20020521==
  *
  * ppp_mppe_compress.c - interface MPPE to the PPP code.
  * This version is for use with Linux kernel 2.2.19+ and 2.4.x.
@@ -62,13 +62,8 @@ typedef struct ppp_mppe_state {
 #define MPPE_CCOUNT(p) ((((p)[4] & 0x0f) << 8) + (p)[5])
 #define MPPE_CCOUNT_SPACE 0x1000       /* The size of the ccount space */
 
-/*
- * MPPE overhead/packet.
- * Note that we use this differently than other compressors.
- */
 #define MPPE_OVHD      2               /* MPPE overhead/packet */
-/* Max bogon factor we will tolerate */
-#define SANITY_MAX     1600
+#define SANITY_MAX     1600            /* Max bogon factor we will tolerate */
 
 static void    GetNewKeyFromSHA __P((unsigned char *StartKey,
                                      unsigned char *SessionKey,
@@ -236,17 +231,17 @@ mppe_init(void *arg, unsigned char *options, int optlen, int unit, int debug,
 
     if (debug) {
        int i;
-       char mkey[sizeof(state->master_key) * 3 + 1];
-       char skey[sizeof(state->session_key) * 3 + 1];
+       char mkey[sizeof(state->master_key) * 2 + 1];
+       char skey[sizeof(state->session_key) * 2 + 1];
 
        printk(KERN_DEBUG "%s[%d]: initialized with %d-bit %s mode\n", debugstr,
               unit, (state->keylen == 16)? 128: 40,
               (state->stateful)? "stateful": "stateless");
 
        for (i = 0; i < sizeof(state->master_key); i++)
-           sprintf(mkey + i * 2, "%.2x ", state->master_key[i]);
+           sprintf(mkey + i * 2, "%.2x", state->master_key[i]);
        for (i = 0; i < sizeof(state->session_key); i++)
-           sprintf(skey + i * 2, "%.2x ", state->session_key[i]);
+           sprintf(skey + i * 2, "%.2x", state->session_key[i]);
        printk(KERN_DEBUG "%s[%d]: keys: master: %s initial session: %s\n",
               debugstr, unit, mkey, skey);
     }
@@ -544,6 +539,7 @@ mppe_incomp(void *arg, unsigned char *ibuf, int icnt)
 {
     ppp_mppe_state *state = (ppp_mppe_state *) arg;
 
+/* XXX */
     if (state->debug &&
        (PPP_PROTOCOL(ibuf) >= 0x0021 && PPP_PROTOCOL(ibuf) <= 0x00fa))
        printk(KERN_DEBUG "mppe_incomp[%d]: incompressible (unencrypted) data! "
index 11ecabd228c0a02d95d67e872ff8d8d26f5a6329..7b873e2dabd0177f4f3dde38538d4e64ebef2f2d 100644 (file)
@@ -2,7 +2,7 @@
 # pppd makefile for NeXT
 #
 # $Orignial: Makefile.ultrix,v 1.4 1994/09/01 00:40:40 paulus Exp $
-# $Id: Makefile.NeXT,v 1.6 1999/04/12 06:24:44 paulus Exp $
+# $Id: Makefile.NeXT,v 1.7 2002/05/21 17:26:48 dfs Exp $
 #
 
 ARCHFLAGS = 
@@ -11,7 +11,7 @@ BINDIR = /usr/local/ppp/bin
 MANDIR = /usr/local/ppp/man
 
 OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
-       auth.o options.o demand.o utils.o sys-NeXT.o
+       ecp.o auth.o options.o demand.o utils.o sys-NeXT.o
 
 #
 # For HPPA and SPARC, define FIXSIGS to get around posix bugs in
index 05e503bee8fa92b7beaf49f0ce92ce5340e321a7..e173f6f76dba9321cc0908891cff35d5dc884427 100644 (file)
@@ -1,6 +1,6 @@
 #
 # pppd makefile for AIX 4.1
-# $Id: Makefile.aix4,v 1.4 1999/04/12 06:24:44 paulus Exp $
+# $Id: Makefile.aix4,v 1.5 2002/05/21 17:26:48 dfs Exp $
 #
 #ifndef BINDIR
 BINDIR = /usr/sbin
@@ -10,11 +10,11 @@ MANDIR = /usr/man
 #ENDIF
 
 PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \
-       auth.c options.c demand.c utils.c sys-aix4.c \
+       ecp.c auth.c options.c demand.c utils.c sys-aix4.c \
        gencode.c grammar.c scanner.c nametoaddr.c optimize.c
 
 PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
-       auth.o options.o demand.o utils.o sys-aix4.o \
+       ecp.o auth.o options.o demand.o utils.o sys-aix4.o \
        gencode.o grammar.o scanner.o nametoaddr.o optimize.o
 
 CC = xlc
index ea94db5c37d8a1af47fafda50d0f04042a70a21e..83a899f2149fda58190c5172e3eb38dbbe88440e 100644 (file)
@@ -1,4 +1,4 @@
-#      $Id: Makefile.bsd,v 1.15 1999/04/12 06:24:44 paulus Exp $
+#      $Id: Makefile.bsd,v 1.16 2002/05/21 17:26:48 dfs Exp $
 
 BINDIR?= /usr/sbin
 # -D_BITYPES is for FreeBSD, which doesn't define anything to
@@ -8,7 +8,7 @@ CFLAGS+= -g -I../include -DHAVE_PATHS_H -D_BITYPES
 
 PROG=  pppd
 SRCS=  main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \
-       demand.c auth.c options.c utils.c sys-bsd.c
+       ecp.c demand.c auth.c options.c utils.c sys-bsd.c
 MAN=   pppd.cat8
 MAN8=  pppd.8
 BINMODE=4555
index 57b6b08091a78e105ad039c3df3785dcaa9f0965..ada4ac89fafb561aa78a811daa7e9de0e1960056 100644 (file)
@@ -1,19 +1,19 @@
 #
 # pppd makefile for Linux
-# $Id: Makefile.linux,v 1.47 2002/04/02 13:54:59 dfs Exp $
+# $Id: Makefile.linux,v 1.48 2002/05/21 17:26:48 dfs Exp $
 #
 
 # Default installation locations
 BINDIR = /usr/sbin
 MANDIR = /usr/man
 
-PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \
+PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c ecp.c \
           ipxcp.c auth.c options.c sys-linux.c md4.c chap_ms.c cbcp.c \
           demand.c utils.c tty.c sha1.c
 HEADERS =  callout.h pathnames.h patchlevel.h chap.h md5.h chap_ms.h md4.h \
           ipxcp.h cbcp.h tdb.h sha1.h
 MANPAGES = pppd.8
-PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
+PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o ecp.o \
           auth.o options.o demand.o utils.o sys-linux.o ipxcp.o tty.o sha1.o
 
 all: pppd
index d10dfacc64b2fecdcbc2c741dd0ae35fab6dbcab..e50b7f54e2b722ec81c7f64a3cf96b91549a1eeb 100644 (file)
@@ -3,7 +3,7 @@
 PCAPDIR=${.CURDIR}/../../lib/libpcap
 
 PROG=  pppd
-SRCS=  auth.c cbcp.c ccp.c chap.c chap_ms.c demand.c fsm.c ipcp.c \
+SRCS=  auth.c cbcp.c ccp.c ecp.c chap.c chap_ms.c demand.c fsm.c ipcp.c \
        ipxcp.c lcp.c magic.c main.c options.c sys-bsd.c upap.c
 
 .PATH: ${PCAPDIR} ${.CURDIR}/../../sys/net
index 63f4eb9697077612fd920e3a8bbcbe9fc3b8ffe1..e680d2a58c8ada625f47c365081d8fe03bf5c6ca 100644 (file)
@@ -1,15 +1,15 @@
 #
 # pppd makefile for OSF/1 on DEC Alpha
-# $Id: Makefile.osf,v 1.11 2002/03/05 15:14:04 dfs Exp $
+# $Id: Makefile.osf,v 1.12 2002/05/21 17:26:48 dfs Exp $
 #
 
 BINDIR = /usr/local/etc
 MANDIR = /usr/local/man
 
-PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \
+PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c ecp.c \
        auth.c options.c demand.c utils.c sys-osf.c md4.c chap_ms.c sha1.c
 
-PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
+PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o ecp.o \
        auth.o options.o demand.o utils.o sys-osf.o md4.o chap_ms.o sha1.o
 
 CC = cc
index f1f08a8b18a8ddc257a77ee5ecffc30a5f95f9f3..2f32aaf74da825044df64c8d4584292d7dd95d5e 100644 (file)
@@ -1,6 +1,6 @@
 #
 # Makefile for pppd under Solaris 2.
-# $Id: Makefile.sol2,v 1.20 2001/03/08 05:01:03 paulus Exp $
+# $Id: Makefile.sol2,v 1.21 2002/05/21 17:26:48 dfs Exp $
 #
 
 include ../solaris/Makedefs
@@ -10,7 +10,7 @@ CFLAGS        =  -I../include -DSVR4 -DSOL2 $(COPTS)
 LIBS   = -lsocket -lnsl
 
 OBJS   =  main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o tty.o \
-       ccp.o auth.o options.o demand.o utils.o sys-solaris.o tdb.o
+       ccp.o ecp.o auth.o options.o demand.o utils.o sys-solaris.o tdb.o
 
 #
 # uncomment the following to enable plugins
index 714cb4d86c1efaea19ac19407230fcda3e6a836f..09276d28bc6ddd5a6f06774fd79bb35aa7d81571 100644 (file)
@@ -1,6 +1,6 @@
 #
 # Makefile for pppd under SunOS 4.
-# $Id: Makefile.sunos4,v 1.11 2001/03/08 05:01:03 paulus Exp $
+# $Id: Makefile.sunos4,v 1.12 2002/05/21 17:26:48 dfs Exp $
 #
 
 include ../sunos4/Makedefs
@@ -12,7 +12,7 @@ CFLAGS = $(COPTS) -I../include -DSUNOS4 -DGIDSET_TYPE=int \
 
 all: pppd
 
-OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
+OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o ecp.o \
        auth.o options.o demand.o utils.o sys-sunos4.o tty.o
 
 pppd:  $(OBJS)
index 842c6155fd79ae0ceac8b09bb1592f2d459432d5..ea7e7f890540b35ee459c482f59936b1cb6489ec 100644 (file)
@@ -1,6 +1,6 @@
 #
 # Makefile for pppd under Solaris 2.
-# $Id: Makefile.svr4,v 1.14 1999/04/12 06:24:44 paulus Exp $
+# $Id: Makefile.svr4,v 1.15 2002/05/21 17:26:48 dfs Exp $
 #
 
 include ../svr4/Makedefs
@@ -10,7 +10,7 @@ LIBS = -lsocket -lnsl -lc -L/usr/ucblib -lucb
 
 all: pppd
 
-OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
+OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o ecp.o \
        auth.o options.o demand.o utils.o sys-svr4.o
 
 pppd:  $(OBJS)
index cfd191ceeafbe88be693a5ba6a4164dbbfa9644a..8ffa6248ffa221e27d253acbd6872e65eeca19da 100644 (file)
@@ -1,15 +1,15 @@
 #
 # pppd makefile for Ultrix
-# $Id: Makefile.ultrix,v 1.11 1999/04/12 06:24:44 paulus Exp $
+# $Id: Makefile.ultrix,v 1.12 2002/05/21 17:26:49 dfs Exp $
 #
 
 BINDIR = /usr/local/etc
 MANDIR = /usr/local/man
 
-PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \
+PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c ecp.c \
        auth.c options.c demand.c utils.c sys-ultrix.c
 
-PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
+PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o ecp.o \
        auth.o options.o demand.o utils.o sys-ultrix.o
 
 # CC = gcc
index 67f12782584c279b21fc705f05e3fbac0393db50..727c69d4af8d92bf55924d95eef3edf1c3070b17 100644 (file)
@@ -32,7 +32,7 @@
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define RCSID  "$Id: auth.c,v 1.76 2002/04/02 13:54:59 dfs Exp $"
+#define RCSID  "$Id: auth.c,v 1.77 2002/05/21 17:26:49 dfs Exp $"
 
 #include <stdio.h>
 #include <stddef.h>
@@ -69,6 +69,8 @@
 #include "pppd.h"
 #include "fsm.h"
 #include "lcp.h"
+#include "ccp.h"
+#include "ecp.h"
 #include "ipcp.h"
 #include "upap.h"
 #include "chap.h"
@@ -595,42 +597,66 @@ network_phase(unit)
        free_wordlist(extra_options);
        extra_options = 0;
     }
-    start_networks();
+    start_networks(unit);
 }
 
 void
-start_networks()
+start_networks(unit)
+    int unit;
 {
+    static int started = 0;
     int i;
     struct protent *protp;
+    int ecp_required, mppe_required;
 
-    new_phase(PHASE_NETWORK);
+    if (!started) {
+       started = 1;
+       new_phase(PHASE_NETWORK);
 
 #ifdef HAVE_MULTILINK
-    if (multilink) {
-       if (mp_join_bundle()) {
-           if (updetach && !nodetach)
-               detach();
-           return;
+       if (multilink) {
+           if (mp_join_bundle()) {
+               if (updetach && !nodetach)
+                   detach();
+               return;
+           }
        }
-    }
 #endif /* HAVE_MULTILINK */
 
 #ifdef PPP_FILTER
-    if (!demand)
-       set_filters(&pass_filter, &active_filter);
+       if (!demand)
+           set_filters(&pass_filter, &active_filter);
 #endif
-    for (i = 0; (protp = protocols[i]) != NULL; ++i)
-        if (protp->protocol < 0xC000 && protp->enabled_flag
-           && protp->open != NULL) {
-           (*protp->open)(0);
-           if (protp->protocol != PPP_CCP)
+       /* Start CCP and ECP */
+       for (i = 0; (protp = protocols[i]) != NULL; ++i)
+           if ((protp->protocol == PPP_ECP || protp->protocol == PPP_CCP)
+               && protp->enabled_flag && protp->open != NULL)
+               (*protp->open)(0);
+    }
+
+    /*
+     * Bring up other network protocols after encryption has completed.
+     * OPENED here merely means that negotiation has completed.  It is
+     * up to the protocol to correctly terminate or disable LCP/NCP 
+     * based on the result of the negotiation.
+     */
+    ecp_required = ecp_gotoptions[unit].required;
+    mppe_required = ccp_gotoptions[unit].mppe;
+    if ((!ecp_required && !mppe_required)
+       || (ecp_required && ecp_fsm[unit].state == OPENED)
+       || (mppe_required && ccp_fsm[unit].state == OPENED)) {
+       for (i = 0; (protp = protocols[i]) != NULL; ++i)
+           if (protp->protocol < 0xC000
+               && protp->protocol != PPP_CCP && protp->protocol != PPP_ECP
+               && protp->enabled_flag && protp->open != NULL) {
+               (*protp->open)(0);
                ++num_np_open;
-       }
+           }
 
-    if (num_np_open == 0)
-       /* nothing to do */
-       lcp_close(0, "No network protocols running");
+       if (num_np_open == 0)
+           /* nothing to do */
+           lcp_close(0, "No network protocols running");
+    }
 }
 
 /*
index e48aa4637d72c3a2cafdcc6ec06f558ba71fe5f7..439d7edca1e522841e978004acaed5590fd42d52 100644 (file)
@@ -18,7 +18,7 @@
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define RCSID  "$Id: cbcp.c,v 1.11 2001/03/08 05:11:10 paulus Exp $"
+#define RCSID  "$Id: cbcp.c,v 1.12 2002/05/21 17:26:49 dfs Exp $"
 
 #include <stdio.h>
 #include <string.h>
@@ -383,7 +383,7 @@ cbcp_resp(us)
        PUTCHAR(len , bufp);
        PUTCHAR(0, bufp);
        cbcp_send(us, CBCP_RESP, buf, len);
-       start_networks();
+       start_networks(us->us_unit);
        return;
     }
 }
index fa8a5a0cb950f6993ebe51d008c98b556b1c5272..40bf77f7a7a7d89d14e92c4a20745521b3e0822b 100644 (file)
@@ -25,7 +25,7 @@
  * OR MODIFICATIONS.
  */
 
-#define RCSID  "$Id: ccp.c,v 1.34 2002/04/02 13:54:59 dfs Exp $"
+#define RCSID  "$Id: ccp.c,v 1.35 2002/05/21 17:26:49 dfs Exp $"
 
 #include <stdlib.h>
 #include <string.h>
@@ -36,7 +36,7 @@
 #include <net/ppp-comp.h>
 
 #ifdef MPPE
-#include "chap_ms.h"   /* mppe_xx_key */
+#include "chap_ms.h"   /* mppe_xxxx_key */
 #include "lcp.h"       /* lcp_close() */
 #endif
 
@@ -510,6 +510,12 @@ ccp_protrej(unit)
 {
     ccp_flags_set(unit, 0, 0);
     fsm_lowerdown(&ccp_fsm[unit]);
+
+#ifdef MPPE
+    if (ccp_gotoptions[unit].mppe)
+       lcp_close(unit, "MPPE required but peer negotiation failed");
+#endif
+
 }
 
 /*
@@ -542,10 +548,10 @@ ccp_resetci(f)
         */
 
        /* Leave only the mschap auth bits set */
-       auth_mschap_bits &= ~(PAP_WITHPEER | PAP_PEER |
-                             CHAP_WITHPEER | CHAP_PEER |
-                             CHAP_MD5_WITHPEER | CHAP_MD5_PEER);
+       auth_mschap_bits &= (CHAP_MS_WITHPEER  | CHAP_MS_PEER |
+                            CHAP_MS2_WITHPEER | CHAP_MS2_PEER);
        /* Count the mschap auths */
+       auth_mschap_bits >>= CHAP_MS_SHIFT;
        numbits = 0;
        do {
            numbits += auth_mschap_bits & 1;
@@ -568,6 +574,7 @@ ccp_resetci(f)
            if (go->mppe & MPPE_OPT_40) {
                notice("Disabling 40-bit MPPE; MS-CHAP LM not supported");
                go->mppe &= ~MPPE_OPT_40;
+               ccp_wantoptions[f->unit].mppe &= ~MPPE_OPT_40;
            }
        }
 
@@ -1047,6 +1054,9 @@ ccp_reqci(f, p, lenp, dont_nak)
     int len, clen, type, nb;
     ccp_options *ho = &ccp_hisoptions[f->unit];
     ccp_options *ao = &ccp_allowoptions[f->unit];
+#ifdef MPPE
+    bool seen_ci_mppe = 0;
+#endif
 
     ret = CONFACK;
     retp = p0 = p;
@@ -1073,6 +1083,7 @@ ccp_reqci(f, p, lenp, dont_nak)
                    newret = CONFREJ;
                    break;
                }
+               seen_ci_mppe = 1;
                MPPE_CI_TO_OPTS(&p[2], ho->mppe);
 
                /* Nak if anything unsupported or unknown are set. */
@@ -1302,8 +1313,10 @@ ccp_reqci(f, p, lenp, dont_nak)
        else
            *lenp = retp - p0;
     }
-    if (ret == CONFREJ && ao->mppe)
+#ifdef MPPE
+    if (ret == CONFREJ && ao->mppe && !seen_ci_mppe)
        lcp_close(f->unit, "MPPE required but peer negotiation failed");
+#endif
     return ret;
 }
 
@@ -1397,6 +1410,13 @@ ccp_up(f)
            notice("%s receive compression enabled", method_name(go, NULL));
     } else if (ANY_COMPRESS(*ho))
        notice("%s transmit compression enabled", method_name(ho, NULL));
+#ifdef MPPE
+    if (go->mppe) {
+       BZERO(mppe_recv_key, MPPE_MAX_KEY_LEN);
+       BZERO(mppe_send_key, MPPE_MAX_KEY_LEN);
+       start_networks(f->unit);                /* Bring up IP et al */
+    }
+#endif
 }
 
 /*
@@ -1410,6 +1430,10 @@ ccp_down(f)
        UNTIMEOUT(ccp_rack_timeout, f);
     ccp_localstate[f->unit] = 0;
     ccp_flags_set(f->unit, 1, 0);
+#ifdef MPPE
+    if (ccp_gotoptions[f->unit].mppe)
+       lcp_close(f->unit, "MPPE disabled");
+#endif
 }
 
 /*
@@ -1480,6 +1504,9 @@ ccp_printpkt(p, plen, printer, arg)
                            (p[5] & MPPE_D_BIT)? "+D": "-D",
                            (p[5] & MPPE_C_BIT)? "+C": "-C",
                            (mppe_opts & MPPE_OPT_UNKNOWN)? " +U": "");
+                   if (mppe_opts & MPPE_OPT_UNKNOWN)
+                       printer(arg, " (%.2x %.2x %.2x %.2x)",
+                               p[2], p[3], p[4], p[5]);
                    p += CILEN_MPPE;
                }
                break;
index a9dc78cdc91d887feb06e1bd6c36fd39e2b86332..c295bb360864520b2d98e06d27f21ed2f66ec175 100644 (file)
@@ -33,7 +33,7 @@
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define RCSID  "$Id: chap.c,v 1.31 2002/04/02 14:15:07 dfs Exp $"
+#define RCSID  "$Id: chap.c,v 1.32 2002/05/21 17:26:49 dfs Exp $"
 
 /*
  * TODO:
@@ -585,6 +585,11 @@ ChapReceiveResponse(cstate, inp, id, len)
     BCOPY(inp, rhostname, len);
     rhostname[len] = '\000';
 
+#ifdef CHAPMS
+    /* copy the flags into cstate for use elsewhere */
+    if (cstate->chal_type == CHAP_MICROSOFT_V2)
+       cstate->resp_flags = ((MS_Chap2Response *) remmd)->Flags[0];
+#endif /* CHAPMS */
     /*
      * Get secret for authenticating them with us,
      * do the hash ourselves, and compare the result.
@@ -824,35 +829,35 @@ ChapReceiveFailure(cstate, inp, id, len)
            /* No M=<message>; use the error code. */
            switch(error) {
            case MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS:
-               p = "Restricted logon hours";
+               p = "E=646 Restricted logon hours";
                break;
 
            case MS_CHAP_ERROR_ACCT_DISABLED:
-               p = "Account disabled";
+               p = "E=647 Account disabled";
                break;
 
            case MS_CHAP_ERROR_PASSWD_EXPIRED:
-               p = "Password expired";
+               p = "E=648 Password expired";
                break;
 
            case MS_CHAP_ERROR_NO_DIALIN_PERMISSION:
-               p = "No dialin permission";
+               p = "E=649 No dialin permission";
                break;
 
            case MS_CHAP_ERROR_AUTHENTICATION_FAILURE:
-               p = "Authentication failure";
+               p = "E=691 Authentication failure";
                break;
 
            case MS_CHAP_ERROR_CHANGING_PASSWORD:
                /* Should never see this, we don't support Change Password. */
-               p = "Error changing password";
+               p = "E=709 Error changing password";
                break;
 
            default:
                free(msg);
                p = msg = malloc(len + 33);
                if (!msg) {
-                   notice("Out of memory in ChapReceiveFailure");
+                   novm("ChapReceiveFailure");
                    goto print_msg;
                }
                slprintf(p, len + 33, "Unknown authentication failure: %.*s",
@@ -935,16 +940,30 @@ ChapSendStatus(cstate, code)
 #ifdef CHAPMS
        if (cstate->chal_type == CHAP_MICROSOFT_V2) {
            /*
-            * Success message must be formatted as
+            * Per RFC 2759, success message must be formatted as
             *     "S=<auth_string> M=<message>"
             * where
             *     <auth_string> is the Authenticator Response (mutual auth)
             *     <message> is a text message
+            *
+            * However, some versions of Windows (win98 tested) do not know
+            * about the M=<message> part (required per RFC 2759) and flag
+            * it as an error (reported incorrectly as an encryption error
+            * to the user).  Since the RFC requires it, and it can be
+            * useful information, we supply it if the peer is a conforming
+            * system.  Luckily (?), win98 sets the Flags field to 0x04
+            * (contrary to RFC requirements) so we can use that to
+            * distinguish between conforming and non-conforming systems.
+            *
+            * Special thanks to Alex Swiridov <say@real.kharkov.ua> for
+            * help debugging this.
             */
            slprintf(p, q - p, "S=");
            p += 2;
            slprintf(p, q - p, "%s", cstate->saresponse);
            p += strlen(cstate->saresponse);
+           if (cstate->resp_flags != 0)
+               goto msgdone;
            slprintf(p, q - p, " M=");
            p += 3;
        }
@@ -967,7 +986,16 @@ ChapSendStatus(cstate, code)
             *
             * The M=m part is only for MS-CHAPv2, but MS-CHAP should ignore
             * any extra text according to RFC 2433.  So we'll go the easy
-            * (read: lazy) route and include it always.
+            * (read: lazy) route and include it always.  Neither win2k nor
+            * win98 (others untested) display the message to the user anyway.
+            * They also both ignore the E=e code.
+            *
+            * Note that it's safe to reuse the same challenge as we don't
+            * actually accept another response based on the error message
+            * (and no clients try to resend a response anyway).
+            *
+            * Basically, this whole bit is useless code, even the small
+            * implementation here is only because of overspecification.
             */
            slprintf(p, q - p, "E=691 R=1 C=");
            p += 12;
@@ -981,6 +1009,7 @@ ChapSendStatus(cstate, code)
 
        slprintf(p, q - p, "I don't like you.  Go 'way.");
     }
+msgdone:
     msglen = strlen(msg);
 
     outlen = CHAP_HEADERLEN + msglen;
index 13f05113bedbab2c5b06e3bfac715b643f6e65b4..ae4237908ec1f8fe7686cc564d47cd8fd7771a0d 100644 (file)
@@ -30,7 +30,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * $Id: chap.h,v 1.12 2002/04/02 13:54:59 dfs Exp $
+ * $Id: chap.h,v 1.13 2002/05/21 17:26:49 dfs Exp $
  */
 
 #ifndef __CHAP_INCLUDE__
  */
 
 /* bitmask of supported algorithms */
-#define MDTYPE_MD5             0x1
-#define MDTYPE_MICROSOFT_V2    0x2
-#define MDTYPE_MICROSOFT       0x4
+#define MDTYPE_MICROSOFT_V2    0x1
+#define MDTYPE_MICROSOFT       0x2
+#define MDTYPE_MD5             0x4
 
 #ifdef CHAPMS
-#define MDTYPE_ALL (MDTYPE_MD5 | MDTYPE_MICROSOFT_V2 | MDTYPE_MICROSOFT)
+#define MDTYPE_ALL (MDTYPE_MICROSOFT_V2 | MDTYPE_MICROSOFT |MDTYPE_MD5)
 #else
 #define MDTYPE_ALL (MDTYPE_MD5)
 #endif
@@ -65,9 +65,9 @@
 
 /* Return the digest alg. ID for the most preferred digest type. */
 #define CHAP_DIGEST(mdtype) \
-    ((mdtype) & MDTYPE_MD5)? CHAP_DIGEST_MD5: \
     ((mdtype) & MDTYPE_MICROSOFT_V2)? CHAP_MICROSOFT_V2: \
     ((mdtype) & MDTYPE_MICROSOFT)? CHAP_MICROSOFT: \
+    ((mdtype) & MDTYPE_MD5)? CHAP_DIGEST_MD5: \
     0
 
 /* Return the bit flag (lsb set) for our most preferred digest type. */
 
 /* Return the bit flag for a given digest algorithm ID. */
 #define CHAP_MDTYPE_D(digest) \
-    ((digest) == CHAP_DIGEST_MD5)? MDTYPE_MD5: \
     ((digest) == CHAP_MICROSOFT_V2)? MDTYPE_MICROSOFT_V2: \
     ((digest) == CHAP_MICROSOFT)? MDTYPE_MICROSOFT: \
+    ((digest) == CHAP_DIGEST_MD5)? MDTYPE_MD5: \
     0
 
 /* Can we do the requested digest? */
 #define CHAP_CANDIGEST(mdtype, digest) \
-    ((digest) == CHAP_DIGEST_MD5)? (mdtype) & MDTYPE_MD5: \
     ((digest) == CHAP_MICROSOFT_V2)? (mdtype) & MDTYPE_MICROSOFT_V2: \
     ((digest) == CHAP_MICROSOFT)? (mdtype) & MDTYPE_MICROSOFT: \
+    ((digest) == CHAP_DIGEST_MD5)? (mdtype) & MDTYPE_MD5: \
     0
 
 #define CHAP_CHALLENGE         1
@@ -124,6 +124,7 @@ typedef struct chap_state {
     char saresponse[MS_AUTH_RESPONSE_LENGTH+1];        /* Auth response to send */
     char earesponse[MS_AUTH_RESPONSE_LENGTH+1];        /* Auth response expected */
                                                /* +1 for null terminator */
+    u_char resp_flags;         /* flags from MS-CHAPv2 auth response */
     u_char resp_length;                /* length of response */
     u_char resp_id;            /* ID for response messages */
     u_char resp_type;          /* hash algorithm for responses */
index 16231db75ead75a846022061d3a9a4d4c2395306..c6ba438a43576f021ce86721a0171a51b55d043b 100644 (file)
@@ -17,7 +17,7 @@
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define RCSID  "$Id: main.c,v 1.112 2002/02/12 20:07:09 dfs Exp $"
+#define RCSID  "$Id: main.c,v 1.113 2002/05/21 17:26:49 dfs Exp $"
 
 #include <stdio.h>
 #include <ctype.h>
@@ -53,6 +53,7 @@
 #include "upap.h"
 #include "chap.h"
 #include "ccp.h"
+#include "ecp.h"
 #include "pathnames.h"
 
 #ifdef USE_TDB
@@ -222,6 +223,7 @@ struct protent *protocols[] = {
     &ipv6cp_protent,
 #endif
     &ccp_protent,
+    &ecp_protent,
 #ifdef IPX_CHANGE
     &ipxcp_protent,
 #endif
@@ -1671,7 +1673,7 @@ remove_notifier(notif, func, arg)
 }
 
 /*
- * notify - call a set of functions registered with add_notify.
+ * notify - call a set of functions registered with add_notifier.
  */
 void
 notify(notif, val)
index 6befb316f31d4f4ccab9dadf7415f6f08cd3638b..5b9a76537d4d76d544c65efd346bb3b0c29c2d51 100644 (file)
@@ -1,5 +1,5 @@
 .\" manual page [] for pppd 2.4
-.\" $Id: pppd.8,v 1.62 2002/04/02 13:54:59 dfs Exp $
+.\" $Id: pppd.8,v 1.63 2002/05/21 17:26:49 dfs Exp $
 .\" SH section heading
 .\" SS subsection heading
 .\" LP paragraph
@@ -890,6 +890,8 @@ Require the use of MPPE (Microsoft Point to Point Encryption).  This
 option disables all other compression types.  This option enables
 both 40\-bit and 128\-bit encryption.  In order for MPPE to successfully
 come up, you must have authenticated with either MS-CHAP or MS-CHAPv2.
+This option is presently only supported under Linux, and only if your
+kernel has been configured to include MPPE support.
 .TP
 .B require-mppe-40
 Require the use of MPPE, with 40\-bit encryption.
index a9b780a9e796d70575b76f8e1ed9960f079b7acf..3ade18e78960ceadd1843b00e0b3d99f082b2982 100644 (file)
@@ -16,7 +16,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * $Id: pppd.h,v 1.67 2002/04/02 13:54:59 dfs Exp $
+ * $Id: pppd.h,v 1.68 2002/05/21 17:26:49 dfs Exp $
  */
 
 /*
@@ -306,6 +306,7 @@ extern bool ms_lanman;      /* Use LanMan password instead of NT */
 #define CHAP_MD5_WITHPEER      0x10
 #define CHAP_MD5_PEER          0x20
 #ifdef CHAPMS
+#define CHAP_MS_SHIFT          6       /* LSB position for MS auths */
 #define CHAP_MS_WITHPEER       0x40
 #define CHAP_MS_PEER           0x80
 #define CHAP_MS2_WITHPEER      0x100
@@ -478,7 +479,7 @@ void link_required __P((int));        /* we are starting to use the link */
 void link_terminated __P((int));  /* we are finished with the link */
 void link_down __P((int));       /* the LCP layer has left the Opened state */
 void link_established __P((int)); /* the link is up; authenticate now */
-void start_networks __P((void));  /* start all the network control protos */
+void start_networks __P((int));   /* start all the network control protos */
 void np_up __P((int, int));      /* a network protocol has come up */
 void np_down __P((int, int));    /* a network protocol has gone down */
 void np_finished __P((int, int)); /* a network protocol no longer needs link */