- djm@cvs.openbsd.org 2005/03/01 10:40:27
[hostfile.c hostfile.h readconf.c readconf.h ssh.1 ssh_config.5] [sshconnect.c sshd.8] add support for hashing host names and addresses added to known_hosts files, to improve privacy of which hosts user have been visiting; ok markus@ deraadt@
This commit is contained in:
parent
f91ee4c3de
commit
e1776155d1
|
@ -27,6 +27,12 @@
|
|||
Patch originally by Dan Astorian, but worked on by several people
|
||||
Adds GatewayPorts=clientspecified option on server to allow remote
|
||||
forwards to bind to client-specified ports.
|
||||
- djm@cvs.openbsd.org 2005/03/01 10:40:27
|
||||
[hostfile.c hostfile.h readconf.c readconf.h ssh.1 ssh_config.5]
|
||||
[sshconnect.c sshd.8]
|
||||
add support for hashing host names and addresses added to known_hosts
|
||||
files, to improve privacy of which hosts user have been visiting; ok
|
||||
markus@ deraadt@
|
||||
|
||||
20050226
|
||||
- (dtucker) [openbsd-compat/bsd-openpty.c openbsd-compat/inet_ntop.c]
|
||||
|
@ -2203,4 +2209,4 @@
|
|||
- (djm) Trim deprecated options from INSTALL. Mention UsePAM
|
||||
- (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
|
||||
|
||||
$Id: ChangeLog,v 1.3672 2005/03/01 10:24:33 djm Exp $
|
||||
$Id: ChangeLog,v 1.3673 2005/03/01 10:47:37 djm Exp $
|
||||
|
|
123
hostfile.c
123
hostfile.c
|
@ -36,13 +36,102 @@
|
|||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: hostfile.c,v 1.32 2003/11/10 16:23:41 jakob Exp $");
|
||||
RCSID("$OpenBSD: hostfile.c,v 1.33 2005/03/01 10:40:26 djm Exp $");
|
||||
|
||||
#include <resolv.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "packet.h"
|
||||
#include "match.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "log.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
static int
|
||||
extract_salt(const char *s, u_int l, char *salt, size_t salt_len)
|
||||
{
|
||||
char *p, *b64salt;
|
||||
u_int b64len;
|
||||
int ret;
|
||||
|
||||
if (l < sizeof(HASH_MAGIC) - 1) {
|
||||
debug2("extract_salt: string too short");
|
||||
return (-1);
|
||||
}
|
||||
if (strncmp(s, HASH_MAGIC, sizeof(HASH_MAGIC) - 1) != 0) {
|
||||
debug2("extract_salt: invalid magic identifier");
|
||||
return (-1);
|
||||
}
|
||||
s += sizeof(HASH_MAGIC) - 1;
|
||||
l -= sizeof(HASH_MAGIC) - 1;
|
||||
if ((p = memchr(s, HASH_DELIM, l)) == NULL) {
|
||||
debug2("extract_salt: missing salt termination character");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
b64len = p - s;
|
||||
/* Sanity check */
|
||||
if (b64len == 0 || b64len > 1024) {
|
||||
debug2("extract_salt: bad encoded salt length %u", b64len);
|
||||
return (-1);
|
||||
}
|
||||
b64salt = xmalloc(1 + b64len);
|
||||
memcpy(b64salt, s, b64len);
|
||||
b64salt[b64len] = '\0';
|
||||
|
||||
ret = __b64_pton(b64salt, salt, salt_len);
|
||||
xfree(b64salt);
|
||||
if (ret == -1) {
|
||||
debug2("extract_salt: salt decode error");
|
||||
return (-1);
|
||||
}
|
||||
if (ret != SHA_DIGEST_LENGTH) {
|
||||
debug2("extract_salt: expected salt len %u, got %u",
|
||||
salt_len, ret);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
char *
|
||||
host_hash(const char *host, const char *name_from_hostfile, u_int src_len)
|
||||
{
|
||||
const EVP_MD *md = EVP_sha1();
|
||||
HMAC_CTX mac_ctx;
|
||||
char salt[256], result[256], uu_salt[512], uu_result[512];
|
||||
static char encoded[1024];
|
||||
u_int i, len;
|
||||
|
||||
len = EVP_MD_size(md);
|
||||
|
||||
if (name_from_hostfile == NULL) {
|
||||
/* Create new salt */
|
||||
for (i = 0; i < len; i++)
|
||||
salt[i] = arc4random();
|
||||
} else {
|
||||
/* Extract salt from known host entry */
|
||||
if (extract_salt(name_from_hostfile, src_len, salt,
|
||||
sizeof(salt)) == -1)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
HMAC_Init(&mac_ctx, salt, len, md);
|
||||
HMAC_Update(&mac_ctx, host, strlen(host));
|
||||
HMAC_Final(&mac_ctx, result, NULL);
|
||||
HMAC_cleanup(&mac_ctx);
|
||||
|
||||
if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 ||
|
||||
__b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1)
|
||||
fatal("host_hash: __b64_ntop failed");
|
||||
|
||||
snprintf(encoded, sizeof(encoded), "%s%s%c%s", HASH_MAGIC, uu_salt,
|
||||
HASH_DELIM, uu_result);
|
||||
|
||||
return (encoded);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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,
|
|||
char line[8192];
|
||||
int linenum = 0;
|
||||
u_int kbits;
|
||||
char *cp, *cp2;
|
||||
char *cp, *cp2, *hashed_host;
|
||||
HostStatus end_return;
|
||||
|
||||
debug3("check_host_in_hostfile: filename %s", filename);
|
||||
|
@ -137,8 +226,18 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
|
|||
;
|
||||
|
||||
/* Check if the host name matches. */
|
||||
if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1)
|
||||
continue;
|
||||
if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1) {
|
||||
if (*cp != HASH_DELIM)
|
||||
continue;
|
||||
hashed_host = host_hash(host, cp, (u_int) (cp2 - cp));
|
||||
if (hashed_host == NULL) {
|
||||
debug("Invalid hashed host line %d of %s",
|
||||
linenum, filename);
|
||||
continue;
|
||||
}
|
||||
if (strncmp(hashed_host, cp, (u_int) (cp2 - cp)) != 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Got a match. Skip host name. */
|
||||
cp = cp2;
|
||||
|
@ -211,16 +310,28 @@ lookup_key_in_hostfile_by_type(const char *filename, const char *host,
|
|||
*/
|
||||
|
||||
int
|
||||
add_host_to_hostfile(const char *filename, const char *host, const Key *key)
|
||||
add_host_to_hostfile(const char *filename, const char *host, const Key *key,
|
||||
int store_hash)
|
||||
{
|
||||
FILE *f;
|
||||
int success = 0;
|
||||
char *hashed_host;
|
||||
|
||||
if (key == NULL)
|
||||
return 1; /* XXX ? */
|
||||
f = fopen(filename, "a");
|
||||
if (!f)
|
||||
return 0;
|
||||
fprintf(f, "%s ", host);
|
||||
|
||||
if (store_hash) {
|
||||
if ((hashed_host = host_hash(host, NULL, 0)) == NULL) {
|
||||
error("add_host_to_hostfile: host_hash failed");
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fprintf(f, "%s ", store_hash ? hashed_host : host);
|
||||
|
||||
if (key_write(key, f)) {
|
||||
success = 1;
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: hostfile.h,v 1.14 2003/11/10 16:23:41 jakob Exp $ */
|
||||
/* $OpenBSD: hostfile.h,v 1.15 2005/03/01 10:40:26 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -21,8 +21,13 @@ typedef enum {
|
|||
int hostfile_read_key(char **, u_int *, Key *);
|
||||
HostStatus check_host_in_hostfile(const char *, const char *,
|
||||
const Key *, Key *, int *);
|
||||
int add_host_to_hostfile(const char *, const char *, const Key *);
|
||||
int add_host_to_hostfile(const char *, const char *, const Key *, int);
|
||||
int lookup_key_in_hostfile_by_type(const char *, const char *,
|
||||
int, Key *, int *);
|
||||
|
||||
#define HASH_MAGIC "|1|"
|
||||
#define HASH_DELIM '|'
|
||||
|
||||
char *host_hash(const char *, const char *, u_int);
|
||||
|
||||
#endif
|
||||
|
|
12
readconf.c
12
readconf.c
|
@ -12,7 +12,7 @@
|
|||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: readconf.c,v 1.135 2005/03/01 10:09:52 djm Exp $");
|
||||
RCSID("$OpenBSD: readconf.c,v 1.136 2005/03/01 10:40:26 djm Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "xmalloc.h"
|
||||
|
@ -106,7 +106,7 @@ typedef enum {
|
|||
oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
|
||||
oAddressFamily, oGssAuthentication, oGssDelegateCreds,
|
||||
oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
|
||||
oSendEnv, oControlPath, oControlMaster,
|
||||
oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
|
||||
oDeprecated, oUnsupported
|
||||
} OpCodes;
|
||||
|
||||
|
@ -197,6 +197,7 @@ static struct {
|
|||
{ "sendenv", oSendEnv },
|
||||
{ "controlpath", oControlPath },
|
||||
{ "controlmaster", oControlMaster },
|
||||
{ "hashknownhosts", oHashKnownHosts },
|
||||
{ NULL, oBadOption }
|
||||
};
|
||||
|
||||
|
@ -790,6 +791,10 @@ parse_int:
|
|||
intptr = &options->control_master;
|
||||
goto parse_yesnoask;
|
||||
|
||||
case oHashKnownHosts:
|
||||
intptr = &options->hash_known_hosts;
|
||||
goto parse_flag;
|
||||
|
||||
case oDeprecated:
|
||||
debug("%s line %d: Deprecated option \"%s\"",
|
||||
filename, linenum, keyword);
|
||||
|
@ -933,6 +938,7 @@ initialize_options(Options * options)
|
|||
options->num_send_env = 0;
|
||||
options->control_path = NULL;
|
||||
options->control_master = -1;
|
||||
options->hash_known_hosts = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1055,6 +1061,8 @@ fill_default_options(Options * options)
|
|||
options->server_alive_count_max = 3;
|
||||
if (options->control_master == -1)
|
||||
options->control_master = 0;
|
||||
if (options->hash_known_hosts == -1)
|
||||
options->hash_known_hosts = 0;
|
||||
/* options->proxy_command should not be set by default */
|
||||
/* options->user will be set in the main program if appropriate */
|
||||
/* options->hostname will be set in the main program if appropriate */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: readconf.h,v 1.65 2005/03/01 10:09:52 djm Exp $ */
|
||||
/* $OpenBSD: readconf.h,v 1.66 2005/03/01 10:40:27 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -112,6 +112,8 @@ typedef struct {
|
|||
|
||||
char *control_path;
|
||||
int control_master;
|
||||
|
||||
int hash_known_hosts;
|
||||
} Options;
|
||||
|
||||
|
||||
|
|
3
ssh.1
3
ssh.1
|
@ -34,7 +34,7 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: ssh.1,v 1.200 2005/03/01 10:09:52 djm Exp $
|
||||
.\" $OpenBSD: ssh.1,v 1.201 2005/03/01 10:40:27 djm Exp $
|
||||
.Dd September 25, 1999
|
||||
.Dt SSH 1
|
||||
.Os
|
||||
|
@ -701,6 +701,7 @@ For full details of the options listed below, and their possible values, see
|
|||
.It GlobalKnownHostsFile
|
||||
.It GSSAPIAuthentication
|
||||
.It GSSAPIDelegateCredentials
|
||||
.It HashKnownHosts
|
||||
.It Host
|
||||
.It HostbasedAuthentication
|
||||
.It HostKeyAlgorithms
|
||||
|
|
17
ssh_config.5
17
ssh_config.5
|
@ -34,7 +34,7 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: ssh_config.5,v 1.43 2005/03/01 10:09:52 djm Exp $
|
||||
.\" $OpenBSD: ssh_config.5,v 1.44 2005/03/01 10:40:27 djm Exp $
|
||||
.Dd September 25, 1999
|
||||
.Dt SSH_CONFIG 5
|
||||
.Os
|
||||
|
@ -407,6 +407,21 @@ Forward (delegate) credentials to the server.
|
|||
The default is
|
||||
.Dq no .
|
||||
Note that this option applies to protocol version 2 only.
|
||||
.It Cm HashKnownHosts
|
||||
Indicates that
|
||||
.Nm ssh
|
||||
should hash host names and addresses when they are added to
|
||||
.Pa $HOME/.ssh/known_hosts .
|
||||
These hashed names may be used normally by
|
||||
.Nm ssh
|
||||
and
|
||||
.Nm sshd ,
|
||||
but they do not reveal identifying information should the file's contents
|
||||
be disclosed.
|
||||
The default is
|
||||
.Dq no .
|
||||
Note that hashing of names and addresses will not be retrospectively applied
|
||||
to existing known hosts files.
|
||||
.It Cm HostbasedAuthentication
|
||||
Specifies whether to try rhosts based authentication with public key
|
||||
authentication.
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sshconnect.c,v 1.159 2005/01/05 08:51:32 markus Exp $");
|
||||
RCSID("$OpenBSD: sshconnect.c,v 1.160 2005/03/01 10:40:27 djm Exp $");
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
|
@ -678,7 +678,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
|||
"'%.128s' not in list of known hosts.",
|
||||
type, ip);
|
||||
else if (!add_host_to_hostfile(user_hostfile, ip,
|
||||
host_key))
|
||||
host_key, options.hash_known_hosts))
|
||||
logit("Failed to add the %s host key for IP "
|
||||
"address '%.128s' to the list of known "
|
||||
"hosts (%.30s).", type, ip, user_hostfile);
|
||||
|
@ -744,7 +744,8 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
|||
* If not in strict mode, add the key automatically to the
|
||||
* local known_hosts file.
|
||||
*/
|
||||
if (!add_host_to_hostfile(user_hostfile, hostp, host_key))
|
||||
if (!add_host_to_hostfile(user_hostfile, hostp, host_key,
|
||||
options.hash_known_hosts))
|
||||
logit("Failed to add the host to the list of known "
|
||||
"hosts (%.500s).", user_hostfile);
|
||||
else
|
||||
|
|
15
sshd.8
15
sshd.8
|
@ -34,7 +34,7 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: sshd.8,v 1.204 2005/02/25 10:55:13 jmc Exp $
|
||||
.\" $OpenBSD: sshd.8,v 1.205 2005/03/01 10:40:27 djm Exp $
|
||||
.Dd September 25, 1999
|
||||
.Dt SSHD 8
|
||||
.Os
|
||||
|
@ -553,6 +553,14 @@ to indicate negation: if the host name matches a negated
|
|||
pattern, it is not accepted (by that line) even if it matched another
|
||||
pattern on the line.
|
||||
.Pp
|
||||
Alternately, hostnames may be stored in a hashed form which hides host names
|
||||
and addresses should the file's contents be disclosed. Hashed hostnames start
|
||||
with a
|
||||
.Ql \&|
|
||||
character.
|
||||
Only one hashed hostname may appear on a single line and none of the above
|
||||
negation or wildcard operators may be applied.
|
||||
.Pp
|
||||
Bits, exponent, and modulus are taken directly from the RSA host key; they
|
||||
can be obtained, e.g., from
|
||||
.Pa /etc/ssh/ssh_host_key.pub .
|
||||
|
@ -584,6 +592,11 @@ and adding the host names at the front.
|
|||
closenet,...,130.233.208.41 1024 37 159...93 closenet.hut.fi
|
||||
cvs.openbsd.org,199.185.137.3 ssh-rsa AAAA1234.....=
|
||||
.Ed
|
||||
.Bd -literal
|
||||
# A hashed hostname
|
||||
|1|JfKTdBh7rNbXkVAQCRp4OQoPfmI=|USECr3SWf1JUPsms5AqfD5QfxkM= ssh-rsa
|
||||
AAAA1234.....=
|
||||
.Ed
|
||||
.Sh FILES
|
||||
.Bl -tag -width Ds
|
||||
.It Pa /etc/ssh/sshd_config
|
||||
|
|
Loading…
Reference in New Issue