]> git.ozlabs.org Git - ppp.git/blobdiff - linux/mppe/ppp_mppe_compress.c
Fix the argument type in call to MD5_Update properly
[ppp.git] / linux / mppe / ppp_mppe_compress.c
index efdb5d15e95af072a6f8b8a1a571760c8fdd2cb1..051213273970fa4affb73b00d68c0c1bafe1945e 100644 (file)
@@ -1,11 +1,9 @@
 /*
- *  ==FILEVERSION 20020320==
- *
  * ppp_mppe_compress.c - interface MPPE to the PPP code.
- * This version is for use with Linux kernel 2.2.19+ and 2.4.x.
+ * This version is for use with Linux kernel 2.2.19+, 2.4.18+ and 2.6.2+.
  *
  * By Frank Cusack <frank@google.com>.
- * Copyright (c) 2002 Google, Inc.
+ * Copyright (c) 2002,2003,2004 Google, Inc.
  * All rights reserved.
  *
  * Permission to use, copy, modify, and distribute this software and its
  * notice appears in all copies.  This software is provided without any
  * warranty, express or implied.
  *
+ * Changelog:
+ *      2/15/04 - TS: added #include <version.h> and testing for Kernel
+ *                    version before using 
+ *                    MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are
+ *                    deprecated in 2.6
  */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/slab.h>
@@ -62,13 +66,8 @@ typedef struct ppp_mppe_state {
 #define MPPE_CCOUNT(p) ((((p)[4] & 0x0f) << 8) + (p)[5])
 #define MPPE_CCOUNT_SPACE 0x1000       /* The size of the ccount space */
 
-/*
- * MPPE overhead/packet.
- * Note that we use this differently than other compressors.
- */
 #define MPPE_OVHD      2               /* MPPE overhead/packet */
-/* Max bogon factor we will tolerate */
-#define SANITY_MAX     1600
+#define SANITY_MAX     1600            /* Max bogon factor we will tolerate */
 
 static void    GetNewKeyFromSHA __P((unsigned char *StartKey,
                                      unsigned char *SessionKey,
@@ -175,7 +174,11 @@ mppe_alloc(unsigned char *options, int optlen)
     if (state == NULL)
        return NULL;
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+    try_module_get(THIS_MODULE);
+#else
     MOD_INC_USE_COUNT;
+#endif
     memset(state, 0, sizeof(*state));
 
     /* Save keys. */
@@ -199,7 +202,11 @@ mppe_free(void *arg)
 
     if (state) {
        kfree(state);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+       module_put(THIS_MODULE);
+#else
        MOD_DEC_USE_COUNT;
+#endif
     }
 }
 
@@ -236,17 +243,17 @@ mppe_init(void *arg, unsigned char *options, int optlen, int unit, int debug,
 
     if (debug) {
        int i;
-       char mkey[sizeof(state->master_key) * 3 + 1];
-       char skey[sizeof(state->session_key) * 3 + 1];
+       char mkey[sizeof(state->master_key) * 2 + 1];
+       char skey[sizeof(state->session_key) * 2 + 1];
 
        printk(KERN_DEBUG "%s[%d]: initialized with %d-bit %s mode\n", debugstr,
               unit, (state->keylen == 16)? 128: 40,
               (state->stateful)? "stateful": "stateless");
 
        for (i = 0; i < sizeof(state->master_key); i++)
-           sprintf(mkey + i * 2, "%.2x ", state->master_key[i]);
+           sprintf(mkey + i * 2, "%.2x", state->master_key[i]);
        for (i = 0; i < sizeof(state->session_key); i++)
-           sprintf(skey + i * 2, "%.2x ", state->session_key[i]);
+           sprintf(skey + i * 2, "%.2x", state->session_key[i]);
        printk(KERN_DEBUG "%s[%d]: keys: master: %s initial session: %s\n",
               debugstr, unit, mkey, skey);
     }
@@ -338,6 +345,9 @@ mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
     obuf += PPP_HDRLEN;
 
     state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
+    if (state->debug >= 7)
+       printk(KERN_DEBUG "mppe_compress[%d]: ccount %d\n", state->unit,
+              state->ccount);
     obuf[0] = state->ccount >> 8;
     obuf[1] = state->ccount & 0xff;
 
@@ -417,12 +427,25 @@ mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
                   state->unit, isize);
        return DECOMP_ERROR;
     }
-    /* Strange ... our output size is always LESS than the input size. */
-    /* assert(osize >= isize - MPPE_OVHD - 2); */
 
-    osize = isize - MPPE_OVHD - 2;
+    /*
+     * Make sure we have enough room to decrypt the packet.
+     * Note that for our test we only subtract 1 byte whereas in
+     * mppe_compress() we added 2 bytes (+MPPE_OVHD);
+     * this is to account for possible PFC.
+     */
+    if (osize < isize - MPPE_OVHD - 1) {
+       printk(KERN_DEBUG "mppe_decompress[%d]: osize too small! "
+              "(have: %d need: %d)\n", state->unit,
+              osize, isize - MPPE_OVHD - 1);
+       return DECOMP_ERROR;
+    }
+    osize = isize - MPPE_OVHD - 2;     /* assume no PFC */
 
     ccount = MPPE_CCOUNT(ibuf);
+    if (state->debug >= 7)
+       printk(KERN_DEBUG "mppe_decompress[%d]: ccount %d\n", state->unit,
+              ccount);
 
     /* sanity checks -- terminate with extreme prejudice */
     if (!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) {
@@ -513,14 +536,32 @@ mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
      * comes from the decrypted data.
      */
     obuf[0] = PPP_ADDRESS(ibuf);       /* +1 */
-    obuf[1] = PPP_CONTROL(ibuf);       /* +2 */
+    obuf[1] = PPP_CONTROL(ibuf);       /* +1 */
     obuf  += 2;
     ibuf  += PPP_HDRLEN + MPPE_OVHD;
     isize -= PPP_HDRLEN + MPPE_OVHD;   /* -6 */
-                                       /* net: -4 */
+                                       /* net osize: isize-4 */
+
+    /*
+     * Decrypt the first byte in order to check if it is
+     * a compressed or uncompressed protocol field.
+     */
+    arcfour_decrypt(&state->arcfour_context, ibuf, 1, obuf);
+
+    /*
+     * Do PFC decompression.
+     * This would be nicer if we were given the actual sk_buff
+     * instead of a char *.
+     */
+    if ((obuf[0] & 0x01) != 0) {
+       obuf[1] = obuf[0];
+       obuf[0] = 0;
+       obuf++;
+       osize++;
+    }
 
-    /* And finally, decrypt the packet. */
-    arcfour_decrypt(&state->arcfour_context, ibuf, isize, obuf);
+    /* And finally, decrypt the rest of the packet. */
+    arcfour_decrypt(&state->arcfour_context, ibuf + 1, isize - 1, obuf + 1);
 
     state->stats.unc_bytes += osize;
     state->stats.unc_packets++;