Add have_ssh_host_key() and use it to influence algorithm selection.

The general plan is that if PuTTY knows a host key for a server, it
should preferentially ask for the same type of key so that there's some
chance of actually getting the same key again.  This should mean that
when a server (or PuTTY) adds a new host key type, PuTTY doesn't
gratuitously switch to that key type and then warn the user about an
unrecognised key.
This commit is contained in:
Ben Harris 2015-05-29 22:40:50 +01:00
Родитель e222db14ff
Коммит d21041f7f8
4 изменённых файлов: 37 добавлений и 1 удалений

Просмотреть файл

@ -1197,6 +1197,11 @@ void pgp_fingerprints(void);
int verify_ssh_host_key(void *frontend, char *host, int port,
const char *keytype, char *keystr, char *fingerprint,
void (*callback)(void *ctx, int result), void *ctx);
/*
* have_ssh_host_key() just returns true if a key of that type is
* already chached and false otherwise.
*/
int have_ssh_host_key(const char *host, int port, const char *keytype);
/*
* askalg has the same set of return values as verify_ssh_host_key.
*/

13
ssh.c
Просмотреть файл

@ -6350,9 +6350,20 @@ static void do_ssh2_transport(Ssh ssh, const void *vin, int inlen,
if (!s->got_session_id) {
/*
* In the first key exchange, we list all the algorithms
* we're prepared to cope with.
* we're prepared to cope with, but prefer those algorithms
* for which we have a host key for this host.
*/
n = 0;
for (i = 0; i < lenof(hostkey_algs); i++) {
if (have_ssh_host_key(ssh->savedhost, ssh->savedport,
hostkey_algs[i]->keytype)) {
assert(n < MAXKEXLIST);
s->kexlists[KEXLIST_HOSTKEY][n].name =
hostkey_algs[i]->name;
s->kexlists[KEXLIST_HOSTKEY][n].u.hostkey = hostkey_algs[i];
n++;
}
}
for (i = 0; i < lenof(hostkey_algs); i++) {
assert(n < MAXKEXLIST);
s->kexlists[KEXLIST_HOSTKEY][n].name = hostkey_algs[i]->name;

Просмотреть файл

@ -589,6 +589,16 @@ int verify_host_key(const char *hostname, int port,
return ret;
}
int have_ssh_host_key(const char *hostname, int port,
const char *keytype)
{
/*
* If we have a host key, verify_host_key will return 0 or 2.
* If we don't have one, it'll return 1.
*/
return verify_host_key(hostname, port, keytype, "") != 1;
}
void store_host_key(const char *hostname, int port,
const char *keytype, const char *key)
{

Просмотреть файл

@ -454,6 +454,16 @@ int verify_host_key(const char *hostname, int port,
return 0; /* key matched OK in registry */
}
int have_ssh_host_key(const char *hostname, int port,
const char *keytype)
{
/*
* If we have a host key, verify_host_key will return 0 or 2.
* If we don't have one, it'll return 1.
*/
return verify_host_key(hostname, port, keytype, "") != 1;
}
void store_host_key(const char *hostname, int port,
const char *keytype, const char *key)
{