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