/* * allocsymkey - common code to allocate and link in symkey * * secret must be allocated with a free-compatible allocator. It is * owned by the referring symkey structure, and will be free()d by * freesymkey(). */ static void allocsymkey( symkey ** bucket, keyid_t id, u_short flags, u_short type, u_long lifetime, u_short secretsize, uint8_t * secret ) { symkey * sk; if (authnumfreekeys < 1) auth_moremem(-1); UNLINK_HEAD_SLIST(sk, authfreekeys, llink.f); DEBUG_ENSURE(sk != NULL); sk->keyid = id; sk->flags = flags; sk->type = type; sk->secretsize = secretsize; sk->secret = secret; sk->lifetime = lifetime; LINK_SLIST(*bucket, sk, hlink); LINK_TAIL_DLIST(key_listhead, sk, llink); authnumfreekeys--; authnumkeys++; }
/* * auth_prealloc_symkeys */ void auth_prealloc_symkeys( int keycount ) { int allocated; int additional; allocated = authnumkeys + authnumfreekeys; additional = keycount - allocated; if (additional > 0) auth_moremem(additional); auth_resize_hashtable(); }
void MD5auth_setkey( keyid_t keyno, int keytype, const u_char *key, size_t len ) { struct savekey *sk; /* * See if we already have the key. If so just stick in the * new value. */ sk = key_hash[KEYHASH(keyno)]; while (sk != NULL) { if (keyno == sk->keyid) { sk->type = keytype; sk->keylen = min(len, sizeof(sk->k.MD5_key)); #ifndef DISABLE_BUG1243_FIX memcpy(sk->k.MD5_key, key, sk->keylen); #else strncpy((char *)sk->k.MD5_key, (const char *)key, sizeof(sk->k.MD5_key)); #endif if (cache_keyid == keyno) { cache_flags = 0; cache_keyid = 0; } return; } sk = sk->next; } /* * Need to allocate new structure. Do it. */ if (0 == authnumfreekeys && !auth_moremem()) return; sk = authfreekeys; authfreekeys = sk->next; authnumfreekeys--; sk->keyid = keyno; sk->type = keytype; sk->flags = 0; sk->lifetime = 0; sk->keylen = min(len, sizeof(sk->k.MD5_key)); #ifndef DISABLE_BUG1243_FIX memcpy(sk->k.MD5_key, key, sk->keylen); #else strncpy((char *)sk->k.MD5_key, (const char *)key, sizeof(sk->k.MD5_key)); #endif sk->next = key_hash[KEYHASH(keyno)]; key_hash[KEYHASH(keyno)] = sk; #ifdef DEBUG if (debug > 1) { char hex[] = "0123456789abcdef"; int j; printf("auth_setkey: key %d type %d len %d ", sk->keyid, sk->type, sk->keylen); for (j = 0; j < sk->keylen; j++) printf("%c%c", hex[key[j] >> 4], hex[key[j] & 0xf]); printf("\n"); }
/* * authtrust - declare a key to be trusted/untrusted */ void authtrust( keyid_t keyno, u_long trust ) { struct savekey *sk; /* * Search bin for key; if it does not exist and is untrusted, * forget it. */ sk = key_hash[KEYHASH(keyno)]; while (sk != 0) { if (keyno == sk->keyid) break; sk = sk->next; } if (sk == 0 && !trust) 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 != 0) { if (cache_keyid == keyno) { cache_flags = 0; cache_keyid = 0; } /* * Key exists. If it is to be trusted, say so and * update its lifetime. If not, return it to the * free list. */ if (trust > 0) { sk->flags |= KEY_TRUSTED; if (trust > 1) sk->lifetime = current_time + trust; else sk->lifetime = 0; return; } sk->flags &= ~KEY_TRUSTED; { struct savekey *skp; skp = key_hash[KEYHASH(keyno)]; if (skp == sk) { key_hash[KEYHASH(keyno)] = sk->next; } else { while (skp->next != sk) skp = skp->next; skp->next = sk->next; } authnumkeys--; sk->next = authfreekeys; authfreekeys = sk; authnumfreekeys++; } return; } /* * Here there is not key, but the key is to be trusted. There * seems to be a disconnect here. Here we allocate a new key, * but do not specify a key type, key or key length. */ if (authnumfreekeys == 0) if (auth_moremem() == 0) return; sk = authfreekeys; authfreekeys = sk->next; authnumfreekeys--; sk->keyid = keyno; sk->type = 0; sk->keylen = 0; sk->flags = KEY_TRUSTED; sk->next = key_hash[KEYHASH(keyno)]; key_hash[KEYHASH(keyno)] = sk; authnumkeys++; return; }