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