From a9fd0810d2425f9e0936c3c52903d73e9e74a6ab Mon Sep 17 00:00:00 2001 From: Heimdal Developers Date: Mon, 25 Feb 2013 23:00:46 +0000 Subject: [PATCH] Import of code from heimdal 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 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- src/external/heimdal-last | 2 +- src/external/heimdal/krb5/config_file.c | 13 +- src/external/heimdal/krb5/crypto-evp.c | 6 +- src/external/heimdal/krb5/crypto.c | 98 ++++++--------- src/external/heimdal/krb5/data.c | 6 +- src/external/heimdal/krb5/keyblock.c | 6 +- src/external/heimdal/krb5/n-fold.c | 145 ++++++++++++---------- src/external/heimdal/roken/roken-common.h | 4 + src/external/heimdal/roken/socket.c | 23 ++++ 9 files changed, 149 insertions(+), 154 deletions(-) diff --git a/src/external/heimdal-last b/src/external/heimdal-last index 461108f53..5a8fadd2b 100644 --- a/src/external/heimdal-last +++ b/src/external/heimdal-last @@ -1 +1 @@ -4a438db29d361b7e5f47b86ced1482a96cde86ea +66f4c441e9e0de68fbcf81763642779ac5c33631 diff --git a/src/external/heimdal/krb5/config_file.c b/src/external/heimdal/krb5/config_file.c index 00b3d6d58..debfd35b2 100644 --- a/src/external/heimdal/krb5/config_file.c +++ b/src/external/heimdal/krb5/config_file.c @@ -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 } diff --git a/src/external/heimdal/krb5/crypto-evp.c b/src/external/heimdal/krb5/crypto-evp.c index e8fb1caf6..cab7c2906 100644 --- a/src/external/heimdal/krb5/crypto-evp.c +++ b/src/external/heimdal/krb5/crypto-evp.c @@ -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); diff --git a/src/external/heimdal/krb5/crypto.c b/src/external/heimdal/krb5/crypto.c index ae7aa21a8..2565cc26a 100644 --- a/src/external/heimdal/krb5/crypto.c +++ b/src/external/heimdal/krb5/crypto.c @@ -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 diff --git a/src/external/heimdal/krb5/data.c b/src/external/heimdal/krb5/data.c index f62a5532a..0a6677de9 100644 --- a/src/external/heimdal/krb5/data.c +++ b/src/external/heimdal/krb5/data.c @@ -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); diff --git a/src/external/heimdal/krb5/keyblock.c b/src/external/heimdal/krb5/keyblock.c index 6e781aca7..abca3ee05 100644 --- a/src/external/heimdal/krb5/keyblock.c +++ b/src/external/heimdal/krb5/keyblock.c @@ -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) { diff --git a/src/external/heimdal/krb5/n-fold.c b/src/external/heimdal/krb5/n-fold.c index 2e6092c5c..ba3150d42 100644 --- a/src/external/heimdal/krb5/n-fold.c +++ b/src/external/heimdal/krb5/n-fold.c @@ -32,68 +32,79 @@ #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; } diff --git a/src/external/heimdal/roken/roken-common.h b/src/external/heimdal/roken/roken-common.h index a819d510d..02122be49 100644 --- a/src/external/heimdal/roken/roken-common.h +++ b/src/external/heimdal/roken/roken-common.h @@ -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); diff --git a/src/external/heimdal/roken/socket.c b/src/external/heimdal/roken/socket.c index 017d6252e..65aea15b5 100644 --- a/src/external/heimdal/roken/socket.c +++ b/src/external/heimdal/roken/socket.c @@ -259,6 +259,29 @@ socket_set_tos (rk_socket_t sock, int tos) #endif } +/* + * 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'. */ -- 2.39.5