diff options
author | djm@openbsd.org <djm@openbsd.org> | 2015-01-26 03:04:45 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2015-01-27 00:00:57 +1100 |
commit | 8d4f87258f31cb6def9b3b55b6a7321d84728ff2 (patch) | |
tree | c98e66c1c0824f0b0e312d7b44d8eeac46265362 /sshd.c | |
parent | 60b1825262b1f1e24fc72050b907189c92daf18e (diff) |
upstream commit
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 'sshd.c')
-rw-r--r-- | sshd.c | 44 |
1 files changed, 43 insertions, 1 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.438 2015/01/20 23:14:00 deraadt Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.439 2015/01/26 03:04:46 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -911,6 +911,42 @@ get_hostkey_index(Key *key, struct ssh *ssh) | |||
911 | return (-1); | 911 | return (-1); |
912 | } | 912 | } |
913 | 913 | ||
914 | /* Inform the client of all hostkeys */ | ||
915 | static void | ||
916 | notify_hostkeys(struct ssh *ssh) | ||
917 | { | ||
918 | struct sshbuf *buf; | ||
919 | struct sshkey *key; | ||
920 | int i, nkeys, r; | ||
921 | char *fp; | ||
922 | |||
923 | if ((buf = sshbuf_new()) == NULL) | ||
924 | fatal("%s: sshbuf_new", __func__); | ||
925 | for (i = nkeys = 0; i < options.num_host_key_files; i++) { | ||
926 | key = get_hostkey_public_by_index(i, ssh); | ||
927 | if (key == NULL || key->type == KEY_UNSPEC || | ||
928 | key->type == KEY_RSA1 || sshkey_is_cert(key)) | ||
929 | continue; | ||
930 | fp = sshkey_fingerprint(key, options.fingerprint_hash, | ||
931 | SSH_FP_DEFAULT); | ||
932 | debug3("%s: key %d: %s %s", __func__, i, | ||
933 | sshkey_ssh_name(key), fp); | ||
934 | free(fp); | ||
935 | if ((r = sshkey_puts(key, buf)) != 0) | ||
936 | fatal("%s: couldn't put hostkey %d: %s", | ||
937 | __func__, i, ssh_err(r)); | ||
938 | nkeys++; | ||
939 | } | ||
940 | if (nkeys == 0) | ||
941 | fatal("%s: no hostkeys", __func__); | ||
942 | debug3("%s: send %d hostkeys", __func__, nkeys); | ||
943 | packet_start(SSH2_MSG_GLOBAL_REQUEST); | ||
944 | packet_put_cstring("hostkeys@openssh.com"); | ||
945 | packet_put_char(0); /* want-reply */ | ||
946 | packet_put_string(sshbuf_ptr(buf), sshbuf_len(buf)); | ||
947 | packet_send(); | ||
948 | } | ||
949 | |||
914 | /* | 950 | /* |
915 | * returns 1 if connection should be dropped, 0 otherwise. | 951 | * returns 1 if connection should be dropped, 0 otherwise. |
916 | * dropping starts at connection #max_startups_begin with a probability | 952 | * dropping starts at connection #max_startups_begin with a probability |
@@ -1722,6 +1758,8 @@ main(int ac, char **av) | |||
1722 | continue; | 1758 | continue; |
1723 | key = key_load_private(options.host_key_files[i], "", NULL); | 1759 | key = key_load_private(options.host_key_files[i], "", NULL); |
1724 | pubkey = key_load_public(options.host_key_files[i], NULL); | 1760 | pubkey = key_load_public(options.host_key_files[i], NULL); |
1761 | if (pubkey == NULL && key != NULL) | ||
1762 | pubkey = key_demote(key); | ||
1725 | sensitive_data.host_keys[i] = key; | 1763 | sensitive_data.host_keys[i] = key; |
1726 | sensitive_data.host_pubkeys[i] = pubkey; | 1764 | sensitive_data.host_pubkeys[i] = pubkey; |
1727 | 1765 | ||
@@ -2185,6 +2223,10 @@ main(int ac, char **av) | |||
2185 | packet_set_timeout(options.client_alive_interval, | 2223 | packet_set_timeout(options.client_alive_interval, |
2186 | options.client_alive_count_max); | 2224 | options.client_alive_count_max); |
2187 | 2225 | ||
2226 | /* Try to send all our hostkeys to the client */ | ||
2227 | if (compat20) | ||
2228 | notify_hostkeys(active_state); | ||
2229 | |||
2188 | /* Start session. */ | 2230 | /* Start session. */ |
2189 | do_authenticated(authctxt); | 2231 | do_authenticated(authctxt); |
2190 | 2232 | ||