Import of code from heimdal
authorHeimdal Developers <heimdal-discuss@sics.se>
Mon, 25 Feb 2013 23:00:46 +0000 (23:00 +0000)
committerDerrick Brashear <shadow@your-file-system.com>
Tue, 26 Feb 2013 11:50:57 +0000 (03:50 -0800)
This commit updates the code imported from heimdal to
66f4c441e9e0de68fbcf81763642779ac5c33631 (git2svn-syncpoint-master-199-g66f4c44)

Upstream changes are:

Kumar Thangavelu (1):
      unning "kinit --fast-armor-cache=xxx" against a Win2K3 domain resulted in a crash with the attached backtrace. FAST is not supported with RC4 keys which are used in Win2K3. The code already handles this but the error code is not propagated up the stack.

Love Hornquist Astrand (1):
      add socket_set_nonblocking

Roland C. Dowdeswell (3):
      Optimise _krb5_n_fold() a bit.
      Use krb5_enomem() more consistently in lib/krb5.
      Further improvements to lib/krb5/n-fold.c:

Change-Id: I3b652e3ea3c84a939c4988bc8c24b3edee06446f
Reviewed-on: http://gerrit.openafs.org/9264
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
Reviewed-by: Derrick Brashear <shadow@your-file-system.com>
Tested-by: Derrick Brashear <shadow@your-file-system.com>

src/external/heimdal-last
src/external/heimdal/krb5/config_file.c
src/external/heimdal/krb5/crypto-evp.c
src/external/heimdal/krb5/crypto.c
src/external/heimdal/krb5/data.c
src/external/heimdal/krb5/keyblock.c
src/external/heimdal/krb5/n-fold.c
src/external/heimdal/roken/roken-common.h
src/external/heimdal/roken/socket.c

index 461108f..5a8fadd 100644 (file)
@@ -1 +1 @@
-4a438db29d361b7e5f47b86ced1482a96cde86ea
+66f4c441e9e0de68fbcf81763642779ac5c33631
index 00b3d6d..debfd35 100644 (file)
@@ -447,21 +447,14 @@ krb5_config_parse_file_multi (krb5_context context,
            int aret;
 
            aret = asprintf(&newfname, "%s%s", home, &fname[1]);
-           if (aret == -1 || newfname == NULL) {
-               krb5_set_error_message(context, ENOMEM,
-                                      N_("malloc: out of memory", ""));
-               return ENOMEM;
-           }
+           if (aret == -1 || newfname == NULL)
+               return krb5_enomem(context);
            fname = newfname;
        }
 #else  /* KRB5_USE_PATH_TOKENS */
        if (asprintf(&newfname, "%%{USERCONFIG}%s", &fname[1]) < 0 ||
            newfname == NULL)
-       {
-           krb5_set_error_message(context, ENOMEM,
-                                  N_("malloc: out of memory", ""));
-           return ENOMEM;
-       }
+           return krb5_enomem(context);
        fname = newfname;
 #endif
     }
index e8fb1ca..cab7c29 100644 (file)
@@ -72,10 +72,8 @@ _krb5_evp_encrypt(krb5_context context,
        /* alloca ? */
        size_t len2 = EVP_CIPHER_CTX_iv_length(c);
        void *loiv = malloc(len2);
-       if (loiv == NULL) {
-           krb5_clear_error_message(context);
-           return ENOMEM;
-       }
+       if (loiv == NULL)
+           return krb5_enomem(context);
        memset(loiv, 0, len2);
        EVP_CipherInit_ex(c, NULL, NULL, NULL, loiv, -1);
        free(loiv);
index ae7aa21..2565cc2 100644 (file)
@@ -147,10 +147,8 @@ _key_schedule(krb5_context context,
     if (key->schedule != NULL)
        return 0;
     ALLOC(key->schedule, 1);
-    if(key->schedule == NULL) {
-       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-       return ENOMEM;
-    }
+    if (key->schedule == NULL)
+       return krb5_enomem(context);
     ret = krb5_data_alloc(key->schedule, kt->schedule_size);
     if(ret) {
        free(key->schedule);
@@ -325,10 +323,8 @@ get_checksum_key(krb5_context context,
        size_t i;
 
        *key = _new_derived_key(crypto, 0xff/* KRB5_KU_RFC1510_VARIANT */);
-       if(*key == NULL) {
-           krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-           return ENOMEM;
-       }
+       if (*key == NULL)
+           return krb5_enomem(context);
        ret = krb5_copy_keyblock(context, crypto->key.key, &(*key)->key);
        if(ret)
            return ret;
@@ -666,10 +662,8 @@ krb5_enctype_to_string(krb5_context context,
        return KRB5_PROG_ETYPE_NOSUPP;
     }
     *string = strdup(e->name);
-    if(*string == NULL) {
-       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-       return ENOMEM;
-    }
+    if (*string == NULL)
+       return krb5_enomem(context);
     return 0;
 }
 
@@ -836,10 +830,8 @@ encrypt_internal_derived(krb5_context context,
     block_sz = (sz + et->padsize - 1) &~ (et->padsize - 1); /* pad */
     total_sz = block_sz + checksum_sz;
     p = calloc(1, total_sz);
-    if(p == NULL) {
-       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-       return ENOMEM;
-    }
+    if (p == NULL)
+       return krb5_enomem(context);
 
     q = p;
     krb5_generate_random_block(q, et->confoundersize); /* XXX */
@@ -900,10 +892,8 @@ encrypt_internal(krb5_context context,
     sz = et->confoundersize + checksum_sz + len;
     block_sz = (sz + et->padsize - 1) &~ (et->padsize - 1); /* pad */
     p = calloc(1, block_sz);
-    if(p == NULL) {
-       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-       return ENOMEM;
-    }
+    if (p == NULL)
+       return krb5_enomem(context);
 
     q = p;
     krb5_generate_random_block(q, et->confoundersize); /* XXX */
@@ -962,10 +952,8 @@ encrypt_internal_special(krb5_context context,
     krb5_error_code ret;
 
     tmp = malloc (sz);
-    if (tmp == NULL) {
-       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-       return ENOMEM;
-    }
+    if (tmp == NULL)
+       return krb5_enomem(context);
     p = tmp;
     memset (p, 0, cksum_sz);
     p += cksum_sz;
@@ -1014,10 +1002,8 @@ decrypt_internal_derived(krb5_context context,
     }
 
     p = malloc(len);
-    if(len != 0 && p == NULL) {
-       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-       return ENOMEM;
-    }
+    if (len != 0 && p == NULL)
+       return krb5_enomem(context);
     memcpy(p, data, len);
 
     len -= checksum_sz;
@@ -1057,8 +1043,7 @@ decrypt_internal_derived(krb5_context context,
     result->data = realloc(p, l);
     if(result->data == NULL && l != 0) {
        free(p);
-       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-       return ENOMEM;
+       return krb5_enomem(context);
     }
     result->length = l;
     return 0;
@@ -1091,10 +1076,8 @@ decrypt_internal(krb5_context context,
     }
 
     p = malloc(len);
-    if(len != 0 && p == NULL) {
-       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-       return ENOMEM;
-    }
+    if (len != 0 && p == NULL)
+       return krb5_enomem(context);
     memcpy(p, data, len);
 
     ret = _key_schedule(context, &crypto->key);
@@ -1125,8 +1108,7 @@ decrypt_internal(krb5_context context,
     result->data = realloc(p, l);
     if(result->data == NULL && l != 0) {
        free(p);
-       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-       return ENOMEM;
+       return krb5_enomem(context);
     }
     result->length = l;
     return 0;
@@ -1159,10 +1141,8 @@ decrypt_internal_special(krb5_context context,
     }
 
     p = malloc (len);
-    if (p == NULL) {
-       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-       return ENOMEM;
-    }
+    if (p == NULL)
+       return krb5_enomem(context);
     memcpy(p, data, len);
 
     ret = (*et->encrypt)(context, &crypto->key, p, len, FALSE, usage, ivec);
@@ -1175,8 +1155,7 @@ decrypt_internal_special(krb5_context context,
     result->data = realloc(p, sz);
     if(result->data == NULL && sz != 0) {
        free(p);
-       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-       return ENOMEM;
+       return krb5_enomem(context);
     }
     result->length = sz;
     return 0;
@@ -1864,13 +1843,12 @@ _krb5_derive_key(krb5_context context,
        nblocks = (kt->bits + et->blocksize * 8 - 1) / (et->blocksize * 8);
        k = malloc(nblocks * et->blocksize);
        if(k == NULL) {
-           ret = ENOMEM;
-           krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+           ret = krb5_enomem(context);
            goto out;
        }
        ret = _krb5_n_fold(constant, len, k, et->blocksize);
        if (ret) {
-           krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+           krb5_enomem(context);
            goto out;
        }
 
@@ -1888,8 +1866,7 @@ _krb5_derive_key(krb5_context context,
        size_t res_len = (kt->bits + 7) / 8;
 
        if(len != 0 && c == NULL) {
-           ret = ENOMEM;
-           krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+           ret = krb5_enomem(context);
            goto out;
        }
        memcpy(c, constant, len);
@@ -1897,14 +1874,13 @@ _krb5_derive_key(krb5_context context,
        k = malloc(res_len);
        if(res_len != 0 && k == NULL) {
            free(c);
-           ret = ENOMEM;
-           krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+           ret = krb5_enomem(context);
            goto out;
        }
        ret = _krb5_n_fold(c, len, k, res_len);
        free(c);
        if (ret) {
-           krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+           krb5_enomem(context);
            goto out;
        }
     }
@@ -1998,10 +1974,8 @@ _get_derived_key(krb5_context context,
            return 0;
        }
     d = _new_derived_key(crypto, usage);
-    if(d == NULL) {
-       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-       return ENOMEM;
-    }
+    if (d == NULL)
+       return krb5_enomem(context);
     krb5_copy_keyblock(context, crypto->key.key, &d->key);
     _krb5_put_int(constant, usage, 5);
     _krb5_derive_key(context, crypto->et, d, constant, sizeof(constant));
@@ -2035,10 +2009,8 @@ krb5_crypto_init(krb5_context context,
 {
     krb5_error_code ret;
     ALLOC(*crypto, 1);
-    if(*crypto == NULL) {
-       krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
-       return ENOMEM;
-    }
+    if (*crypto == NULL)
+       return krb5_enomem(context);
     if(etype == (krb5_enctype)ETYPE_NULL)
        etype = key->keytype;
     (*crypto)->et = _krb5_find_enctype(etype);
@@ -2542,7 +2514,7 @@ krb5_crypto_prfplus(krb5_context context,
     krb5_data_free(&input2);
     if (ret)
        krb5_data_free(output);
-    return 0;
+    return ret;
 }
 
 /**
@@ -2575,6 +2547,8 @@ krb5_crypto_fx_cf2(krb5_context context,
     size_t i, keysize;
 
     memset(res, 0, sizeof(*res));
+    krb5_data_zero(&os1);
+    krb5_data_zero(&os2);
 
     ret = krb5_enctype_keysize(context, enctype, &keysize);
     if (ret)
@@ -2639,10 +2613,8 @@ krb5_keytype_to_enctypes (krb5_context context,
     }
 
     ret = malloc(n * sizeof(*ret));
-    if (ret == NULL && n != 0) {
-       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
-       return ENOMEM;
-    }
+    if (ret == NULL && n != 0)
+       return krb5_enomem(context);
     n = 0;
     for (i = _krb5_num_etypes - 1; i >= 0; --i) {
        if (_krb5_etypes[i]->keytype->type == keytype
index f62a553..0a6677d 100644 (file)
@@ -176,10 +176,8 @@ krb5_copy_data(krb5_context context,
 {
     krb5_error_code ret;
     ALLOC(*outdata, 1);
-    if(*outdata == NULL) {
-       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
-       return ENOMEM;
-    }
+    if(*outdata == NULL)
+       return krb5_enomem(context);
     ret = der_copy_octet_string(indata, *outdata);
     if(ret) {
        krb5_clear_error_message (context);
index 6e781ac..abca3ee 100644 (file)
@@ -135,10 +135,8 @@ krb5_copy_keyblock (krb5_context context,
     *to = NULL;
 
     k = calloc (1, sizeof(*k));
-    if (k == NULL) {
-       krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
-       return ENOMEM;
-    }
+    if (k == NULL)
+       return krb5_enomem(context);
 
     ret = krb5_copy_keyblock_contents (context, inblock, k);
     if (ret) {
index 2e6092c..ba3150d 100644 (file)
 
 #include "krb5_locl.h"
 
-static krb5_error_code
-rr13(unsigned char *buf, size_t len)
+static void
+rr13(uint8_t *dst1, uint8_t *dst2, uint8_t *src, size_t len)
 {
-    unsigned char *tmp;
     int bytes = (len + 7) / 8;
     int i;
-    if(len == 0)
-       return 0;
-    {
-       const int bits = 13 % len;
-       const int lbit = len % 8;
-
-       tmp = malloc(bytes);
-       if (tmp == NULL)
-           return ENOMEM;
-       memcpy(tmp, buf, bytes);
-       if(lbit) {
-           /* pad final byte with inital bits */
-           tmp[bytes - 1] &= 0xff << (8 - lbit);
-           for(i = lbit; i < 8; i += len)
-               tmp[bytes - 1] |= buf[0] >> i;
-       }
-       for(i = 0; i < bytes; i++) {
-           int bb;
-           int b1, s1, b2, s2;
-           /* calculate first bit position of this byte */
-           bb = 8 * i - bits;
-           while(bb < 0)
-               bb += len;
-           /* byte offset and shift count */
-           b1 = bb / 8;
-           s1 = bb % 8;
-
-           if(bb + 8 > bytes * 8)
-               /* watch for wraparound */
-               s2 = (len + 8 - s1) % 8;
-           else
-               s2 = 8 - s1;
-           b2 = (b1 + 1) % bytes;
-           buf[i] = (tmp[b1] << s1) | (tmp[b2] >> s2);
-       }
-       free(tmp);
+    const int bits = 13 % len;
+
+    for (i = 0; i < bytes; i++) {
+       int bb;
+       int b1, s1, b2, s2;
+       /* calculate first bit position of this byte */
+       bb = 8 * i - bits;
+       while(bb < 0)
+           bb += len;
+       /* byte offset and shift count */
+       b1 = bb / 8;
+       s1 = bb % 8;
+
+       if (bb + 8 > bytes * 8)
+           /* watch for wraparound */
+           s2 = (len + 8 - s1) % 8;
+       else
+           s2 = 8 - s1;
+       b2 = (b1 + 1) % bytes;
+       dst1[i] = (src[b1] << s1) | (src[b2] >> s2);
+       dst2[i] = dst1[i];
     }
-    return 0;
+
+    return;
 }
 
-/* Add `b' to `a', both being one's complement numbers. */
+/*
+ * Add `b' to `a', both being one's complement numbers.
+ * This function assumes that inputs *a, *b are aligned
+ * to 4 bytes.
+ */
 static void
-add1(unsigned char *a, unsigned char *b, size_t len)
+add1(uint8_t *a, uint8_t *b, size_t len)
 {
     int i;
     int carry = 0;
-    for(i = len - 1; i >= 0; i--){
-       int x = a[i] + b[i] + carry;
+    uint32_t x;
+    uint32_t left, right;
+
+    for (i = len - 1; (i+1) % 4; i--) {
+       x = a[i] + b[i] + carry;
        carry = x > 0xff;
        a[i] = x & 0xff;
     }
-    for(i = len - 1; carry && i >= 0; i--){
-       int x = a[i] + carry;
+
+    for (i = len / 4 - 1; i >= 0; i--) {
+       left = ntohl(((uint32_t *)a)[i]);
+       right = ntohl(((uint32_t *)b)[i]);
+       x = left + right + carry;
+       carry = x < left || x < right;
+       ((uint32_t *)a)[i]  = x;
+    }
+
+    for (i = len - 1; (i+1) % 4; i--) {
+       x = a[i] + carry;
        carry = x > 0xff;
        a[i] = x & 0xff;
     }
+
+    for (i = len / 4 - 1; carry && i >= 0; i--) {
+        left = ((uint32_t *)a)[i];
+        x = left + carry;
+        carry = x < left;
+        ((uint32_t *)a)[i] = x;
+    }
+
+    for (i = len / 4 - 1; i >=0; i--)
+        ((uint32_t *)a)[i] = htonl(((uint32_t *)a)[i]);
 }
 
 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
@@ -101,25 +112,25 @@ _krb5_n_fold(const void *str, size_t len, void *key, size_t size)
 {
     /* if len < size we need at most N * len bytes, ie < 2 * size;
        if len > size we need at most 2 * len */
-    krb5_error_code ret = 0;
     size_t maxlen = 2 * max(size, len);
     size_t l = 0;
-    unsigned char *tmp = malloc(maxlen);
-    unsigned char *buf = malloc(len);
+    uint8_t *tmp;
+    uint8_t *tmpbuf;
+    uint8_t *buf1;
+    uint8_t *buf2;
 
-    if (tmp == NULL || buf == NULL) {
-        ret = ENOMEM;
-       goto out;
-    }
+    tmp = malloc(maxlen + 2 * len);
+    if (tmp == NULL)
+        return ENOMEM;
+
+    buf1 = tmp + maxlen;
+    buf2 = tmp + maxlen + len;
 
-    memcpy(buf, str, len);
     memset(key, 0, size);
+    memcpy(buf1, str, len);
+    memcpy(tmp, buf1, len);
     do {
-       memcpy(tmp + l, buf, len);
        l += len;
-       ret = rr13(buf, len * 8);
-       if (ret)
-           goto out;
        while(l >= size) {
            add1(key, tmp, size);
            l -= size;
@@ -127,15 +138,13 @@ _krb5_n_fold(const void *str, size_t len, void *key, size_t size)
                break;
            memmove(tmp, tmp + size, l);
        }
+       rr13(tmp + l, buf2, buf1, len * 8);
+       tmpbuf = buf1;
+       buf1 = buf2;
+       buf2 = tmpbuf;
     } while(l != 0);
-out:
-    if (buf) {
-        memset(buf, 0, len);
-       free(buf);
-    }
-    if (tmp) {
-        memset(tmp, 0, maxlen);
-       free(tmp);
-    }
-    return ret;
+
+    memset(tmp, 0, maxlen + 2 * len);
+    free(tmp);
+    return 0;
 }
index a819d51..02122be 100644 (file)
@@ -401,6 +401,10 @@ socket_set_debug (rk_socket_t);
 ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
 socket_set_tos (rk_socket_t, int);
 
+#define socket_set_nonblocking rk_socket_set_nonblocking
+ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
+socket_set_nonblocking(rk_socket_t, int);
+
 #define socket_set_reuseaddr rk_socket_set_reuseaddr
 ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
 socket_set_reuseaddr (rk_socket_t, int);
index 017d625..65aea15 100644 (file)
@@ -260,6 +260,29 @@ socket_set_tos (rk_socket_t sock, int tos)
 }
 
 /*
+ * Set the non-blocking-ness of the socket.
+ */
+
+ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
+socket_set_nonblocking(rk_socket_t sock, int nonblock)
+{
+    int flags;
+#if defined(O_NONBLOCK)
+    flags = fcntl(sock, F_GETFL, 0);
+    if (flags == -1)
+       return;
+    if (nonblock)
+       flags |= O_NONBLOCK;
+    else
+       flags &= ~O_NONBLOCK;
+    fcntl(sock, F_SETFL, flags);
+#elif defined(FIOBIO)
+    flags = !!nonblock;
+    return ioctl(sock, FIOBIO, &flags);
+#endif
+}
+
+/*
  * set the reuse of addresses on `sock' to `val'.
  */