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