summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--hostfile.c123
-rw-r--r--hostfile.h9
-rw-r--r--readconf.c12
-rw-r--r--readconf.h4
-rw-r--r--ssh.13
-rw-r--r--ssh_config.517
-rw-r--r--sshconnect.c7
-rw-r--r--sshd.815
9 files changed, 180 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index f31a52665..b69fe2f51 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -27,6 +27,12 @@
27 Patch originally by Dan Astorian, but worked on by several people 27 Patch originally by Dan Astorian, but worked on by several people
28 Adds GatewayPorts=clientspecified option on server to allow remote 28 Adds GatewayPorts=clientspecified option on server to allow remote
29 forwards to bind to client-specified ports. 29 forwards to bind to client-specified ports.
30 - djm@cvs.openbsd.org 2005/03/01 10:40:27
31 [hostfile.c hostfile.h readconf.c readconf.h ssh.1 ssh_config.5]
32 [sshconnect.c sshd.8]
33 add support for hashing host names and addresses added to known_hosts
34 files, to improve privacy of which hosts user have been visiting; ok
35 markus@ deraadt@
30 36
3120050226 3720050226
32 - (dtucker) [openbsd-compat/bsd-openpty.c openbsd-compat/inet_ntop.c] 38 - (dtucker) [openbsd-compat/bsd-openpty.c openbsd-compat/inet_ntop.c]
@@ -2203,4 +2209,4 @@
2203 - (djm) Trim deprecated options from INSTALL. Mention UsePAM 2209 - (djm) Trim deprecated options from INSTALL. Mention UsePAM
2204 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu 2210 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
2205 2211
2206$Id: ChangeLog,v 1.3672 2005/03/01 10:24:33 djm Exp $ 2212$Id: ChangeLog,v 1.3673 2005/03/01 10:47:37 djm Exp $
diff --git a/hostfile.c b/hostfile.c
index 88c054912..2e1c8bcd0 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -36,13 +36,102 @@
36 */ 36 */
37 37
38#include "includes.h" 38#include "includes.h"
39RCSID("$OpenBSD: hostfile.c,v 1.32 2003/11/10 16:23:41 jakob Exp $"); 39RCSID("$OpenBSD: hostfile.c,v 1.33 2005/03/01 10:40:26 djm Exp $");
40
41#include <resolv.h>
42#include <openssl/hmac.h>
43#include <openssl/sha.h>
40 44
41#include "packet.h" 45#include "packet.h"
42#include "match.h" 46#include "match.h"
43#include "key.h" 47#include "key.h"
44#include "hostfile.h" 48#include "hostfile.h"
45#include "log.h" 49#include "log.h"
50#include "xmalloc.h"
51
52static int
53extract_salt(const char *s, u_int l, char *salt, size_t salt_len)
54{
55 char *p, *b64salt;
56 u_int b64len;
57 int ret;
58
59 if (l < sizeof(HASH_MAGIC) - 1) {
60 debug2("extract_salt: string too short");
61 return (-1);
62 }
63 if (strncmp(s, HASH_MAGIC, sizeof(HASH_MAGIC) - 1) != 0) {
64 debug2("extract_salt: invalid magic identifier");
65 return (-1);
66 }
67 s += sizeof(HASH_MAGIC) - 1;
68 l -= sizeof(HASH_MAGIC) - 1;
69 if ((p = memchr(s, HASH_DELIM, l)) == NULL) {
70 debug2("extract_salt: missing salt termination character");
71 return (-1);
72 }
73
74 b64len = p - s;
75 /* Sanity check */
76 if (b64len == 0 || b64len > 1024) {
77 debug2("extract_salt: bad encoded salt length %u", b64len);
78 return (-1);
79 }
80 b64salt = xmalloc(1 + b64len);
81 memcpy(b64salt, s, b64len);
82 b64salt[b64len] = '\0';
83
84 ret = __b64_pton(b64salt, salt, salt_len);
85 xfree(b64salt);
86 if (ret == -1) {
87 debug2("extract_salt: salt decode error");
88 return (-1);
89 }
90 if (ret != SHA_DIGEST_LENGTH) {
91 debug2("extract_salt: expected salt len %u, got %u",
92 salt_len, ret);
93 return (-1);
94 }
95
96 return (0);
97}
98
99char *
100host_hash(const char *host, const char *name_from_hostfile, u_int src_len)
101{
102 const EVP_MD *md = EVP_sha1();
103 HMAC_CTX mac_ctx;
104 char salt[256], result[256], uu_salt[512], uu_result[512];
105 static char encoded[1024];
106 u_int i, len;
107
108 len = EVP_MD_size(md);
109
110 if (name_from_hostfile == NULL) {
111 /* Create new salt */
112 for (i = 0; i < len; i++)
113 salt[i] = arc4random();
114 } else {
115 /* Extract salt from known host entry */
116 if (extract_salt(name_from_hostfile, src_len, salt,
117 sizeof(salt)) == -1)
118 return (NULL);
119 }
120
121 HMAC_Init(&mac_ctx, salt, len, md);
122 HMAC_Update(&mac_ctx, host, strlen(host));
123 HMAC_Final(&mac_ctx, result, NULL);
124 HMAC_cleanup(&mac_ctx);
125
126 if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 ||
127 __b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1)
128 fatal("host_hash: __b64_ntop failed");
129
130 snprintf(encoded, sizeof(encoded), "%s%s%c%s", HASH_MAGIC, uu_salt,
131 HASH_DELIM, uu_result);
132
133 return (encoded);
134}
46 135
47/* 136/*
48 * Parses an RSA (number of bits, e, n) or DSA key from a string. Moves the 137 * Parses an RSA (number of bits, e, n) or DSA key from a string. Moves the
@@ -104,7 +193,7 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
104 char line[8192]; 193 char line[8192];
105 int linenum = 0; 194 int linenum = 0;
106 u_int kbits; 195 u_int kbits;
107 char *cp, *cp2; 196 char *cp, *cp2, *hashed_host;
108 HostStatus end_return; 197 HostStatus end_return;
109 198
110 debug3("check_host_in_hostfile: filename %s", filename); 199 debug3("check_host_in_hostfile: filename %s", filename);
@@ -137,8 +226,18 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
137 ; 226 ;
138 227
139 /* Check if the host name matches. */ 228 /* Check if the host name matches. */
140 if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1) 229 if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1) {
141 continue; 230 if (*cp != HASH_DELIM)
231 continue;
232 hashed_host = host_hash(host, cp, (u_int) (cp2 - cp));
233 if (hashed_host == NULL) {
234 debug("Invalid hashed host line %d of %s",
235 linenum, filename);
236 continue;
237 }
238 if (strncmp(hashed_host, cp, (u_int) (cp2 - cp)) != 0)
239 continue;
240 }
142 241
143 /* Got a match. Skip host name. */ 242 /* Got a match. Skip host name. */
144 cp = cp2; 243 cp = cp2;
@@ -211,16 +310,28 @@ lookup_key_in_hostfile_by_type(const char *filename, const char *host,
211 */ 310 */
212 311
213int 312int
214add_host_to_hostfile(const char *filename, const char *host, const Key *key) 313add_host_to_hostfile(const char *filename, const char *host, const Key *key,
314 int store_hash)
215{ 315{
216 FILE *f; 316 FILE *f;
217 int success = 0; 317 int success = 0;
318 char *hashed_host;
319
218 if (key == NULL) 320 if (key == NULL)
219 return 1; /* XXX ? */ 321 return 1; /* XXX ? */
220 f = fopen(filename, "a"); 322 f = fopen(filename, "a");
221 if (!f) 323 if (!f)
222 return 0; 324 return 0;
223 fprintf(f, "%s ", host); 325
326 if (store_hash) {
327 if ((hashed_host = host_hash(host, NULL, 0)) == NULL) {
328 error("add_host_to_hostfile: host_hash failed");
329 fclose(f);
330 return 0;
331 }
332 }
333 fprintf(f, "%s ", store_hash ? hashed_host : host);
334
224 if (key_write(key, f)) { 335 if (key_write(key, f)) {
225 success = 1; 336 success = 1;
226 } else { 337 } else {
diff --git a/hostfile.h b/hostfile.h
index efcddc9f9..d6330752e 100644
--- a/hostfile.h
+++ b/hostfile.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: hostfile.h,v 1.14 2003/11/10 16:23:41 jakob Exp $ */ 1/* $OpenBSD: hostfile.h,v 1.15 2005/03/01 10:40:26 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -21,8 +21,13 @@ typedef enum {
21int hostfile_read_key(char **, u_int *, Key *); 21int hostfile_read_key(char **, u_int *, Key *);
22HostStatus check_host_in_hostfile(const char *, const char *, 22HostStatus check_host_in_hostfile(const char *, const char *,
23 const Key *, Key *, int *); 23 const Key *, Key *, int *);
24int add_host_to_hostfile(const char *, const char *, const Key *); 24int add_host_to_hostfile(const char *, const char *, const Key *, int);
25int lookup_key_in_hostfile_by_type(const char *, const char *, 25int lookup_key_in_hostfile_by_type(const char *, const char *,
26 int, Key *, int *); 26 int, Key *, int *);
27 27
28#define HASH_MAGIC "|1|"
29#define HASH_DELIM '|'
30
31char *host_hash(const char *, const char *, u_int);
32
28#endif 33#endif
diff --git a/readconf.c b/readconf.c
index c3dc71e66..e50a42222 100644
--- a/readconf.c
+++ b/readconf.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$OpenBSD: readconf.c,v 1.135 2005/03/01 10:09:52 djm Exp $"); 15RCSID("$OpenBSD: readconf.c,v 1.136 2005/03/01 10:40:26 djm Exp $");
16 16
17#include "ssh.h" 17#include "ssh.h"
18#include "xmalloc.h" 18#include "xmalloc.h"
@@ -106,7 +106,7 @@ typedef enum {
106 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, 106 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
107 oAddressFamily, oGssAuthentication, oGssDelegateCreds, 107 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
108 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, 108 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
109 oSendEnv, oControlPath, oControlMaster, 109 oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
110 oDeprecated, oUnsupported 110 oDeprecated, oUnsupported
111} OpCodes; 111} OpCodes;
112 112
@@ -197,6 +197,7 @@ static struct {
197 { "sendenv", oSendEnv }, 197 { "sendenv", oSendEnv },
198 { "controlpath", oControlPath }, 198 { "controlpath", oControlPath },
199 { "controlmaster", oControlMaster }, 199 { "controlmaster", oControlMaster },
200 { "hashknownhosts", oHashKnownHosts },
200 { NULL, oBadOption } 201 { NULL, oBadOption }
201}; 202};
202 203
@@ -790,6 +791,10 @@ parse_int:
790 intptr = &options->control_master; 791 intptr = &options->control_master;
791 goto parse_yesnoask; 792 goto parse_yesnoask;
792 793
794 case oHashKnownHosts:
795 intptr = &options->hash_known_hosts;
796 goto parse_flag;
797
793 case oDeprecated: 798 case oDeprecated:
794 debug("%s line %d: Deprecated option \"%s\"", 799 debug("%s line %d: Deprecated option \"%s\"",
795 filename, linenum, keyword); 800 filename, linenum, keyword);
@@ -933,6 +938,7 @@ initialize_options(Options * options)
933 options->num_send_env = 0; 938 options->num_send_env = 0;
934 options->control_path = NULL; 939 options->control_path = NULL;
935 options->control_master = -1; 940 options->control_master = -1;
941 options->hash_known_hosts = -1;
936} 942}
937 943
938/* 944/*
@@ -1055,6 +1061,8 @@ fill_default_options(Options * options)
1055 options->server_alive_count_max = 3; 1061 options->server_alive_count_max = 3;
1056 if (options->control_master == -1) 1062 if (options->control_master == -1)
1057 options->control_master = 0; 1063 options->control_master = 0;
1064 if (options->hash_known_hosts == -1)
1065 options->hash_known_hosts = 0;
1058 /* options->proxy_command should not be set by default */ 1066 /* options->proxy_command should not be set by default */
1059 /* options->user will be set in the main program if appropriate */ 1067 /* options->user will be set in the main program if appropriate */
1060 /* options->hostname will be set in the main program if appropriate */ 1068 /* options->hostname will be set in the main program if appropriate */
diff --git a/readconf.h b/readconf.h
index 03b772a2d..de4b4cb27 100644
--- a/readconf.h
+++ b/readconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.h,v 1.65 2005/03/01 10:09:52 djm Exp $ */ 1/* $OpenBSD: readconf.h,v 1.66 2005/03/01 10:40:27 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -112,6 +112,8 @@ typedef struct {
112 112
113 char *control_path; 113 char *control_path;
114 int control_master; 114 int control_master;
115
116 int hash_known_hosts;
115} Options; 117} Options;
116 118
117 119
diff --git a/ssh.1 b/ssh.1
index 27da08c69..c371b7cf5 100644
--- a/ssh.1
+++ b/ssh.1
@@ -34,7 +34,7 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: ssh.1,v 1.200 2005/03/01 10:09:52 djm Exp $ 37.\" $OpenBSD: ssh.1,v 1.201 2005/03/01 10:40:27 djm Exp $
38.Dd September 25, 1999 38.Dd September 25, 1999
39.Dt SSH 1 39.Dt SSH 1
40.Os 40.Os
@@ -701,6 +701,7 @@ For full details of the options listed below, and their possible values, see
701.It GlobalKnownHostsFile 701.It GlobalKnownHostsFile
702.It GSSAPIAuthentication 702.It GSSAPIAuthentication
703.It GSSAPIDelegateCredentials 703.It GSSAPIDelegateCredentials
704.It HashKnownHosts
704.It Host 705.It Host
705.It HostbasedAuthentication 706.It HostbasedAuthentication
706.It HostKeyAlgorithms 707.It HostKeyAlgorithms
diff --git a/ssh_config.5 b/ssh_config.5
index 6b6cfc5e9..9077acbee 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -34,7 +34,7 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: ssh_config.5,v 1.43 2005/03/01 10:09:52 djm Exp $ 37.\" $OpenBSD: ssh_config.5,v 1.44 2005/03/01 10:40:27 djm Exp $
38.Dd September 25, 1999 38.Dd September 25, 1999
39.Dt SSH_CONFIG 5 39.Dt SSH_CONFIG 5
40.Os 40.Os
@@ -407,6 +407,21 @@ Forward (delegate) credentials to the server.
407The default is 407The default is
408.Dq no . 408.Dq no .
409Note that this option applies to protocol version 2 only. 409Note that this option applies to protocol version 2 only.
410.It Cm HashKnownHosts
411Indicates that
412.Nm ssh
413should hash host names and addresses when they are added to
414.Pa $HOME/.ssh/known_hosts .
415These hashed names may be used normally by
416.Nm ssh
417and
418.Nm sshd ,
419but they do not reveal identifying information should the file's contents
420be disclosed.
421The default is
422.Dq no .
423Note that hashing of names and addresses will not be retrospectively applied
424to existing known hosts files.
410.It Cm HostbasedAuthentication 425.It Cm HostbasedAuthentication
411Specifies whether to try rhosts based authentication with public key 426Specifies whether to try rhosts based authentication with public key
412authentication. 427authentication.
diff --git a/sshconnect.c b/sshconnect.c
index 33ec4753a..bafe7ba92 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -13,7 +13,7 @@
13 */ 13 */
14 14
15#include "includes.h" 15#include "includes.h"
16RCSID("$OpenBSD: sshconnect.c,v 1.159 2005/01/05 08:51:32 markus Exp $"); 16RCSID("$OpenBSD: sshconnect.c,v 1.160 2005/03/01 10:40:27 djm Exp $");
17 17
18#include <openssl/bn.h> 18#include <openssl/bn.h>
19 19
@@ -678,7 +678,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
678 "'%.128s' not in list of known hosts.", 678 "'%.128s' not in list of known hosts.",
679 type, ip); 679 type, ip);
680 else if (!add_host_to_hostfile(user_hostfile, ip, 680 else if (!add_host_to_hostfile(user_hostfile, ip,
681 host_key)) 681 host_key, options.hash_known_hosts))
682 logit("Failed to add the %s host key for IP " 682 logit("Failed to add the %s host key for IP "
683 "address '%.128s' to the list of known " 683 "address '%.128s' to the list of known "
684 "hosts (%.30s).", type, ip, user_hostfile); 684 "hosts (%.30s).", type, ip, user_hostfile);
@@ -744,7 +744,8 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
744 * If not in strict mode, add the key automatically to the 744 * If not in strict mode, add the key automatically to the
745 * local known_hosts file. 745 * local known_hosts file.
746 */ 746 */
747 if (!add_host_to_hostfile(user_hostfile, hostp, host_key)) 747 if (!add_host_to_hostfile(user_hostfile, hostp, host_key,
748 options.hash_known_hosts))
748 logit("Failed to add the host to the list of known " 749 logit("Failed to add the host to the list of known "
749 "hosts (%.500s).", user_hostfile); 750 "hosts (%.500s).", user_hostfile);
750 else 751 else
diff --git a/sshd.8 b/sshd.8
index 9d30369c9..05b88f59e 100644
--- a/sshd.8
+++ b/sshd.8
@@ -34,7 +34,7 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: sshd.8,v 1.204 2005/02/25 10:55:13 jmc Exp $ 37.\" $OpenBSD: sshd.8,v 1.205 2005/03/01 10:40:27 djm Exp $
38.Dd September 25, 1999 38.Dd September 25, 1999
39.Dt SSHD 8 39.Dt SSHD 8
40.Os 40.Os
@@ -553,6 +553,14 @@ to indicate negation: if the host name matches a negated
553pattern, it is not accepted (by that line) even if it matched another 553pattern, it is not accepted (by that line) even if it matched another
554pattern on the line. 554pattern on the line.
555.Pp 555.Pp
556Alternately, hostnames may be stored in a hashed form which hides host names
557and addresses should the file's contents be disclosed. Hashed hostnames start
558with a
559.Ql \&|
560character.
561Only one hashed hostname may appear on a single line and none of the above
562negation or wildcard operators may be applied.
563.Pp
556Bits, exponent, and modulus are taken directly from the RSA host key; they 564Bits, exponent, and modulus are taken directly from the RSA host key; they
557can be obtained, e.g., from 565can be obtained, e.g., from
558.Pa /etc/ssh/ssh_host_key.pub . 566.Pa /etc/ssh/ssh_host_key.pub .
@@ -584,6 +592,11 @@ and adding the host names at the front.
584closenet,...,130.233.208.41 1024 37 159...93 closenet.hut.fi 592closenet,...,130.233.208.41 1024 37 159...93 closenet.hut.fi
585cvs.openbsd.org,199.185.137.3 ssh-rsa AAAA1234.....= 593cvs.openbsd.org,199.185.137.3 ssh-rsa AAAA1234.....=
586.Ed 594.Ed
595.Bd -literal
596# A hashed hostname
597|1|JfKTdBh7rNbXkVAQCRp4OQoPfmI=|USECr3SWf1JUPsms5AqfD5QfxkM= ssh-rsa
598AAAA1234.....=
599.Ed
587.Sh FILES 600.Sh FILES
588.Bl -tag -width Ds 601.Bl -tag -width Ds
589.It Pa /etc/ssh/sshd_config 602.It Pa /etc/ssh/sshd_config