void MD5auth_setkey( keyid_t keyno, int keytype, const uint8_t *key, size_t len ) { symkey * sk; symkey ** bucket; uint8_t * secret; size_t secretsize; DEBUG_ENSURE(keytype <= USHRT_MAX); DEBUG_ENSURE(len < 4 * 1024); /* * See if we already have the key. If so just stick in the * new value. */ bucket = &key_hash[KEYHASH(keyno)]; for (sk = *bucket; sk != NULL; sk = sk->hlink) { if (keyno == sk->keyid) { sk->type = (u_short)keytype; secretsize = len; sk->secretsize = (u_short)secretsize; free(sk->secret); sk->secret = emalloc(secretsize); memcpy(sk->secret, key, secretsize); if (cache_keyid == keyno) { cache_flags = 0; cache_keyid = 0; } return; } } /* * Need to allocate new structure. Do it. */ secretsize = len; secret = emalloc(secretsize); memcpy(secret, key, secretsize); allocsymkey(bucket, keyno, 0, (u_short)keytype, 0, (u_short)secretsize, secret); #ifdef DEBUG if (debug >= 4) { size_t j; printf("auth_setkey: key %d type %d len %d ", (int)keyno, keytype, (int)secretsize); for (j = 0; j < secretsize; j++) printf("%02x", secret[j]); printf("\n"); } #endif }
/* * authtrust - declare a key to be trusted/untrusted */ void authtrust( keyid_t id, u_long trust ) { symkey ** bucket; symkey * sk; u_long lifetime; /* * Search bin for key; if it does not exist and is untrusted, * forget it. */ bucket = &key_hash[KEYHASH(id)]; for (sk = *bucket; sk != NULL; sk = sk->hlink) { if (id == sk->keyid) break; } if (!trust && NULL == sk) return; /* * There are two conditions remaining. Either it does not * exist and is to be trusted or it does exist and is or is * not to be trusted. */ if (sk != NULL) { if (cache_keyid == id) { cache_flags = 0; cache_keyid = 0; } /* * Key exists. If it is to be trusted, say so and * update its lifetime. */ if (trust > 0) { sk->flags |= KEY_TRUSTED; if (trust > 1) sk->lifetime = current_time + trust; else sk->lifetime = 0; return; } /* No longer trusted, return it to the free list. */ freesymkey(sk, bucket); return; } /* * keyid is not present, but the is to be trusted. We allocate * a new key, but do not specify a key type or secret. */ if (trust > 1) { lifetime = current_time + trust; } else { lifetime = 0; } allocsymkey(bucket, id, KEY_TRUSTED, 0, lifetime, 0, NULL); }
/* Note: There are two locations below where 'strncpy()' is used. While * this function is a hazard by itself, it's essential that it is used * here. Bug 1243 involved that the secret was filled with NUL bytes * after the first NUL encountered, and 'strlcpy()' simply does NOT have * this behaviour. So disabling the fix and reverting to the buggy * behaviour due to compatibility issues MUST also fill with NUL and * this needs 'strncpy'. Also, the secret is managed as a byte blob of a * given size, and eventually truncating it and replacing the last byte * with a NUL would be a bug. * [email protected] 2015-10-10 */ void MD5auth_setkey( keyid_t keyno, int keytype, const u_char *key, size_t len, KeyAccT *ka ) { symkey * sk; symkey ** bucket; u_char * secret; size_t secretsize; DEBUG_ENSURE(keytype <= USHRT_MAX); DEBUG_ENSURE(len < 4 * 1024); /* * See if we already have the key. If so just stick in the * new value. */ bucket = &key_hash[KEYHASH(keyno)]; for (sk = *bucket; sk != NULL; sk = sk->hlink) { if (keyno == sk->keyid) { /* TALOS-CAN-0054: make sure we have a new buffer! */ if (NULL != sk->secret) { memset(sk->secret, 0, sk->secretsize); free(sk->secret); } sk->secret = emalloc(len); sk->type = (u_short)keytype; secretsize = len; sk->secretsize = (u_short)secretsize; sk->keyacclist = ka; #ifndef DISABLE_BUG1243_FIX memcpy(sk->secret, key, secretsize); #else /* >MUST< use 'strncpy()' here! See above! */ strncpy((char *)sk->secret, (const char *)key, secretsize); #endif if (cache_keyid == keyno) { cache_flags = 0; cache_keyid = 0; cache_keyacclist = NULL; } return; } } /* * Need to allocate new structure. Do it. */ secretsize = len; secret = emalloc(secretsize); #ifndef DISABLE_BUG1243_FIX memcpy(secret, key, secretsize); #else /* >MUST< use 'strncpy()' here! See above! */ strncpy((char *)secret, (const char *)key, secretsize); #endif allocsymkey(bucket, keyno, 0, (u_short)keytype, 0, (u_short)secretsize, secret, ka); #ifdef DEBUG if (debug >= 4) { size_t j; printf("auth_setkey: key %d type %d len %d ", (int)keyno, keytype, (int)secretsize); for (j = 0; j < secretsize; j++) printf("%02x", secret[j]); printf("\n"); } #endif }