summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2015-01-26 03:04:45 +0000
committerDamien Miller <djm@mindrot.org>2015-01-27 00:00:57 +1100
commit8d4f87258f31cb6def9b3b55b6a7321d84728ff2 (patch)
treec98e66c1c0824f0b0e312d7b44d8eeac46265362 /sshd.c
parent60b1825262b1f1e24fc72050b907189c92daf18e (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.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/sshd.c b/sshd.c
index ef63bd1e8..f2ee10d2c 100644
--- a/sshd.c
+++ b/sshd.c
@@ -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 */
915static void
916notify_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