]>
Commit | Line | Data |
---|---|---|
1b28c30e JK |
1 | diff -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 @@ | |
ea686db0 JP |
32 | #define CI_MPPE 18 /* config option for MPPE */ |
33 | #define CILEN_MPPE 6 /* length of config option */ | |
1b28c30e JK |
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 | */ | |
65 | diff -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 @@ | |
ea686db0 JP |
69 | #define CI_MPPE 18 /* config option for MPPE */ |
70 | #define CILEN_MPPE 6 /* length of config option */ | |
1b28c30e JK |
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 | ||
1435 | diff -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; | |
1458 | diff -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 |