Root/package/network/services/ppp/patches/201-mppe_mppc_1.1.patch

1pppd: add support for MPPE and MPPC encryption and compression protocols
2
3This is a forward ported version of ppp-2.4.3-mppe-mppc-1.1.patch.gz found on
4http://mppe-mppc.alphacron.de/ .
5
6Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
7
8--- a/include/linux/ppp-comp.h
9+++ b/include/linux/ppp-comp.h
10@@ -36,7 +36,7 @@
11  */
12 
13 /*
14- * ==FILEVERSION 20020319==
15+ * ==FILEVERSION 20020715==
16  *
17  * NOTE TO MAINTAINERS:
18  * If you modify this file at all, please set the above date.
19@@ -201,6 +201,33 @@ struct compressor {
20 #define CI_MPPE 18 /* config option for MPPE */
21 #define CILEN_MPPE 6 /* length of config option */
22 
23+/* MPPE/MPPC definitions by J.D.*/
24+#define MPPE_STATELESS MPPE_H_BIT /* configuration bit H */
25+#define MPPE_40BIT MPPE_L_BIT /* configuration bit L */
26+#define MPPE_56BIT MPPE_M_BIT /* configuration bit M */
27+#define MPPE_128BIT MPPE_S_BIT /* configuration bit S */
28+#define MPPE_MPPC MPPE_C_BIT /* configuration bit C */
29+
30+/*
31+ * Definitions for Stac LZS.
32+ */
33+
34+#define CI_LZS 17 /* config option for Stac LZS */
35+#define CILEN_LZS 5 /* length of config option */
36+
37+#define LZS_OVHD 4 /* max. LZS overhead */
38+#define LZS_HIST_LEN 2048 /* LZS history size */
39+#define LZS_MAX_CCOUNT 0x0FFF /* max. coherency counter value */
40+
41+#define LZS_MODE_NONE 0
42+#define LZS_MODE_LCB 1
43+#define LZS_MODE_CRC 2
44+#define LZS_MODE_SEQ 3
45+#define LZS_MODE_EXT 4
46+
47+#define LZS_EXT_BIT_FLUSHED 0x80 /* bit A */
48+#define LZS_EXT_BIT_COMP 0x20 /* bit C */
49+
50 /*
51  * Definitions for other, as yet unsupported, compression methods.
52  */
53--- a/include/net/ppp-comp.h
54+++ b/include/net/ppp-comp.h
55@@ -168,6 +168,33 @@ struct compressor {
56 #define CI_MPPE 18 /* config option for MPPE */
57 #define CILEN_MPPE 6 /* length of config option */
58 
59+/* MPPE/MPPC definitions by J.D.*/
60+#define MPPE_STATELESS MPPE_H_BIT /* configuration bit H */
61+#define MPPE_40BIT MPPE_L_BIT /* configuration bit L */
62+#define MPPE_56BIT MPPE_M_BIT /* configuration bit M */
63+#define MPPE_128BIT MPPE_S_BIT /* configuration bit S */
64+#define MPPE_MPPC MPPE_C_BIT /* configuration bit C */
65+
66+/*
67+ * Definitions for Stac LZS.
68+ */
69+
70+#define CI_LZS 17 /* config option for Stac LZS */
71+#define CILEN_LZS 5 /* length of config option */
72+
73+#define LZS_OVHD 4 /* max. LZS overhead */
74+#define LZS_HIST_LEN 2048 /* LZS history size */
75+#define LZS_MAX_CCOUNT 0x0FFF /* max. coherency counter value */
76+
77+#define LZS_MODE_NONE 0
78+#define LZS_MODE_LCB 1
79+#define LZS_MODE_CRC 2
80+#define LZS_MODE_SEQ 3
81+#define LZS_MODE_EXT 4
82+
83+#define LZS_EXT_BIT_FLUSHED 0x80 /* bit A */
84+#define LZS_EXT_BIT_COMP 0x20 /* bit C */
85+
86 /*
87  * Definitions for other, as yet unsupported, compression methods.
88  */
89--- a/pppd/ccp.c
90+++ b/pppd/ccp.c
91@@ -62,12 +62,10 @@ static int setdeflate __P((char **));
92 static char bsd_value[8];
93 static char deflate_value[8];
94 
95-/*
96- * Option variables.
97- */
98 #ifdef MPPE
99-bool refuse_mppe_stateful = 1; /* Allow stateful mode? */
100-#endif
101+static int setmppe(char **);
102+static int setnomppe(void);
103+#endif /* MPPE */
104 
105 static option_t ccp_option_list[] = {
106     { "noccp", o_bool, &ccp_protent.enabled_flag,
107@@ -108,54 +106,36 @@ static option_t ccp_option_list[] = {
108       "don't allow Predictor-1", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
109       &ccp_allowoptions[0].predictor_1 },
110 
111+ { "lzs", o_bool, &ccp_wantoptions[0].lzs,
112+ "request Stac LZS", 1, &ccp_allowoptions[0].lzs, OPT_PRIO },
113+ { "+lzs", o_bool, &ccp_wantoptions[0].lzs,
114+ "request Stac LZS", 1, &ccp_allowoptions[0].lzs, OPT_ALIAS | OPT_PRIO },
115+ { "nolzs", o_bool, &ccp_wantoptions[0].lzs,
116+ "don't allow Stac LZS", OPT_PRIOSUB | OPT_A2CLR,
117+ &ccp_allowoptions[0].lzs },
118+ { "-lzs", o_bool, &ccp_wantoptions[0].lzs,
119+ "don't allow Stac LZS", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
120+ &ccp_allowoptions[0].lzs },
121+
122 #ifdef MPPE
123- /* MPPE options are symmetrical ... we only set wantoptions here */
124- { "require-mppe", o_bool, &ccp_wantoptions[0].mppe,
125- "require MPPE encryption",
126- OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 },
127- { "+mppe", o_bool, &ccp_wantoptions[0].mppe,
128- "require MPPE encryption",
129- OPT_ALIAS | OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 },
130- { "nomppe", o_bool, &ccp_wantoptions[0].mppe,
131- "don't allow MPPE encryption", OPT_PRIO },
132- { "-mppe", o_bool, &ccp_wantoptions[0].mppe,
133- "don't allow MPPE encryption", OPT_ALIAS | OPT_PRIO },
134-
135- /* We use ccp_allowoptions[0].mppe as a junk var ... it is reset later */
136- { "require-mppe-40", o_bool, &ccp_allowoptions[0].mppe,
137- "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40,
138- &ccp_wantoptions[0].mppe },
139- { "+mppe-40", o_bool, &ccp_allowoptions[0].mppe,
140- "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40,
141- &ccp_wantoptions[0].mppe },
142- { "nomppe-40", o_bool, &ccp_allowoptions[0].mppe,
143- "don't allow MPPE 40-bit encryption",
144- OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, &ccp_wantoptions[0].mppe },
145- { "-mppe-40", o_bool, &ccp_allowoptions[0].mppe,
146- "don't allow MPPE 40-bit encryption",
147- OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40,
148- &ccp_wantoptions[0].mppe },
149-
150- { "require-mppe-128", o_bool, &ccp_allowoptions[0].mppe,
151- "require MPPE 128-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_128,
152- &ccp_wantoptions[0].mppe },
153- { "+mppe-128", o_bool, &ccp_allowoptions[0].mppe,
154- "require MPPE 128-bit encryption",
155- OPT_ALIAS | OPT_PRIO | OPT_A2OR | MPPE_OPT_128,
156- &ccp_wantoptions[0].mppe },
157- { "nomppe-128", o_bool, &ccp_allowoptions[0].mppe,
158- "don't allow MPPE 128-bit encryption",
159- OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, &ccp_wantoptions[0].mppe },
160- { "-mppe-128", o_bool, &ccp_allowoptions[0].mppe,
161- "don't allow MPPE 128-bit encryption",
162- OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128,
163- &ccp_wantoptions[0].mppe },
164-
165- /* strange one; we always request stateless, but will we allow stateful? */
166- { "mppe-stateful", o_bool, &refuse_mppe_stateful,
167- "allow MPPE stateful mode", OPT_PRIO },
168- { "nomppe-stateful", o_bool, &refuse_mppe_stateful,
169- "disallow MPPE stateful mode", OPT_PRIO | 1 },
170+ { "mppc", o_bool, &ccp_wantoptions[0].mppc,
171+ "request MPPC compression", 1, &ccp_allowoptions[0].mppc },
172+ { "+mppc", o_bool, &ccp_wantoptions[0].mppc,
173+ "request MPPC compression", 1, &ccp_allowoptions[0].mppc, OPT_ALIAS },
174+ { "nomppc", o_bool, &ccp_wantoptions[0].mppc,
175+ "don't allow MPPC compression", OPT_PRIOSUB | OPT_A2CLR,
176+ &ccp_allowoptions[0].mppc },
177+ { "-mppc", o_bool, &ccp_wantoptions[0].mppc,
178+ "don't allow MPPC compression", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
179+ &ccp_allowoptions[0].mppc },
180+ { "mppe", o_special, (void *)setmppe,
181+ "request MPPE encryption" },
182+ { "+mppe", o_special, (void *)setmppe,
183+ "request MPPE encryption" },
184+ { "nomppe", o_special_noarg, (void *)setnomppe,
185+ "don't allow MPPE encryption" },
186+ { "-mppe", o_special_noarg, (void *)setnomppe,
187+ "don't allow MPPE encryption" },
188 #endif /* MPPE */
189 
190     { NULL }
191@@ -241,7 +221,7 @@ static fsm_callbacks ccp_callbacks = {
192  */
193 #define ANY_COMPRESS(opt) ((opt).deflate || (opt).bsd_compress \
194                  || (opt).predictor_1 || (opt).predictor_2 \
195- || (opt).mppe)
196+ || (opt).lzs || (opt).mppc || (opt).mppe)
197 
198 /*
199  * Local state (mainly for handling reset-reqs and reset-acks).
200@@ -344,6 +324,100 @@ setdeflate(argv)
201     return 1;
202 }
203 
204+#ifdef MPPE
205+/*
206+ * Functions called from config options
207+ */
208+/*
209+ MPPE suboptions:
210+ required - require MPPE; disconnect if peer doesn't support it
211+ stateless - use stateless mode
212+ no40 - disable 40 bit keys
213+ no56 - disable 56 bit keys
214+ no128 - disable 128 bit keys
215+*/
216+int setmppe(char **argv)
217+{
218+ int i;
219+ char *str, cmdbuf[16];
220+
221+ ccp_allowoptions[0].mppe = 1;
222+ ccp_allowoptions[0].mppe_40 = 1;
223+ ccp_allowoptions[0].mppe_56 = 1;
224+ ccp_allowoptions[0].mppe_128 = 1;
225+ ccp_allowoptions[0].mppe_stateless = 0;
226+ ccp_wantoptions[0].mppe = 0;
227+
228+ str = *argv;
229+
230+ while (1) {
231+ i = 0;
232+ memset(cmdbuf, '\0', 16);
233+ while ((i < 16) && (*str != ',') && (*str != '\0'))
234+ cmdbuf[i++] = *str++;
235+ cmdbuf[i] = '\0';
236+ if (!strncasecmp(cmdbuf, "no40", strlen("no40"))) {
237+ ccp_allowoptions[0].mppe_40 = 0;
238+ goto next_param;
239+ } else if (!strncasecmp(cmdbuf, "no56", strlen("no56"))) {
240+ ccp_allowoptions[0].mppe_56 = 0;
241+ goto next_param;
242+ } else if (!strncasecmp(cmdbuf, "no128", strlen("no128"))) {
243+ ccp_allowoptions[0].mppe_128 = 0;
244+ goto next_param;
245+ } else if (!strncasecmp(cmdbuf, "stateless", strlen("stateless"))) {
246+ ccp_allowoptions[0].mppe_stateless = 1;
247+ goto next_param;
248+ } else if (!strncasecmp(cmdbuf, "required", strlen("required"))) {
249+ ccp_wantoptions[0].mppe = 1;
250+ goto next_param;
251+ } else {
252+ option_error("invalid parameter '%s' for mppe option", cmdbuf);
253+ return 0;
254+ }
255+
256+ next_param:
257+ if (*str == ',') {
258+ str++;
259+ continue;
260+ }
261+ if (*str == '\0') {
262+ if (!(ccp_allowoptions[0].mppe_40 || ccp_allowoptions[0].mppe_56 ||
263+ ccp_allowoptions[0].mppe_128)) {
264+ if (ccp_wantoptions[0].mppe == 1) {
265+ option_error("You require MPPE but you have switched off "
266+ "all encryption key lengths.");
267+ return 0;
268+ }
269+ ccp_wantoptions[0].mppe = ccp_allowoptions[0].mppe = 0;
270+ ccp_wantoptions[0].mppe_stateless =
271+ ccp_allowoptions[0].mppe_stateless = 0;
272+ } else {
273+ ccp_allowoptions[0].mppe = 1;
274+ ccp_wantoptions[0].mppe_stateless =
275+ ccp_allowoptions[0].mppe_stateless;
276+ if (ccp_wantoptions[0].mppe == 1) {
277+ ccp_wantoptions[0].mppe_40 = ccp_allowoptions[0].mppe_40;
278+ ccp_wantoptions[0].mppe_56 = ccp_allowoptions[0].mppe_56;
279+ ccp_wantoptions[0].mppe_128 = ccp_allowoptions[0].mppe_128;
280+ }
281+ }
282+ return 1;
283+ }
284+ }
285+}
286+
287+int setnomppe(void)
288+{
289+ ccp_wantoptions[0].mppe = ccp_allowoptions[0].mppe = 0;
290+ ccp_wantoptions[0].mppe_40 = ccp_allowoptions[0].mppe_40 = 0;
291+ ccp_wantoptions[0].mppe_56 = ccp_allowoptions[0].mppe_56 = 0;
292+ ccp_wantoptions[0].mppe_128 = ccp_allowoptions[0].mppe_128 = 0;
293+ ccp_wantoptions[0].mppe_stateless = ccp_allowoptions[0].mppe_stateless = 0;
294+ return 1;
295+}
296+#endif /* MPPE */
297+
298 /*
299  * ccp_init - initialize CCP.
300  */
301@@ -378,6 +452,30 @@ ccp_init(unit)
302     ccp_allowoptions[0].bsd_bits = BSD_MAX_BITS;
303 
304     ccp_allowoptions[0].predictor_1 = 1;
305+
306+ ccp_wantoptions[0].lzs = 0; /* Stac LZS - will be enabled in the future */
307+ ccp_wantoptions[0].lzs_mode = LZS_MODE_SEQ;
308+ ccp_wantoptions[0].lzs_hists = 1;
309+ ccp_allowoptions[0].lzs = 0; /* Stac LZS - will be enabled in the future */
310+ ccp_allowoptions[0].lzs_mode = LZS_MODE_SEQ;
311+ ccp_allowoptions[0].lzs_hists = 1;
312+
313+#ifdef MPPE
314+ /* by default allow and request MPPC... */
315+ ccp_wantoptions[0].mppc = ccp_allowoptions[0].mppc = 1;
316+
317+ /* ... and allow but don't request MPPE */
318+ ccp_allowoptions[0].mppe = 1;
319+ ccp_allowoptions[0].mppe_40 = 1;
320+ ccp_allowoptions[0].mppe_56 = 1;
321+ ccp_allowoptions[0].mppe_128 = 1;
322+ ccp_allowoptions[0].mppe_stateless = 1;
323+ ccp_wantoptions[0].mppe = 0;
324+ ccp_wantoptions[0].mppe_40 = 0;
325+ ccp_wantoptions[0].mppe_56 = 0;
326+ ccp_wantoptions[0].mppe_128 = 0;
327+ ccp_wantoptions[0].mppe_stateless = 0;
328+#endif /* MPPE */
329 }
330 
331 /*
332@@ -455,11 +553,11 @@ ccp_input(unit, p, len)
333     if (oldstate == OPENED && p[0] == TERMREQ && f->state != OPENED) {
334     notice("Compression disabled by peer.");
335 #ifdef MPPE
336- if (ccp_gotoptions[unit].mppe) {
337+ if (ccp_wantoptions[unit].mppe) {
338         error("MPPE disabled, closing LCP");
339         lcp_close(unit, "MPPE disabled by peer");
340     }
341-#endif
342+#endif /* MPPE */
343     }
344 
345     /*
346@@ -487,6 +585,15 @@ ccp_extcode(f, code, id, p, len)
347         break;
348     /* send a reset-ack, which the transmitter will see and
349        reset its compression state. */
350+
351+ /* In case of MPPE/MPPC or LZS we shouldn't send CCP_RESETACK,
352+ but we do it in order to reset compressor; CCP_RESETACK is
353+ then silently discarded. See functions ppp_send_frame and
354+ ppp_ccp_peek in ppp_generic.c (Linux only !!!). All the
355+ confusion is caused by the fact that CCP code is splited
356+ into two parts - one part is handled by pppd, the other one
357+ is handled by kernel. */
358+
359     fsm_sdata(f, CCP_RESETACK, id, NULL, 0);
360     break;
361 
362@@ -515,12 +622,11 @@ ccp_protrej(unit)
363     fsm_lowerdown(&ccp_fsm[unit]);
364 
365 #ifdef MPPE
366- if (ccp_gotoptions[unit].mppe) {
367+ if (ccp_wantoptions[unit].mppe) {
368     error("MPPE required but peer negotiation failed");
369     lcp_close(unit, "MPPE required but peer negotiation failed");
370     }
371-#endif
372-
373+#endif /* MPPE */
374 }
375 
376 /*
377@@ -537,7 +643,7 @@ ccp_resetci(f)
378     all_rejected[f->unit] = 0;
379 
380 #ifdef MPPE
381- if (go->mppe) {
382+ if (go->mppe || go->mppc) {
383     ccp_options *ao = &ccp_allowoptions[f->unit];
384     int auth_mschap_bits = auth_done[f->unit];
385     int numbits;
386@@ -551,80 +657,109 @@ ccp_resetci(f)
387      * NB: If MPPE is required, all other compression opts are invalid.
388      * So, we return right away if we can't do it.
389      */
390+ if (ccp_wantoptions[f->unit].mppe) {
391+ /* Leave only the mschap auth bits set */
392+ auth_mschap_bits &= (CHAP_MS_WITHPEER | CHAP_MS_PEER |
393+ CHAP_MS2_WITHPEER | CHAP_MS2_PEER);
394+ /* Count the mschap auths */
395+ auth_mschap_bits >>= CHAP_MS_SHIFT;
396+ numbits = 0;
397+ do {
398+ numbits += auth_mschap_bits & 1;
399+ auth_mschap_bits >>= 1;
400+ } while (auth_mschap_bits);
401+ if (numbits > 1) {
402+ error("MPPE required, but auth done in both directions.");
403+ lcp_close(f->unit, "MPPE required but not available");
404+ return;
405+ }
406+ if (!numbits) {
407+ error("MPPE required, but MS-CHAP[v2] auth not performed.");
408+ lcp_close(f->unit, "MPPE required but not available");
409+ return;
410+ }
411 
412- /* Leave only the mschap auth bits set */
413- auth_mschap_bits &= (CHAP_MS_WITHPEER | CHAP_MS_PEER |
414- CHAP_MS2_WITHPEER | CHAP_MS2_PEER);
415- /* Count the mschap auths */
416- auth_mschap_bits >>= CHAP_MS_SHIFT;
417- numbits = 0;
418- do {
419- numbits += auth_mschap_bits & 1;
420- auth_mschap_bits >>= 1;
421- } while (auth_mschap_bits);
422- if (numbits > 1) {
423- error("MPPE required, but auth done in both directions.");
424- lcp_close(f->unit, "MPPE required but not available");
425- return;
426- }
427- if (!numbits) {
428- error("MPPE required, but MS-CHAP[v2] auth not performed.");
429- lcp_close(f->unit, "MPPE required but not available");
430- return;
431- }
432-
433- /* A plugin (eg radius) may not have obtained key material. */
434- if (!mppe_keys_set) {
435- error("MPPE required, but keys are not available. "
436- "Possible plugin problem?");
437- lcp_close(f->unit, "MPPE required but not available");
438- return;
439- }
440-
441- /* LM auth not supported for MPPE */
442- if (auth_done[f->unit] & (CHAP_MS_WITHPEER | CHAP_MS_PEER)) {
443- /* This might be noise */
444- if (go->mppe & MPPE_OPT_40) {
445- notice("Disabling 40-bit MPPE; MS-CHAP LM not supported");
446- go->mppe &= ~MPPE_OPT_40;
447- ccp_wantoptions[f->unit].mppe &= ~MPPE_OPT_40;
448+ /* A plugin (eg radius) may not have obtained key material. */
449+ if (!mppe_keys_set) {
450+ error("MPPE required, but keys are not available. "
451+ "Possible plugin problem?");
452+ lcp_close(f->unit, "MPPE required but not available");
453+ return;
454         }
455     }
456 
457- /* Last check: can we actually negotiate something? */
458- if (!(go->mppe & (MPPE_OPT_40 | MPPE_OPT_128))) {
459- /* Could be misconfig, could be 40-bit disabled above. */
460- error("MPPE required, but both 40-bit and 128-bit disabled.");
461- lcp_close(f->unit, "MPPE required but not available");
462- return;
463+ /*
464+ * Check whether the kernel knows about the various
465+ * compression methods we might request. Key material
466+ * unimportant here.
467+ */
468+ if (go->mppc) {
469+ opt_buf[0] = CI_MPPE;
470+ opt_buf[1] = CILEN_MPPE;
471+ opt_buf[2] = 0;
472+ opt_buf[3] = 0;
473+ opt_buf[4] = 0;
474+ opt_buf[5] = MPPE_MPPC;
475+ if (ccp_test(f->unit, opt_buf, CILEN_MPPE, 0) <= 0)
476+ go->mppc = 0;
477+ }
478+ if (go->mppe_40) {
479+ opt_buf[0] = CI_MPPE;
480+ opt_buf[1] = CILEN_MPPE;
481+ opt_buf[2] = MPPE_STATELESS;
482+ opt_buf[3] = 0;
483+ opt_buf[4] = 0;
484+ opt_buf[5] = MPPE_40BIT;
485+ if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0)
486+ go->mppe_40 = 0;
487+ }
488+ if (go->mppe_56) {
489+ opt_buf[0] = CI_MPPE;
490+ opt_buf[1] = CILEN_MPPE;
491+ opt_buf[2] = MPPE_STATELESS;
492+ opt_buf[3] = 0;
493+ opt_buf[4] = 0;
494+ opt_buf[5] = MPPE_56BIT;
495+ if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0)
496+ go->mppe_56 = 0;
497+ }
498+ if (go->mppe_128) {
499+ opt_buf[0] = CI_MPPE;
500+ opt_buf[1] = CILEN_MPPE;
501+ opt_buf[2] = MPPE_STATELESS;
502+ opt_buf[3] = 0;
503+ opt_buf[4] = 0;
504+ opt_buf[5] = MPPE_128BIT;
505+ if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0)
506+ go->mppe_128 = 0;
507+ }
508+ if (!go->mppe_40 && !go->mppe_56 && !go->mppe_128) {
509+ if (ccp_wantoptions[f->unit].mppe) {
510+ error("MPPE required, but kernel has no support.");
511+ lcp_close(f->unit, "MPPE required but not available");
512+ }
513+ go->mppe = go->mppe_stateless = 0;
514+ } else {
515+ /* MPPE is not compatible with other compression types */
516+ if (ccp_wantoptions[f->unit].mppe) {
517+ ao->bsd_compress = go->bsd_compress = 0;
518+ ao->predictor_1 = go->predictor_1 = 0;
519+ ao->predictor_2 = go->predictor_2 = 0;
520+ ao->deflate = go->deflate = 0;
521+ ao->lzs = go->lzs = 0;
522+ }
523     }
524-
525- /* sync options */
526- ao->mppe = go->mppe;
527- /* MPPE is not compatible with other compression types */
528- ao->bsd_compress = go->bsd_compress = 0;
529- ao->predictor_1 = go->predictor_1 = 0;
530- ao->predictor_2 = go->predictor_2 = 0;
531- ao->deflate = go->deflate = 0;
532     }
533 #endif /* MPPE */
534-
535- /*
536- * Check whether the kernel knows about the various
537- * compression methods we might request.
538- */
539-#ifdef MPPE
540- if (go->mppe) {
541- opt_buf[0] = CI_MPPE;
542- opt_buf[1] = CILEN_MPPE;
543- MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
544- /* Key material unimportant here. */
545- if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0) {
546- error("MPPE required, but kernel has no support.");
547- lcp_close(f->unit, "MPPE required but not available");
548- }
549+ if (go->lzs) {
550+ opt_buf[0] = CI_LZS;
551+ opt_buf[1] = CILEN_LZS;
552+ opt_buf[2] = go->lzs_hists >> 8;
553+ opt_buf[3] = go->lzs_hists & 0xff;
554+ opt_buf[4] = LZS_MODE_SEQ;
555+ if (ccp_test(f->unit, opt_buf, CILEN_LZS, 0) <= 0)
556+ go->lzs = 0;
557     }
558-#endif
559     if (go->bsd_compress) {
560     opt_buf[0] = CI_BSD_COMPRESS;
561     opt_buf[1] = CILEN_BSD_COMPRESS;
562@@ -679,7 +814,8 @@ ccp_cilen(f)
563     + (go->deflate? CILEN_DEFLATE: 0)
564     + (go->predictor_1? CILEN_PREDICTOR_1: 0)
565     + (go->predictor_2? CILEN_PREDICTOR_2: 0)
566- + (go->mppe? CILEN_MPPE: 0);
567+ + (go->lzs? CILEN_LZS: 0)
568+ + ((go->mppe || go->mppc)? CILEN_MPPE: 0);
569 }
570 
571 /*
572@@ -693,6 +829,8 @@ ccp_addci(f, p, lenp)
573 {
574     int res;
575     ccp_options *go = &ccp_gotoptions[f->unit];
576+ ccp_options *ao = &ccp_allowoptions[f->unit];
577+ ccp_options *wo = &ccp_wantoptions[f->unit];
578     u_char *p0 = p;
579 
580     /*
581@@ -701,22 +839,43 @@ ccp_addci(f, p, lenp)
582      * in case it gets Acked.
583      */
584 #ifdef MPPE
585- if (go->mppe) {
586+ if (go->mppe || go->mppc || (!wo->mppe && ao->mppe)) {
587     u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];
588 
589- p[0] = opt_buf[0] = CI_MPPE;
590- p[1] = opt_buf[1] = CILEN_MPPE;
591- MPPE_OPTS_TO_CI(go->mppe, &p[2]);
592- MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
593+ p[0] = CI_MPPE;
594+ p[1] = CILEN_MPPE;
595+ p[2] = (go->mppe_stateless ? MPPE_STATELESS : 0);
596+ p[3] = 0;
597+ p[4] = 0;
598+ p[5] = (go->mppe_40 ? MPPE_40BIT : 0) | (go->mppe_56 ? MPPE_56BIT : 0) |
599+ (go->mppe_128 ? MPPE_128BIT : 0) | (go->mppc ? MPPE_MPPC : 0);
600+
601+ BCOPY(p, opt_buf, CILEN_MPPE);
602     BCOPY(mppe_recv_key, &opt_buf[CILEN_MPPE], MPPE_MAX_KEY_LEN);
603     res = ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0);
604- if (res > 0)
605+ if (res > 0) {
606         p += CILEN_MPPE;
607- else
608+ } else {
609         /* This shouldn't happen, we've already tested it! */
610- lcp_close(f->unit, "MPPE required but not available in kernel");
611+ go->mppe = go->mppe_40 = go->mppe_56 = go->mppe_128 =
612+ go->mppe_stateless = go->mppc = 0;
613+ if (ccp_wantoptions[f->unit].mppe)
614+ lcp_close(f->unit, "MPPE required but not available in kernel");
615+ }
616+ }
617+#endif /* MPPE */
618+ if (go->lzs) {
619+ p[0] = CI_LZS;
620+ p[1] = CILEN_LZS;
621+ p[2] = go->lzs_hists >> 8;
622+ p[3] = go->lzs_hists & 0xff;
623+ p[4] = LZS_MODE_SEQ;
624+ res = ccp_test(f->unit, p, CILEN_LZS, 0);
625+ if (res > 0) {
626+ p += CILEN_LZS;
627+ } else
628+ go->lzs = 0;
629     }
630-#endif
631     if (go->deflate) {
632     p[0] = go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT;
633     p[1] = CILEN_DEFLATE;
634@@ -802,7 +961,7 @@ ccp_addci(f, p, lenp)
635 
636 /*
637  * ccp_ackci - process a received configure-ack, and return
638- * 1 iff the packet was OK.
639+ * 1 if the packet was OK.
640  */
641 static int
642 ccp_ackci(f, p, len)
643@@ -811,24 +970,44 @@ ccp_ackci(f, p, len)
644     int len;
645 {
646     ccp_options *go = &ccp_gotoptions[f->unit];
647+ ccp_options *ao = &ccp_allowoptions[f->unit];
648+ ccp_options *wo = &ccp_wantoptions[f->unit];
649     u_char *p0 = p;
650 
651 #ifdef MPPE
652- if (go->mppe) {
653- u_char opt_buf[CILEN_MPPE];
654-
655- opt_buf[0] = CI_MPPE;
656- opt_buf[1] = CILEN_MPPE;
657- MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
658- if (len < CILEN_MPPE || memcmp(opt_buf, p, CILEN_MPPE))
659+ if (go->mppe || go->mppc || (!wo->mppe && ao->mppe)) {
660+ if (len < CILEN_MPPE
661+ || p[1] != CILEN_MPPE || p[0] != CI_MPPE
662+ || p[2] != (go->mppe_stateless ? MPPE_STATELESS : 0)
663+ || p[3] != 0
664+ || p[4] != 0
665+ || (p[5] != ((go->mppe_40 ? MPPE_40BIT : 0) |
666+ (go->mppc ? MPPE_MPPC : 0))
667+ && p[5] != ((go->mppe_56 ? MPPE_56BIT : 0) |
668+ (go->mppc ? MPPE_MPPC : 0))
669+ && p[5] != ((go->mppe_128 ? MPPE_128BIT : 0) |
670+ (go->mppc ? MPPE_MPPC : 0))))
671         return 0;
672+ if (go->mppe_40 || go->mppe_56 || go->mppe_128)
673+ go->mppe = 1;
674     p += CILEN_MPPE;
675     len -= CILEN_MPPE;
676+ /* Cope with first/fast ack */
677+ if (p == p0 && len == 0)
678+ return 1;
679+ }
680+#endif /* MPPE */
681+ if (go->lzs) {
682+ if (len < CILEN_LZS || p[0] != CI_LZS || p[1] != CILEN_LZS
683+ || p[2] != go->lzs_hists>>8 || p[3] != (go->lzs_hists&0xff)
684+ || p[4] != LZS_MODE_SEQ)
685+ return 0;
686+ p += CILEN_LZS;
687+ len -= CILEN_LZS;
688     /* XXX Cope with first/fast ack */
689- if (len == 0)
690+ if (p == p0 && len == 0)
691         return 1;
692     }
693-#endif
694     if (go->deflate) {
695     if (len < CILEN_DEFLATE
696         || p[0] != (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
697@@ -901,6 +1080,8 @@ ccp_nakci(f, p, len, treat_as_reject)
698     int treat_as_reject;
699 {
700     ccp_options *go = &ccp_gotoptions[f->unit];
701+ ccp_options *ao = &ccp_allowoptions[f->unit];
702+ ccp_options *wo = &ccp_wantoptions[f->unit];
703     ccp_options no; /* options we've seen already */
704     ccp_options try; /* options to ask for next time */
705 
706@@ -908,28 +1089,100 @@ ccp_nakci(f, p, len, treat_as_reject)
707     try = *go;
708 
709 #ifdef MPPE
710- if (go->mppe && len >= CILEN_MPPE
711- && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
712- no.mppe = 1;
713- /*
714- * Peer wants us to use a different strength or other setting.
715- * Fail if we aren't willing to use his suggestion.
716- */
717- MPPE_CI_TO_OPTS(&p[2], try.mppe);
718- if ((try.mppe & MPPE_OPT_STATEFUL) && refuse_mppe_stateful) {
719- error("Refusing MPPE stateful mode offered by peer");
720- try.mppe = 0;
721- } else if (((go->mppe | MPPE_OPT_STATEFUL) & try.mppe) != try.mppe) {
722- /* Peer must have set options we didn't request (suggest) */
723- try.mppe = 0;
724- }
725+ if ((go->mppe || go->mppc || (!wo->mppe && ao->mppe)) &&
726+ len >= CILEN_MPPE && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
727 
728- if (!try.mppe) {
729- error("MPPE required but peer negotiation failed");
730- lcp_close(f->unit, "MPPE required but peer negotiation failed");
731+ if (go->mppc) {
732+ no.mppc = 1;
733+ if (!(p[5] & MPPE_MPPC))
734+ try.mppc = 0;
735+ }
736+
737+ if (go->mppe)
738+ no.mppe = 1;
739+ if (go->mppe_40)
740+ no.mppe_40 = 1;
741+ if (go->mppe_56)
742+ no.mppe_56 = 1;
743+ if (go->mppe_128)
744+ no.mppe_128 = 1;
745+ if (go->mppe_stateless)
746+ no.mppe_stateless = 1;
747+
748+ if (ao->mppe_40) {
749+ if ((p[5] & MPPE_40BIT))
750+ try.mppe_40 = 1;
751+ else
752+ try.mppe_40 = (p[5] == 0) ? 1 : 0;
753+ }
754+ if (ao->mppe_56) {
755+ if ((p[5] & MPPE_56BIT))
756+ try.mppe_56 = 1;
757+ else
758+ try.mppe_56 = (p[5] == 0) ? 1 : 0;
759+ }
760+ if (ao->mppe_128) {
761+ if ((p[5] & MPPE_128BIT))
762+ try.mppe_128 = 1;
763+ else
764+ try.mppe_128 = (p[5] == 0) ? 1 : 0;
765+ }
766+
767+ if (ao->mppe_stateless) {
768+ if ((p[2] & MPPE_STATELESS) || wo->mppe_stateless)
769+ try.mppe_stateless = 1;
770+ else
771+ try.mppe_stateless = 0;
772+ }
773+
774+ if (!try.mppe_56 && !try.mppe_40 && !try.mppe_128) {
775+ try.mppe = try.mppe_stateless = 0;
776+ if (wo->mppe) {
777+ /* we require encryption, but peer doesn't support it
778+ so we close connection */
779+ wo->mppc = wo->mppe = wo->mppe_stateless = wo->mppe_40 =
780+ wo->mppe_56 = wo->mppe_128 = 0;
781+ lcp_close(f->unit, "MPPE required but cannot negotiate MPPE "
782+ "key length");
783+ }
784+ }
785+ if (wo->mppe && (wo->mppe_40 != try.mppe_40) &&
786+ (wo->mppe_56 != try.mppe_56) && (wo->mppe_128 != try.mppe_128)) {
787+ /* cannot negotiate key length */
788+ wo->mppc = wo->mppe = wo->mppe_stateless = wo->mppe_40 =
789+ wo->mppe_56 = wo->mppe_128 = 0;
790+ lcp_close(f->unit, "Cannot negotiate MPPE key length");
791     }
792+ if (try.mppe_40 && try.mppe_56 && try.mppe_128)
793+ try.mppe_40 = try.mppe_56 = 0;
794+ else
795+ if (try.mppe_56 && try.mppe_128)
796+ try.mppe_56 = 0;
797+ else
798+ if (try.mppe_40 && try.mppe_128)
799+ try.mppe_40 = 0;
800+ else
801+ if (try.mppe_40 && try.mppe_56)
802+ try.mppe_40 = 0;
803+
804+ p += CILEN_MPPE;
805+ len -= CILEN_MPPE;
806     }
807 #endif /* MPPE */
808+
809+ if (go->lzs && len >= CILEN_LZS && p[0] == CI_LZS && p[1] == CILEN_LZS) {
810+ no.lzs = 1;
811+ if (((p[2]<<8)|p[3]) > 1 || (p[4] != LZS_MODE_SEQ &&
812+ p[4] != LZS_MODE_EXT))
813+ try.lzs = 0;
814+ else {
815+ try.lzs_mode = p[4];
816+ try.lzs_hists = (p[2] << 8) | p[3];
817+ }
818+ p += CILEN_LZS;
819+ len -= CILEN_LZS;
820+ }
821+
822     if (go->deflate && len >= CILEN_DEFLATE
823     && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
824     && p[1] == CILEN_DEFLATE) {
825@@ -1002,14 +1255,50 @@ ccp_rejci(f, p, len)
826     return -1;
827 
828 #ifdef MPPE
829- if (go->mppe && len >= CILEN_MPPE
830+ if ((go->mppe || go->mppc) && len >= CILEN_MPPE
831     && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
832- error("MPPE required but peer refused");
833- lcp_close(f->unit, "MPPE required but peer refused");
834+ ccp_options *wo = &ccp_wantoptions[f->unit];
835+ if (p[2] != (go->mppe_stateless ? MPPE_STATELESS : 0) ||
836+ p[3] != 0 ||
837+ p[4] != 0 ||
838+ p[5] != ((go->mppe_40 ? MPPE_40BIT : 0) |
839+ (go->mppe_56 ? MPPE_56BIT : 0) |
840+ (go->mppe_128 ? MPPE_128BIT : 0) |
841+ (go->mppc ? MPPE_MPPC : 0)))
842+ return 0;
843+ if (go->mppc)
844+ try.mppc = 0;
845+ if (go->mppe) {
846+ try.mppe = 0;
847+ if (go->mppe_40)
848+ try.mppe_40 = 0;
849+ if (go->mppe_56)
850+ try.mppe_56 = 0;
851+ if (go->mppe_128)
852+ try.mppe_128 = 0;
853+ if (go->mppe_stateless)
854+ try.mppe_stateless = 0;
855+ if (!try.mppe_56 && !try.mppe_40 && !try.mppe_128)
856+ try.mppe = try.mppe_stateless = 0;
857+ if (wo->mppe) { /* we want MPPE but cannot negotiate key length */
858+ wo->mppc = wo->mppe = wo->mppe_stateless = wo->mppe_40 =
859+ wo->mppe_56 = wo->mppe_128 = 0;
860+ lcp_close(f->unit, "MPPE required but cannot negotiate MPPE "
861+ "key length");
862+ }
863+ }
864     p += CILEN_MPPE;
865     len -= CILEN_MPPE;
866     }
867-#endif
868+#endif /* MPPE */
869+ if (go->lzs && len >= CILEN_LZS && p[0] == CI_LZS && p[1] == CILEN_LZS) {
870+ if (p[2] != go->lzs_hists>>8 || p[3] != (go->lzs_hists&0xff)
871+ || p[4] != go->lzs_mode)
872+ return 0;
873+ try.lzs = 0;
874+ p += CILEN_LZS;
875+ len -= CILEN_LZS;
876+ }
877     if (go->deflate_correct && len >= CILEN_DEFLATE
878     && p[0] == CI_DEFLATE && p[1] == CILEN_DEFLATE) {
879     if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
880@@ -1073,14 +1362,15 @@ ccp_reqci(f, p, lenp, dont_nak)
881     int dont_nak;
882 {
883     int ret, newret, res;
884- u_char *p0, *retp;
885+ u_char *p0, *retp, p2, p5;
886     int len, clen, type, nb;
887     ccp_options *ho = &ccp_hisoptions[f->unit];
888     ccp_options *ao = &ccp_allowoptions[f->unit];
889+ ccp_options *wo = &ccp_wantoptions[f->unit];
890 #ifdef MPPE
891- bool rej_for_ci_mppe = 1; /* Are we rejecting based on a bad/missing */
892- /* CI_MPPE, or due to other options? */
893-#endif
894+ u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];
895+/* int mtu; */
896+#endif /* MPPE */
897 
898     ret = CONFACK;
899     retp = p0 = p;
900@@ -1103,106 +1393,302 @@ ccp_reqci(f, p, lenp, dont_nak)
901         switch (type) {
902 #ifdef MPPE
903         case CI_MPPE:
904- if (!ao->mppe || clen != CILEN_MPPE) {
905+ if ((!ao->mppc && !ao->mppe) || clen != CILEN_MPPE) {
906             newret = CONFREJ;
907             break;
908         }
909- MPPE_CI_TO_OPTS(&p[2], ho->mppe);
910-
911- /* Nak if anything unsupported or unknown are set. */
912- if (ho->mppe & MPPE_OPT_UNSUPPORTED) {
913- newret = CONFNAK;
914- ho->mppe &= ~MPPE_OPT_UNSUPPORTED;
915- }
916- if (ho->mppe & MPPE_OPT_UNKNOWN) {
917+ p2 = p[2];
918+ p5 = p[5];
919+ /* not sure what they want, tell 'em what we got */
920+ if (((p[2] & ~MPPE_STATELESS) != 0 || p[3] != 0 || p[4] != 0 ||
921+ (p[5] & ~(MPPE_40BIT | MPPE_56BIT | MPPE_128BIT |
922+ MPPE_MPPC)) != 0 || p[5] == 0) ||
923+ (p[2] == 0 && p[3] == 0 && p[4] == 0 && p[5] == 0)) {
924             newret = CONFNAK;
925- ho->mppe &= ~MPPE_OPT_UNKNOWN;
926- }
927-
928- /* Check state opt */
929- if (ho->mppe & MPPE_OPT_STATEFUL) {
930- /*
931- * We can Nak and request stateless, but it's a
932- * lot easier to just assume the peer will request
933- * it if he can do it; stateful mode is bad over
934- * the Internet -- which is where we expect MPPE.
935- */
936- if (refuse_mppe_stateful) {
937- error("Refusing MPPE stateful mode offered by peer");
938- newret = CONFREJ;
939- break;
940+ p[2] = (wo->mppe_stateless ? MPPE_STATELESS : 0);
941+ p[3] = 0;
942+ p[4] = 0;
943+ p[5] = (wo->mppe_40 ? MPPE_40BIT : 0) |
944+ (wo->mppe_56 ? MPPE_56BIT : 0) |
945+ (wo->mppe_128 ? MPPE_128BIT : 0) |
946+ (wo->mppc ? MPPE_MPPC : 0);
947+ break;
948+ }
949+
950+ if ((p[5] & MPPE_MPPC)) {
951+ if (ao->mppc) {
952+ ho->mppc = 1;
953+ BCOPY(p, opt_buf, CILEN_MPPE);
954+ opt_buf[2] = opt_buf[3] = opt_buf[4] = 0;
955+ opt_buf[5] = MPPE_MPPC;
956+ if (ccp_test(f->unit, opt_buf, CILEN_MPPE, 1) <= 0) {
957+ ho->mppc = 0;
958+ p[5] &= ~MPPE_MPPC;
959+ newret = CONFNAK;
960+ }
961+ } else {
962+ newret = CONFREJ;
963+ if (wo->mppe || ao->mppe) {
964+ p[5] &= ~MPPE_MPPC;
965+ newret = CONFNAK;
966+ }
967             }
968         }
969-
970- /* Find out which of {S,L} are set. */
971- if ((ho->mppe & MPPE_OPT_128)
972- && (ho->mppe & MPPE_OPT_40)) {
973- /* Both are set, negotiate the strongest. */
974- newret = CONFNAK;
975- if (ao->mppe & MPPE_OPT_128)
976- ho->mppe &= ~MPPE_OPT_40;
977- else if (ao->mppe & MPPE_OPT_40)
978- ho->mppe &= ~MPPE_OPT_128;
979- else {
980- newret = CONFREJ;
981- break;
982- }
983- } else if (ho->mppe & MPPE_OPT_128) {
984- if (!(ao->mppe & MPPE_OPT_128)) {
985- newret = CONFREJ;
986- break;
987- }
988- } else if (ho->mppe & MPPE_OPT_40) {
989- if (!(ao->mppe & MPPE_OPT_40)) {
990- newret = CONFREJ;
991- break;
992- }
993+ if (ao->mppe)
994+ ho->mppe = 1;
995+
996+ if ((p[2] & MPPE_STATELESS)) {
997+ if (ao->mppe_stateless) {
998+ if (wo->mppe_stateless)
999+ ho->mppe_stateless = 1;
1000+ else {
1001+ newret = CONFNAK;
1002+ if (!dont_nak)
1003+ p[2] &= ~MPPE_STATELESS;
1004+ }
1005+ } else {
1006+ newret = CONFNAK;
1007+ if (!dont_nak)
1008+ p[2] &= ~MPPE_STATELESS;
1009+ }
1010+ } else {
1011+ if (wo->mppe_stateless && !dont_nak) {
1012+ wo->mppe_stateless = 0;
1013+ newret = CONFNAK;
1014+ p[2] |= MPPE_STATELESS;
1015+ }
1016+ }
1017+
1018+ if ((p[5] & ~MPPE_MPPC) == (MPPE_40BIT|MPPE_56BIT|MPPE_128BIT)) {
1019+ newret = CONFNAK;
1020+ if (ao->mppe_128) {
1021+ ho->mppe_128 = 1;
1022+ p[5] &= ~(MPPE_40BIT|MPPE_56BIT);
1023+ BCOPY(p, opt_buf, CILEN_MPPE);
1024+ BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
1025+ MPPE_MAX_KEY_LEN);
1026+ if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
1027+ MPPE_MAX_KEY_LEN, 1) <= 0) {
1028+ ho->mppe_128 = 0;
1029+ p[5] |= (MPPE_40BIT|MPPE_56BIT);
1030+ p[5] &= ~MPPE_128BIT;
1031+ goto check_mppe_56_40;
1032+ }
1033+ goto check_mppe;
1034+ }
1035+ p[5] &= ~MPPE_128BIT;
1036+ goto check_mppe_56_40;
1037+ }
1038+ if ((p[5] & ~MPPE_MPPC) == (MPPE_56BIT|MPPE_128BIT)) {
1039+ newret = CONFNAK;
1040+ if (ao->mppe_128) {
1041+ ho->mppe_128 = 1;
1042+ p[5] &= ~MPPE_56BIT;
1043+ BCOPY(p, opt_buf, CILEN_MPPE);
1044+ BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
1045+ MPPE_MAX_KEY_LEN);
1046+ if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
1047+ MPPE_MAX_KEY_LEN, 1) <= 0) {
1048+ ho->mppe_128 = 0;
1049+ p[5] |= MPPE_56BIT;
1050+ p[5] &= ~MPPE_128BIT;
1051+ goto check_mppe_56;
1052+ }
1053+ goto check_mppe;
1054+ }
1055+ p[5] &= ~MPPE_128BIT;
1056+ goto check_mppe_56;
1057+ }
1058+ if ((p[5] & ~MPPE_MPPC) == (MPPE_40BIT|MPPE_128BIT)) {
1059+ newret = CONFNAK;
1060+ if (ao->mppe_128) {
1061+ ho->mppe_128 = 1;
1062+ p[5] &= ~MPPE_40BIT;
1063+ BCOPY(p, opt_buf, CILEN_MPPE);
1064+ BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
1065+ MPPE_MAX_KEY_LEN);
1066+ if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
1067+ MPPE_MAX_KEY_LEN, 1) <= 0) {
1068+ ho->mppe_128 = 0;
1069+ p[5] |= MPPE_40BIT;
1070+ p[5] &= ~MPPE_128BIT;
1071+ goto check_mppe_40;
1072+ }
1073+ goto check_mppe;
1074+ }
1075+ p[5] &= ~MPPE_128BIT;
1076+ goto check_mppe_40;
1077+ }
1078+ if ((p[5] & ~MPPE_MPPC) == MPPE_128BIT) {
1079+ if (ao->mppe_128) {
1080+ ho->mppe_128 = 1;
1081+ BCOPY(p, opt_buf, CILEN_MPPE);
1082+ BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
1083+ MPPE_MAX_KEY_LEN);
1084+ if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
1085+ MPPE_MAX_KEY_LEN, 1) <= 0) {
1086+ ho->mppe_128 = 0;
1087+ p[5] &= ~MPPE_128BIT;
1088+ newret = CONFNAK;
1089+ }
1090+ goto check_mppe;
1091+ }
1092+ p[5] &= ~MPPE_128BIT;
1093+ newret = CONFNAK;
1094+ goto check_mppe;
1095+ }
1096+ check_mppe_56_40:
1097+ if ((p[5] & ~MPPE_MPPC) == (MPPE_40BIT|MPPE_56BIT)) {
1098+ newret = CONFNAK;
1099+ if (ao->mppe_56) {
1100+ ho->mppe_56 = 1;
1101+ p[5] &= ~MPPE_40BIT;
1102+ BCOPY(p, opt_buf, CILEN_MPPE);
1103+ BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
1104+ MPPE_MAX_KEY_LEN);
1105+ if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
1106+ MPPE_MAX_KEY_LEN, 1) <= 0) {
1107+ ho->mppe_56 = 0;
1108+ p[5] |= MPPE_40BIT;
1109+ p[5] &= ~MPPE_56BIT;
1110+ newret = CONFNAK;
1111+ goto check_mppe_40;
1112+ }
1113+ goto check_mppe;
1114+ }
1115+ p[5] &= ~MPPE_56BIT;
1116+ goto check_mppe_40;
1117+ }
1118+ check_mppe_56:
1119+ if ((p[5] & ~MPPE_MPPC) == MPPE_56BIT) {
1120+ if (ao->mppe_56) {
1121+ ho->mppe_56 = 1;
1122+ BCOPY(p, opt_buf, CILEN_MPPE);
1123+ BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
1124+ MPPE_MAX_KEY_LEN);
1125+ if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
1126+ MPPE_MAX_KEY_LEN, 1) <= 0) {
1127+ ho->mppe_56 = 0;
1128+ p[5] &= ~MPPE_56BIT;
1129+ newret = CONFNAK;
1130+ }
1131+ goto check_mppe;
1132+ }
1133+ p[5] &= ~MPPE_56BIT;
1134+ newret = CONFNAK;
1135+ goto check_mppe;
1136+ }
1137+ check_mppe_40:
1138+ if ((p[5] & ~MPPE_MPPC) == MPPE_40BIT) {
1139+ if (ao->mppe_40) {
1140+ ho->mppe_40 = 1;
1141+ BCOPY(p, opt_buf, CILEN_MPPE);
1142+ BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
1143+ MPPE_MAX_KEY_LEN);
1144+ if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
1145+ MPPE_MAX_KEY_LEN, 1) <= 0) {
1146+ ho->mppe_40 = 0;
1147+ p[5] &= ~MPPE_40BIT;
1148+ newret = CONFNAK;
1149+ }
1150+ goto check_mppe;
1151+ }
1152+ p[5] &= ~MPPE_40BIT;
1153+ }
1154+
1155+ check_mppe:
1156+ if (!ho->mppe_40 && !ho->mppe_56 && !ho->mppe_128) {
1157+ if (wo->mppe_40 || wo->mppe_56 || wo->mppe_128) {
1158+ newret = CONFNAK;
1159+ p[2] |= (wo->mppe_stateless ? MPPE_STATELESS : 0);
1160+ p[5] |= (wo->mppe_40 ? MPPE_40BIT : 0) |
1161+ (wo->mppe_56 ? MPPE_56BIT : 0) |
1162+ (wo->mppe_128 ? MPPE_128BIT : 0) |
1163+ (wo->mppc ? MPPE_MPPC : 0);
1164+ } else {
1165+ ho->mppe = ho->mppe_stateless = 0;
1166+ }
1167         } else {
1168- /* Neither are set. */
1169- /* We cannot accept this. */
1170- newret = CONFNAK;
1171- /* Give the peer our idea of what can be used,
1172- so it can choose and confirm */
1173- ho->mppe = ao->mppe;
1174- }
1175-
1176- /* rebuild the opts */
1177- MPPE_OPTS_TO_CI(ho->mppe, &p[2]);
1178- if (newret == CONFACK) {
1179- u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];
1180- int mtu;
1181-
1182- BCOPY(p, opt_buf, CILEN_MPPE);
1183- BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
1184- MPPE_MAX_KEY_LEN);
1185- if (ccp_test(f->unit, opt_buf,
1186- CILEN_MPPE + MPPE_MAX_KEY_LEN, 1) <= 0) {
1187- /* This shouldn't happen, we've already tested it! */
1188- error("MPPE required, but kernel has no support.");
1189- lcp_close(f->unit, "MPPE required but not available");
1190- newret = CONFREJ;
1191- break;
1192- }
1193- /*
1194- * We need to decrease the interface MTU by MPPE_PAD
1195- * because MPPE frames **grow**. The kernel [must]
1196- * allocate MPPE_PAD extra bytes in xmit buffers.
1197- */
1198- mtu = netif_get_mtu(f->unit);
1199- if (mtu)
1200- netif_set_mtu(f->unit, mtu - MPPE_PAD);
1201- else
1202- newret = CONFREJ;
1203- }
1204-
1205- /*
1206- * We have accepted MPPE or are willing to negotiate
1207- * MPPE parameters. A CONFREJ is due to subsequent
1208- * (non-MPPE) processing.
1209- */
1210- rej_for_ci_mppe = 0;
1211- break;
1212-#endif /* MPPE */
1213+ /* MPPE is not compatible with other compression types */
1214+ if (wo->mppe) {
1215+ ao->bsd_compress = 0;
1216+ ao->predictor_1 = 0;
1217+ ao->predictor_2 = 0;
1218+ ao->deflate = 0;
1219+ ao->lzs = 0;
1220+ }
1221+ }
1222+ if ((!ho->mppc || !ao->mppc) && !ho->mppe) {
1223+ p[2] = p2;
1224+ p[5] = p5;
1225+ newret = CONFREJ;
1226+ break;
1227+ }
1228+
1229+ /*
1230+ * I have commented the code below because according to RFC1547
1231+ * MTU is only information for higher level protocols about
1232+ * "the maximum allowable length for a packet (q.v.) transmitted
1233+ * over a point-to-point link without incurring network layer
1234+ * fragmentation." Of course a PPP implementation should be able
1235+ * to handle overhead added by MPPE - in our case apropriate code
1236+ * is located in drivers/net/ppp_generic.c in the kernel sources.
1237+ *
1238+ * According to RFC1661:
1239+ * - when negotiated MRU is less than 1500 octets, a PPP
1240+ * implementation must still be able to receive at least 1500
1241+ * octets,
1242+ * - when PFC is negotiated, a PPP implementation is still
1243+ * required to receive frames with uncompressed protocol field.
1244+ *
1245+ * So why not to handle MPPE overhead without changing MTU value?
1246+ * I am sure that RFC3078, unfortunately silently, assumes that.
1247+ */
1248+
1249+ /*
1250+ * We need to decrease the interface MTU by MPPE_PAD
1251+ * because MPPE frames **grow**. The kernel [must]
1252+ * allocate MPPE_PAD extra bytes in xmit buffers.
1253+ */
1254+ /*
1255+ mtu = netif_get_mtu(f->unit);
1256+ if (mtu) {
1257+ netif_set_mtu(f->unit, mtu - MPPE_PAD);
1258+ } else {
1259+ newret = CONFREJ;
1260+ if (ccp_wantoptions[f->unit].mppe) {
1261+ error("Cannot adjust MTU needed by MPPE.");
1262+ lcp_close(f->unit, "Cannot adjust MTU needed by MPPE.");
1263+ }
1264+ }
1265+ */
1266+ break;
1267+ #endif /* MPPE */
1268+
1269+ case CI_LZS:
1270+ if (!ao->lzs || clen != CILEN_LZS) {
1271+ newret = CONFREJ;
1272+ break;
1273+ }
1274+
1275+ ho->lzs = 1;
1276+ ho->lzs_hists = (p[2] << 8) | p[3];
1277+ ho->lzs_mode = p[4];
1278+ if ((ho->lzs_hists != ao->lzs_hists) ||
1279+ (ho->lzs_mode != ao->lzs_mode)) {
1280+ newret = CONFNAK;
1281+ if (!dont_nak) {
1282+ p[2] = ao->lzs_hists >> 8;
1283+ p[3] = ao->lzs_hists & 0xff;
1284+ p[4] = ao->lzs_mode;
1285+ } else
1286+ break;
1287+ }
1288+
1289+ if (p == p0 && ccp_test(f->unit, p, CILEN_LZS, 1) <= 0) {
1290+ newret = CONFREJ;
1291+ }
1292+ break;
1293         case CI_DEFLATE:
1294         case CI_DEFLATE_DRAFT:
1295         if (!ao->deflate || clen != CILEN_DEFLATE
1296@@ -1344,12 +1830,6 @@ ccp_reqci(f, p, lenp, dont_nak)
1297     else
1298         *lenp = retp - p0;
1299     }
1300-#ifdef MPPE
1301- if (ret == CONFREJ && ao->mppe && rej_for_ci_mppe) {
1302- error("MPPE required but peer negotiation failed");
1303- lcp_close(f->unit, "MPPE required but peer negotiation failed");
1304- }
1305-#endif
1306     return ret;
1307 }
1308 
1309@@ -1371,24 +1851,35 @@ method_name(opt, opt2)
1310     char *p = result;
1311     char *q = result + sizeof(result); /* 1 past result */
1312 
1313- slprintf(p, q - p, "MPPE ");
1314- p += 5;
1315- if (opt->mppe & MPPE_OPT_128) {
1316- slprintf(p, q - p, "128-bit ");
1317- p += 8;
1318- }
1319- if (opt->mppe & MPPE_OPT_40) {
1320- slprintf(p, q - p, "40-bit ");
1321- p += 7;
1322- }
1323- if (opt->mppe & MPPE_OPT_STATEFUL)
1324- slprintf(p, q - p, "stateful");
1325- else
1326- slprintf(p, q - p, "stateless");
1327-
1328+ if (opt->mppe) {
1329+ if (opt->mppc) {
1330+ slprintf(p, q - p, "MPPC/MPPE ");
1331+ p += 10;
1332+ } else {
1333+ slprintf(p, q - p, "MPPE ");
1334+ p += 5;
1335+ }
1336+ if (opt->mppe_128) {
1337+ slprintf(p, q - p, "128-bit ");
1338+ p += 8;
1339+ } else if (opt->mppe_56) {
1340+ slprintf(p, q - p, "56-bit ");
1341+ p += 7;
1342+ } else if (opt->mppe_40) {
1343+ slprintf(p, q - p, "40-bit ");
1344+ p += 7;
1345+ }
1346+ if (opt->mppe_stateless)
1347+ slprintf(p, q - p, "stateless");
1348+ else
1349+ slprintf(p, q - p, "stateful");
1350+ } else if (opt->mppc)
1351+ slprintf(p, q - p, "MPPC");
1352     break;
1353     }
1354-#endif
1355+#endif /* MPPE */
1356+ case CI_LZS:
1357+ return "Stac LZS";
1358     case CI_DEFLATE:
1359     case CI_DEFLATE_DRAFT:
1360     if (opt2 != NULL && opt2->deflate_size != opt->deflate_size)
1361@@ -1444,12 +1935,12 @@ ccp_up(f)
1362     } else if (ANY_COMPRESS(*ho))
1363     notice("%s transmit compression enabled", method_name(ho, NULL));
1364 #ifdef MPPE
1365- if (go->mppe) {
1366+ if (go->mppe || go->mppc) {
1367     BZERO(mppe_recv_key, MPPE_MAX_KEY_LEN);
1368     BZERO(mppe_send_key, MPPE_MAX_KEY_LEN);
1369     continue_networks(f->unit); /* Bring up IP et al */
1370     }
1371-#endif
1372+#endif /* MPPE */
1373 }
1374 
1375 /*
1376@@ -1472,7 +1963,7 @@ ccp_down(f)
1377         lcp_close(f->unit, "MPPE disabled");
1378     }
1379     }
1380-#endif
1381+#endif /* MPPE */
1382 }
1383 
1384 /*
1385@@ -1532,24 +2023,28 @@ ccp_printpkt(p, plen, printer, arg)
1386 #ifdef MPPE
1387         case CI_MPPE:
1388         if (optlen >= CILEN_MPPE) {
1389- u_char mppe_opts;
1390-
1391- MPPE_CI_TO_OPTS(&p[2], mppe_opts);
1392- printer(arg, "mppe %s %s %s %s %s %s%s",
1393- (p[2] & MPPE_H_BIT)? "+H": "-H",
1394- (p[5] & MPPE_M_BIT)? "+M": "-M",
1395- (p[5] & MPPE_S_BIT)? "+S": "-S",
1396- (p[5] & MPPE_L_BIT)? "+L": "-L",
1397+ printer(arg, "mppe %s %s %s %s %s %s",
1398+ (p[2] & MPPE_STATELESS)? "+H": "-H",
1399+ (p[5] & MPPE_56BIT)? "+M": "-M",
1400+ (p[5] & MPPE_128BIT)? "+S": "-S",
1401+ (p[5] & MPPE_40BIT)? "+L": "-L",
1402                 (p[5] & MPPE_D_BIT)? "+D": "-D",
1403- (p[5] & MPPE_C_BIT)? "+C": "-C",
1404- (mppe_opts & MPPE_OPT_UNKNOWN)? " +U": "");
1405- if (mppe_opts & MPPE_OPT_UNKNOWN)
1406+ (p[5] & MPPE_MPPC)? "+C": "-C");
1407+ if ((p[5] & ~(MPPE_56BIT | MPPE_128BIT | MPPE_40BIT |
1408+ MPPE_D_BIT | MPPE_MPPC)) ||
1409+ (p[2] & ~MPPE_STATELESS))
1410             printer(arg, " (%.2x %.2x %.2x %.2x)",
1411                 p[2], p[3], p[4], p[5]);
1412             p += CILEN_MPPE;
1413         }
1414         break;
1415-#endif
1416+#endif /* MPPE */
1417+ case CI_LZS:
1418+ if (optlen >= CILEN_LZS) {
1419+ printer(arg, "lzs %.2x %.2x %.2x", p[2], p[3], p[4]);
1420+ p += CILEN_LZS;
1421+ }
1422+ break;
1423         case CI_DEFLATE:
1424         case CI_DEFLATE_DRAFT:
1425         if (optlen >= CILEN_DEFLATE) {
1426@@ -1635,6 +2130,7 @@ ccp_datainput(unit, pkt, len)
1427         error("Lost compression sync: disabling compression");
1428         ccp_close(unit, "Lost compression sync");
1429 #ifdef MPPE
1430+ /* My module dosn't need this. J.D., 2003-07-06 */
1431         /*
1432          * If we were doing MPPE, we must also take the link down.
1433          */
1434@@ -1642,9 +2138,18 @@ ccp_datainput(unit, pkt, len)
1435         error("Too many MPPE errors, closing LCP");
1436         lcp_close(unit, "Too many MPPE errors");
1437         }
1438-#endif
1439+#endif /* MPPE */
1440     } else {
1441         /*
1442+ * When LZS or MPPE/MPPC is negotiated we just send CCP_RESETREQ
1443+ * and don't wait for CCP_RESETACK
1444+ */
1445+ if ((ccp_gotoptions[f->unit].method == CI_LZS) ||
1446+ (ccp_gotoptions[f->unit].method == CI_MPPE)) {
1447+ fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0);
1448+ return;
1449+ }
1450+ /*
1451          * Send a reset-request to reset the peer's compressor.
1452          * We don't do that if we are still waiting for an
1453          * acknowledgement to a previous reset-request.
1454--- a/pppd/ccp.h
1455+++ b/pppd/ccp.h
1456@@ -37,9 +37,17 @@ typedef struct ccp_options {
1457     bool predictor_2; /* do Predictor-2? */
1458     bool deflate_correct; /* use correct code for deflate? */
1459     bool deflate_draft; /* use draft RFC code for deflate? */
1460+ bool lzs; /* do Stac LZS? */
1461+ bool mppc; /* do MPPC? */
1462     bool mppe; /* do MPPE? */
1463+ bool mppe_40; /* allow 40 bit encryption? */
1464+ bool mppe_56; /* allow 56 bit encryption? */
1465+ bool mppe_128; /* allow 128 bit encryption? */
1466+ bool mppe_stateless; /* allow stateless encryption */
1467     u_short bsd_bits; /* # bits/code for BSD Compress */
1468     u_short deflate_size; /* lg(window size) for Deflate */
1469+ u_short lzs_mode; /* LZS check mode */
1470+ u_short lzs_hists; /* number of LZS histories */
1471     short method; /* code for chosen compression method */
1472 } ccp_options;
1473 
1474--- a/pppd/chap_ms.c
1475+++ b/pppd/chap_ms.c
1476@@ -898,13 +898,17 @@ set_mppe_enc_types(int policy, int types
1477     /*
1478      * Disable undesirable encryption types. Note that we don't ENABLE
1479      * any encryption types, to avoid overriding manual configuration.
1480+ *
1481+ * It seems that 56 bit keys are unsupported in MS-RADIUS (see RFC 2548)
1482      */
1483     switch(types) {
1484     case MPPE_ENC_TYPES_RC4_40:
1485- ccp_wantoptions[0].mppe &= ~MPPE_OPT_128; /* disable 128-bit */
1486+ ccp_wantoptions[0].mppe_128 = 0; /* disable 128-bit */
1487+ ccp_wantoptions[0].mppe_56 = 0; /* disable 56-bit */
1488         break;
1489     case MPPE_ENC_TYPES_RC4_128:
1490- ccp_wantoptions[0].mppe &= ~MPPE_OPT_40; /* disable 40-bit */
1491+ ccp_wantoptions[0].mppe_56 = 0; /* disable 56-bit */
1492+ ccp_wantoptions[0].mppe_40 = 0; /* disable 40-bit */
1493         break;
1494     default:
1495         break;
1496

Archive Download this file



interactive