| 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 |
--- 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 |
| 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) |
| 719 |
@@ -901,6 +1080,8 @@ |
| 720 |
int treat_as_reject; |
| 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 |
|
| 728 |
@@ -908,28 +1089,100 @@ |
| 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) { |
| 847 |
@@ -1002,14 +1255,50 @@ |
| 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) |
| 902 |
@@ -1073,14 +1362,15 @@ |
| 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; |
| 922 |
@@ -1103,106 +1393,307 @@ |
| 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. */ |
| 1184 |
- /* We cannot accept this. */ |
| 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 = CONFNAK; |
| 1198 |
/* Give the peer our idea of what can be used, |
| 1199 |
so it can choose and confirm */ |
| 1200 |
ho->mppe = ao->mppe; |
| 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 |
| 1303 |
@@ -1344,12 +1835,6 @@ |
| 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 |
|
| 1316 |
@@ -1371,24 +1856,35 @@ |
| 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) |
| 1368 |
@@ -1444,12 +1940,12 @@ |
| 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 |
/* |
| 1383 |
@@ -1472,7 +1968,7 @@ |
| 1384 |
lcp_close(f->unit, "MPPE disabled"); |
| 1385 |
} |
| 1386 |
} |
| 1387 |
-#endif |
| 1388 |
+#endif /* MPPE */ |
| 1389 |
} |
| 1390 |
|
| 1391 |
/* |
| 1392 |
@@ -1532,24 +2028,28 @@ |
| 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) { |
| 1433 |
@@ -1635,6 +2135,7 @@ |
| 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 |
*/ |
| 1441 |
@@ -1642,9 +2143,18 @@ |
| 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. |
| 1461 |
@@ -1675,4 +2185,3 @@ |
| 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 |