356 lines
10 KiB
Text
356 lines
10 KiB
Text
$NetBSD: patch-bd,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
|
|
|
|
--- pppd/ccp.c.orig Fri Aug 13 02:46:11 1999
|
|
+++ pppd/ccp.c Sat Sep 25 14:31:25 1999
|
|
@@ -33,6 +33,9 @@
|
|
#include "pppd.h"
|
|
#include "fsm.h"
|
|
#include "ccp.h"
|
|
+#ifdef MPPE
|
|
+#include "mppe.h"
|
|
+#endif
|
|
#include <net/ppp-comp.h>
|
|
|
|
static const char rcsid[] = RCSID;
|
|
@@ -75,6 +78,32 @@
|
|
{ "-predictor1", o_bool, &ccp_wantoptions[0].predictor_1,
|
|
"don't allow Predictor-1", OPT_A2COPY,
|
|
&ccp_allowoptions[0].predictor_1 },
|
|
+#ifdef MPPE
|
|
+ { "mppe-40", o_special_noarg, setmppe_40,
|
|
+ "Allow 40 bit MPPE encryption" },
|
|
+ { "+mppe-40", o_special_noarg, setmppe_40,
|
|
+ "Allow 40 bit MPPE encryption" },
|
|
+ { "nomppe-40", o_special_noarg, setnomppe_40,
|
|
+ "Disallow 40 bit MPPE encryption" },
|
|
+ { "-mppe-40", o_special_noarg, setnomppe_40,
|
|
+ "Disallow 40 bit MPPE encryption" },
|
|
+ { "mppe-128", o_special_noarg, setmppe_128,
|
|
+ "Allow 128 bit MPPE encryption" },
|
|
+ { "+mppe-128", o_special_noarg, setmppe_128,
|
|
+ "Allow 128 bit MPPE encryption" },
|
|
+ { "nomppe-128", o_special_noarg, setnomppe_128,
|
|
+ "Disallow 128 bit MPPE encryption" },
|
|
+ { "-mppe-128", o_special_noarg, setnomppe_128,
|
|
+ "Disallow 128 bit MPPE encryption" },
|
|
+ { "mppe-stateless", o_special_noarg, setmppe_stateless,
|
|
+ "Allow stateless MPPE encryption" },
|
|
+ { "+mppe-stateless", o_special_noarg, setmppe_stateless,
|
|
+ "Allow stateless MPPE encryption" },
|
|
+ { "nomppe-stateless", o_special_noarg, setnomppe_stateless,
|
|
+ "Disallow stateless MPPE encryption" },
|
|
+ { "-mppe-stateless", o_special_noarg, setnomppe_stateless,
|
|
+ "Disallow stateless MPPE encryption" },
|
|
+#endif
|
|
|
|
{ NULL }
|
|
};
|
|
@@ -157,8 +186,14 @@
|
|
/*
|
|
* Do we want / did we get any compression?
|
|
*/
|
|
+#ifdef MPPE
|
|
+#define ANY_COMPRESS(opt) ((opt).deflate || (opt).bsd_compress \
|
|
+ || (opt).predictor_1 || (opt).predictor_2 \
|
|
+ || (opt).mppe )
|
|
+#else
|
|
#define ANY_COMPRESS(opt) ((opt).deflate || (opt).bsd_compress \
|
|
|| (opt).predictor_1 || (opt).predictor_2)
|
|
+#endif
|
|
|
|
/*
|
|
* Local state (mainly for handling reset-reqs and reset-acks).
|
|
@@ -282,6 +317,16 @@
|
|
ccp_allowoptions[0].bsd_bits = BSD_MAX_BITS;
|
|
|
|
ccp_allowoptions[0].predictor_1 = 1;
|
|
+#ifdef MPPE
|
|
+ ccp_wantoptions[0].mppe = 0;
|
|
+ ccp_wantoptions[0].mppe_stateless = 0;
|
|
+ ccp_wantoptions[0].mppe_40 = 0;
|
|
+ ccp_wantoptions[0].mppe_128 = 0;
|
|
+ ccp_allowoptions[0].mppe_stateless = 1;
|
|
+ ccp_allowoptions[0].mppe = 1;
|
|
+ ccp_allowoptions[0].mppe_40 = 1;
|
|
+ ccp_allowoptions[0].mppe_128 = 1;
|
|
+#endif /* MPPE*/
|
|
}
|
|
|
|
/*
|
|
@@ -420,7 +465,7 @@
|
|
fsm *f;
|
|
{
|
|
ccp_options *go = &ccp_gotoptions[f->unit];
|
|
- u_char opt_buf[16];
|
|
+ u_char opt_buf[256];
|
|
|
|
*go = ccp_wantoptions[f->unit];
|
|
all_rejected[f->unit] = 0;
|
|
@@ -436,6 +481,18 @@
|
|
if (ccp_test(f->unit, opt_buf, CILEN_BSD_COMPRESS, 0) <= 0)
|
|
go->bsd_compress = 0;
|
|
}
|
|
+#ifdef MPPE
|
|
+ if (go->mppe) {
|
|
+ opt_buf[0] = CI_MPPE;
|
|
+ opt_buf[1] = CILEN_MPPE;
|
|
+ opt_buf[2] = 0;
|
|
+ /* keysize is 8 here */
|
|
+ BCOPY(mppe_master_send_key_40, opt_buf+3, 8);
|
|
+ BCOPY(mppe_master_recv_key_40, opt_buf+11, 8);
|
|
+ if (ccp_test(f->unit, opt_buf, (2*8)+3, 0) <= 0)
|
|
+ go->mppe = 0;
|
|
+ }
|
|
+#endif /*MPPE*/
|
|
if (go->deflate) {
|
|
if (go->deflate_correct) {
|
|
opt_buf[0] = CI_DEFLATE;
|
|
@@ -481,6 +538,9 @@
|
|
|
|
return (go->bsd_compress? CILEN_BSD_COMPRESS: 0)
|
|
+ (go->deflate? CILEN_DEFLATE: 0)
|
|
+#ifdef MPPE
|
|
+ + (go->mppe? CILEN_MPPE: 0)
|
|
+#endif
|
|
+ (go->predictor_1? CILEN_PREDICTOR_1: 0)
|
|
+ (go->predictor_2? CILEN_PREDICTOR_2: 0);
|
|
}
|
|
@@ -529,6 +589,41 @@
|
|
p += CILEN_DEFLATE;
|
|
}
|
|
}
|
|
+#ifdef MPPE
|
|
+ if (go->mppe) {
|
|
+ u_char opt_buf[64];
|
|
+ u_int keysize = 0;
|
|
+
|
|
+ if(!mppe_allowed)
|
|
+ go->mppe_stateless = go->mppe_40 = go->mppe_128 = 0;
|
|
+ p[0]=CI_MPPE;
|
|
+ p[1]=CILEN_MPPE;
|
|
+ p[2]=(go->mppe_stateless ? MPPE_STATELESS : 0);
|
|
+ p[3]=0;
|
|
+ p[4]=0;
|
|
+ p[5]=(go->mppe_40 ? MPPE_40BIT : 0) | (go->mppe_128 ? MPPE_128BIT : 0);
|
|
+ if(p[5] & MPPE_40BIT) {
|
|
+ keysize = 8;
|
|
+ BCOPY(mppe_master_send_key_40, opt_buf+3, keysize);
|
|
+ BCOPY(mppe_master_recv_key_40, opt_buf+11, keysize);
|
|
+ } else if(p[5] & MPPE_128BIT) {
|
|
+ keysize = 16;
|
|
+ BCOPY(mppe_master_send_key_128, opt_buf+3, keysize);
|
|
+ BCOPY(mppe_master_recv_key_128, opt_buf+19, keysize);
|
|
+ }
|
|
+ if(p[5] != 0) {
|
|
+ opt_buf[0]=CI_MPPE;
|
|
+ opt_buf[1]=CILEN_MPPE;
|
|
+ opt_buf[2] = (go->mppe_stateless) ? 1 : 0;
|
|
+ res = ccp_test(f->unit, opt_buf, (2*keysize)+3, 0);
|
|
+ } else {
|
|
+ res = -1;
|
|
+ }
|
|
+ if (res > 0) {
|
|
+ p += CILEN_MPPE;
|
|
+ }
|
|
+ }
|
|
+#endif /* MPPE*/
|
|
if (go->bsd_compress) {
|
|
p[0] = CI_BSD_COMPRESS;
|
|
p[1] = CILEN_BSD_COMPRESS;
|
|
@@ -612,6 +707,22 @@
|
|
len -= CILEN_DEFLATE;
|
|
}
|
|
}
|
|
+#ifdef MPPE
|
|
+ if (go->mppe) {
|
|
+ if ( len < CILEN_MPPE
|
|
+ || p[1] != CILEN_MPPE || p[0] != CI_MPPE
|
|
+ || p[2] != (go->mppe_stateless ? MPPE_STATELESS : 0)
|
|
+ || p[3] != 0
|
|
+ || p[4] != 0
|
|
+ || p[5] != ((go->mppe_40 ? MPPE_40BIT : 0) | (go->mppe_128 ? MPPE_128BIT : 0)))
|
|
+ return 0;
|
|
+ p += CILEN_MPPE;
|
|
+ len -= CILEN_MPPE;
|
|
+ /* Cope with first/fast ack */
|
|
+ if (len == 0)
|
|
+ return 1;
|
|
+ }
|
|
+#endif /* MPPE */
|
|
if (go->bsd_compress) {
|
|
if (len < CILEN_BSD_COMPRESS
|
|
|| p[0] != CI_BSD_COMPRESS || p[1] != CILEN_BSD_COMPRESS
|
|
@@ -690,6 +801,23 @@
|
|
}
|
|
}
|
|
|
|
+#ifdef MPPE
|
|
+ if (len >= CILEN_MPPE && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
|
|
+ no.mppe = 1;
|
|
+ if((p[5] & MPPE_128BIT) == 0)
|
|
+ try.mppe_128 = 0;
|
|
+ if((p[5] & MPPE_40BIT) == 0)
|
|
+ try.mppe_40 = 0;
|
|
+ if((p[2] & MPPE_STATELESS) == 0)
|
|
+ try.mppe_stateless = 0;
|
|
+ if(!try.mppe_128 && !try.mppe_40) {
|
|
+ no.mppe = 0;
|
|
+ try.mppe = 0;
|
|
+ }
|
|
+ p += CILEN_MPPE;
|
|
+ len -= CILEN_MPPE;
|
|
+ }
|
|
+#endif /* MPPE */
|
|
if (go->bsd_compress && len >= CILEN_BSD_COMPRESS
|
|
&& p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) {
|
|
no.bsd_compress = 1;
|
|
@@ -762,6 +890,14 @@
|
|
if (!try.deflate_correct && !try.deflate_draft)
|
|
try.deflate = 0;
|
|
}
|
|
+#ifdef MPPE
|
|
+ if (go->mppe && len >= CILEN_MPPE
|
|
+ && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
|
|
+ try.mppe = 0;
|
|
+ p += CILEN_MPPE;
|
|
+ len -= CILEN_MPPE;
|
|
+ }
|
|
+#endif /*MPPE*/
|
|
if (go->bsd_compress && len >= CILEN_BSD_COMPRESS
|
|
&& p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) {
|
|
if (p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits))
|
|
@@ -875,6 +1011,78 @@
|
|
}
|
|
break;
|
|
|
|
+#ifdef MPPE
|
|
+ case CI_MPPE:
|
|
+ if (!ao->mppe || clen != CILEN_MPPE) {
|
|
+ newret = CONFREJ;
|
|
+ break;
|
|
+ }
|
|
+ if(!mppe_allowed)
|
|
+ {
|
|
+ newret = CONFREJ;
|
|
+ break;
|
|
+ }
|
|
+ ho->mppe = 1;
|
|
+ if((p[5]&(MPPE_40BIT|MPPE_128BIT)) == (MPPE_40BIT|MPPE_128BIT))
|
|
+ {
|
|
+ /* if both are available, select the stronger */
|
|
+ p[5] &= ~MPPE_40BIT;
|
|
+ newret = CONFNAK;
|
|
+ }
|
|
+ if((p[2] & ~MPPE_STATELESS) != 0
|
|
+ || p[3] != 0
|
|
+ || p[4] != 0
|
|
+ || (p[5] & ~(MPPE_40BIT | MPPE_128BIT)) != 0)
|
|
+ {
|
|
+ ccp_options *wo = &ccp_wantoptions[f->unit];
|
|
+ /* not sure what they want, tell 'em what we got */
|
|
+ p[2] &= MPPE_STATELESS;
|
|
+ p[3] &= 0;
|
|
+ p[4] &= 0;
|
|
+ p[5] &= MPPE_40BIT | MPPE_128BIT;
|
|
+ if(wo->mppe_40)
|
|
+ p[5] |= MPPE_40BIT;
|
|
+ if(wo->mppe_128)
|
|
+ p[5] |= MPPE_128BIT;
|
|
+ newret = CONFNAK;
|
|
+ }
|
|
+
|
|
+ if((newret == CONFACK) || (newret == CONFNAK))
|
|
+ {
|
|
+ /*
|
|
+ * The kernel ppp driver needs the session key
|
|
+ * which is not sent via CCP :(
|
|
+ */
|
|
+ unsigned int keysize;
|
|
+ unsigned char opt_buf[64];
|
|
+ opt_buf[0] = CI_MPPE;
|
|
+ opt_buf[1] = CILEN_MPPE;
|
|
+ opt_buf[2] = ((p[2] & MPPE_STATELESS) ? 1 : 0);
|
|
+ /* push in our send/receive keys */
|
|
+ if(p[5] & MPPE_40BIT) {
|
|
+ ho->mppe_40 = 1;
|
|
+ keysize = 8;
|
|
+ BCOPY(mppe_master_send_key_40, opt_buf+3, keysize);
|
|
+ BCOPY(mppe_master_recv_key_40, opt_buf+11, keysize);
|
|
+ } else if(p[5] & MPPE_128BIT) {
|
|
+ ho->mppe_128 = 1;
|
|
+ keysize = 16;
|
|
+ BCOPY(mppe_master_send_key_128, opt_buf+3, keysize);
|
|
+ BCOPY(mppe_master_recv_key_128, opt_buf+19, keysize);
|
|
+ } else {
|
|
+ ho->mppe = 0;
|
|
+ newret = CONFREJ;
|
|
+ break;
|
|
+ }
|
|
+ /* call ioctl and pass this nasty stuff to the kernel */
|
|
+ if (ccp_test(f->unit, opt_buf, (2*keysize)+3, 1) <= 0){
|
|
+ ho->mppe = 0;
|
|
+ newret = CONFREJ;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ break;
|
|
+#endif /* MPPE */
|
|
case CI_BSD_COMPRESS:
|
|
if (!ao->bsd_compress || clen != CILEN_BSD_COMPRESS) {
|
|
newret = CONFREJ;
|
|
@@ -996,6 +1204,28 @@
|
|
(opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),
|
|
opt->deflate_size);
|
|
break;
|
|
+#ifdef MPPE
|
|
+ case CI_MPPE:
|
|
+ if (opt->mppe_40) {
|
|
+ if (opt->mppe_stateless) {
|
|
+ return "MPPE 40 bit, stateless";
|
|
+ } else {
|
|
+ return "MPPE 40 bit, non-stateless";
|
|
+ }
|
|
+ } else if (opt->mppe_128) {
|
|
+ if (opt->mppe_stateless) {
|
|
+ return "MPPE 128 bit, stateless";
|
|
+ } else {
|
|
+ return "MPPE 128 bit, non-stateless";
|
|
+ }
|
|
+ } else {
|
|
+ if (opt->mppe_stateless) {
|
|
+ return "MPPE unknown strength, stateless";
|
|
+ } else {
|
|
+ return "MPPE unknown strength, stateless";
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
case CI_BSD_COMPRESS:
|
|
if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits)
|
|
slprintf(result, sizeof(result), "BSD-Compress (%d/%d)",
|
|
@@ -1134,6 +1364,14 @@
|
|
p += CILEN_PREDICTOR_1;
|
|
}
|
|
break;
|
|
+#ifdef MPPE
|
|
+ case CI_MPPE:
|
|
+ if (optlen >= CILEN_MPPE) {
|
|
+ printer(arg, "mppe %x %x %x %x",p[2],p[3],p[4],p[5]);
|
|
+ p += CILEN_MPPE;
|
|
+ }
|
|
+ break;
|
|
+#endif
|
|
case CI_PREDICTOR_2:
|
|
if (optlen >= CILEN_PREDICTOR_2) {
|
|
printer(arg, "predictor 2");
|
|
@@ -1193,6 +1431,11 @@
|
|
error("Lost compression sync: disabling compression");
|
|
ccp_close(unit, "Lost compression sync");
|
|
} else {
|
|
+#ifdef MPPE
|
|
+ /* MPPE/MPPC does not requires CCP_RESETREQ */
|
|
+ if (ccp_gotoptions[f->unit].method == CI_MPPE)
|
|
+ return;
|
|
+#endif
|
|
/*
|
|
* Send a reset-request to reset the peer's compressor.
|
|
* We don't do that if we are still waiting for an
|