| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 | 
							- /*
 
-  * Data structure managing host keys in sessions based on GSSAPI KEX.
 
-  *
 
-  * In a session we started with a GSSAPI key exchange, the concept of
 
-  * 'host key' has completely different lifetime and security semantics
 
-  * from the usual ones. Per RFC 4462 section 2.1, we assume that any
 
-  * host key delivered to us in the course of a GSSAPI key exchange is
 
-  * _solely_ there to use as a transient fallback within the same
 
-  * session, if at the time of a subsequent rekey the GSS credentials
 
-  * are temporarily invalid and so a non-GSS KEX method has to be used.
 
-  *
 
-  * In particular, in a GSS-based SSH deployment, host keys may not
 
-  * even _be_ persistent identities for the server; it would be
 
-  * legitimate for a server to generate a fresh one routinely if it
 
-  * wanted to, like SSH-1 server keys.
 
-  *
 
-  * So, in this mode, we never touch the persistent host key cache at
 
-  * all, either to check keys against it _or_ to store keys in it.
 
-  * Instead, we maintain an in-memory cache of host keys that have been
 
-  * mentioned in GSS key exchanges within this particular session, and
 
-  * we permit precisely those host keys in non-GSS rekeys.
 
-  */
 
- #include <assert.h>
 
- #include "putty.h"
 
- #include "ssh.h"
 
- struct ssh_transient_hostkey_cache {
 
-     tree234 *cache;
 
- };
 
- struct ssh_transient_hostkey_cache_entry {
 
-     const ssh_keyalg *alg;
 
-     strbuf *pub_blob;
 
- };
 
- static int ssh_transient_hostkey_cache_cmp(void *av, void *bv)
 
- {
 
-     const struct ssh_transient_hostkey_cache_entry
 
-         *a = (const struct ssh_transient_hostkey_cache_entry *)av,
 
-         *b = (const struct ssh_transient_hostkey_cache_entry *)bv;
 
-     return strcmp(a->alg->ssh_id, b->alg->ssh_id);
 
- }
 
- static int ssh_transient_hostkey_cache_find(void *av, void *bv)
 
- {
 
-     const ssh_keyalg *aalg = (const ssh_keyalg *)av;
 
-     const struct ssh_transient_hostkey_cache_entry
 
-         *b = (const struct ssh_transient_hostkey_cache_entry *)bv;
 
-     return strcmp(aalg->ssh_id, b->alg->ssh_id);
 
- }
 
- ssh_transient_hostkey_cache *ssh_transient_hostkey_cache_new(void)
 
- {
 
-     ssh_transient_hostkey_cache *thc = snew(ssh_transient_hostkey_cache);
 
-     thc->cache = newtree234(ssh_transient_hostkey_cache_cmp);
 
-     return thc;
 
- }
 
- void ssh_transient_hostkey_cache_free(ssh_transient_hostkey_cache *thc)
 
- {
 
-     struct ssh_transient_hostkey_cache_entry *ent;
 
-     while ((ent = delpos234(thc->cache, 0)) != NULL) {
 
-         strbuf_free(ent->pub_blob);
 
-         sfree(ent);
 
-     }
 
-     freetree234(thc->cache);
 
-     sfree(thc);
 
- }
 
- void ssh_transient_hostkey_cache_add(
 
-     ssh_transient_hostkey_cache *thc, ssh_key *key)
 
- {
 
-     struct ssh_transient_hostkey_cache_entry *ent, *retd;
 
-     if ((ent = find234(thc->cache, (void *)ssh_key_alg(key),
 
-                        ssh_transient_hostkey_cache_find)) != NULL) {
 
-         del234(thc->cache, ent);
 
-         strbuf_free(ent->pub_blob);
 
-         sfree(ent);
 
-     }
 
-     ent = snew(struct ssh_transient_hostkey_cache_entry);
 
-     ent->alg = ssh_key_alg(key);
 
-     ent->pub_blob = strbuf_new();
 
-     ssh_key_public_blob(key, BinarySink_UPCAST(ent->pub_blob));
 
-     retd = add234(thc->cache, ent);
 
-     assert(retd == ent);
 
- }
 
- bool ssh_transient_hostkey_cache_verify(
 
-     ssh_transient_hostkey_cache *thc, ssh_key *key)
 
- {
 
-     struct ssh_transient_hostkey_cache_entry *ent;
 
-     bool toret = false;
 
-     if ((ent = find234(thc->cache, (void *)ssh_key_alg(key),
 
-                        ssh_transient_hostkey_cache_find)) != NULL) {
 
-         strbuf *this_blob = strbuf_new();
 
-         ssh_key_public_blob(key, BinarySink_UPCAST(this_blob));
 
-         if (this_blob->len == ent->pub_blob->len &&
 
-             !memcmp(this_blob->s, ent->pub_blob->s,
 
-                     this_blob->len))
 
-             toret = true;
 
-         strbuf_free(this_blob);
 
-     }
 
-     return toret;
 
- }
 
- bool ssh_transient_hostkey_cache_has(
 
-     ssh_transient_hostkey_cache *thc, const ssh_keyalg *alg)
 
- {
 
-     struct ssh_transient_hostkey_cache_entry *ent =
 
-         find234(thc->cache, (void *)alg,
 
-                 ssh_transient_hostkey_cache_find);
 
-     return ent != NULL;
 
- }
 
- bool ssh_transient_hostkey_cache_non_empty(ssh_transient_hostkey_cache *thc)
 
- {
 
-     return count234(thc->cache) > 0;
 
- }
 
 
  |