diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2015-01-26 03:04:47 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2015-01-26 03:04:47 +0000 |
commit | eb39409bcc73a02ed00ce4a050ca400115a85aca (patch) | |
tree | 3417642a1daec6e71a2156999d8626d947d63875 /usr.bin/ssh/sshd.c | |
parent | ec70fe89ea2c7355199e5eda04e830bb613137cb (diff) |
Host key rotation support.
Add a hostkeys@openssh.com protocol extension (global request) for
a server to inform a client of all its available host key after
authentication has completed. The client may record the keys in
known_hosts, allowing it to upgrade to better host key algorithms
and a server to gracefully rotate its keys.
The client side of this is controlled by a UpdateHostkeys config
option (default on).
ok markus@
Diffstat (limited to 'usr.bin/ssh/sshd.c')
-rw-r--r-- | usr.bin/ssh/sshd.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/usr.bin/ssh/sshd.c b/usr.bin/ssh/sshd.c index da6b133aff6..b7596e4bae3 100644 --- a/usr.bin/ssh/sshd.c +++ b/usr.bin/ssh/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.438 2015/01/20 23:14:00 deraadt Exp $ */ +/* $OpenBSD: sshd.c,v 1.439 2015/01/26 03:04:46 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -874,6 +874,42 @@ get_hostkey_index(Key *key, struct ssh *ssh) return (-1); } +/* Inform the client of all hostkeys */ +static void +notify_hostkeys(struct ssh *ssh) +{ + struct sshbuf *buf; + struct sshkey *key; + int i, nkeys, r; + char *fp; + + if ((buf = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new", __func__); + for (i = nkeys = 0; i < options.num_host_key_files; i++) { + key = get_hostkey_public_by_index(i, ssh); + if (key == NULL || key->type == KEY_UNSPEC || + key->type == KEY_RSA1 || sshkey_is_cert(key)) + continue; + fp = sshkey_fingerprint(key, options.fingerprint_hash, + SSH_FP_DEFAULT); + debug3("%s: key %d: %s %s", __func__, i, + sshkey_ssh_name(key), fp); + free(fp); + if ((r = sshkey_puts(key, buf)) != 0) + fatal("%s: couldn't put hostkey %d: %s", + __func__, i, ssh_err(r)); + nkeys++; + } + if (nkeys == 0) + fatal("%s: no hostkeys", __func__); + debug3("%s: send %d hostkeys", __func__, nkeys); + packet_start(SSH2_MSG_GLOBAL_REQUEST); + packet_put_cstring("hostkeys@openssh.com"); + packet_put_char(0); /* want-reply */ + packet_put_string(sshbuf_ptr(buf), sshbuf_len(buf)); + packet_send(); +} + /* * returns 1 if connection should be dropped, 0 otherwise. * dropping starts at connection #max_startups_begin with a probability @@ -1608,6 +1644,8 @@ main(int ac, char **av) continue; key = key_load_private(options.host_key_files[i], "", NULL); pubkey = key_load_public(options.host_key_files[i], NULL); + if (pubkey == NULL && key != NULL) + pubkey = key_demote(key); sensitive_data.host_keys[i] = key; sensitive_data.host_pubkeys[i] = pubkey; @@ -2021,6 +2059,10 @@ main(int ac, char **av) packet_set_timeout(options.client_alive_interval, options.client_alive_count_max); + /* Try to send all our hostkeys to the client */ + if (compat20) + notify_hostkeys(active_state); + /* Start session. */ do_authenticated(authctxt); |