- djm@cvs.openbsd.org 2011/05/24 07:15:47

[readconf.c readconf.h ssh.c ssh_config.5 sshconnect.c sshconnect2.c]
     Remove undocumented legacy options UserKnownHostsFile2 and
     GlobalKnownHostsFile2 by making UserKnownHostsFile/GlobalKnownHostsFile
     accept multiple paths per line and making their defaults include
     known_hosts2; ok markus
This commit is contained in:
Damien Miller 2011-05-29 21:42:31 +10:00
parent 04bb56ef10
commit 295ee63ab2
7 changed files with 127 additions and 96 deletions

View File

@ -24,6 +24,12 @@
read in key comments for v.2 keys (though note that these are not
passed over the agent protocol); bz#439, based on patch from binder
AT arago.de; ok markus@
- djm@cvs.openbsd.org 2011/05/24 07:15:47
[readconf.c readconf.h ssh.c ssh_config.5 sshconnect.c sshconnect2.c]
Remove undocumented legacy options UserKnownHostsFile2 and
GlobalKnownHostsFile2 by making UserKnownHostsFile/GlobalKnownHostsFile
accept multiple paths per line and making their defaults include
known_hosts2; ok markus
20110520
- (djm) [session.c] call setexeccon() before executing passwd for pw

View File

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.c,v 1.192 2011/05/06 21:34:32 djm Exp $ */
/* $OpenBSD: readconf.c,v 1.193 2011/05/24 07:15:47 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -193,9 +193,9 @@ static struct {
{ "host", oHost },
{ "escapechar", oEscapeChar },
{ "globalknownhostsfile", oGlobalKnownHostsFile },
{ "globalknownhostsfile2", oGlobalKnownHostsFile2 }, /* obsolete */
{ "globalknownhostsfile2", oDeprecated },
{ "userknownhostsfile", oUserKnownHostsFile },
{ "userknownhostsfile2", oUserKnownHostsFile2 }, /* obsolete */
{ "userknownhostsfile2", oDeprecated },
{ "connectionattempts", oConnectionAttempts },
{ "batchmode", oBatchMode },
{ "checkhostip", oCheckHostIP },
@ -354,7 +354,9 @@ process_config_line(Options *options, const char *host,
char *line, const char *filename, int linenum,
int *activep)
{
char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
char **cpptr, fwdarg[256];
u_int *uintptr, max_entries = 0;
int negated, opcode, *intptr, value, value2, scale;
LogLevel *log_level_ptr;
long long orig, val64;
@ -598,26 +600,33 @@ parse_yesnoask:
parse_string:
arg = strdelim(&s);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename, linenum);
fatal("%.200s line %d: Missing argument.",
filename, linenum);
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
break;
case oGlobalKnownHostsFile:
charptr = &options->system_hostfile;
goto parse_string;
cpptr = (char **)&options->system_hostfiles;
uintptr = &options->num_system_hostfiles;
max_entries = SSH_MAX_HOSTS_FILES;
parse_char_array:
if (*activep && *uintptr == 0) {
while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
if ((*uintptr) >= max_entries)
fatal("%s line %d: "
"too many authorized keys files.",
filename, linenum);
cpptr[(*uintptr)++] = xstrdup(arg);
}
}
return 0;
case oUserKnownHostsFile:
charptr = &options->user_hostfile;
goto parse_string;
case oGlobalKnownHostsFile2:
charptr = &options->system_hostfile2;
goto parse_string;
case oUserKnownHostsFile2:
charptr = &options->user_hostfile2;
goto parse_string;
cpptr = (char **)&options->user_hostfiles;
uintptr = &options->num_user_hostfiles;
max_entries = SSH_MAX_HOSTS_FILES;
goto parse_char_array;
case oHostName:
charptr = &options->hostname;
@ -1158,10 +1167,8 @@ initialize_options(Options * options)
options->proxy_command = NULL;
options->user = NULL;
options->escape_char = -1;
options->system_hostfile = NULL;
options->user_hostfile = NULL;
options->system_hostfile2 = NULL;
options->user_hostfile2 = NULL;
options->num_system_hostfiles = 0;
options->num_user_hostfiles = 0;
options->local_forwards = NULL;
options->num_local_forwards = 0;
options->remote_forwards = NULL;
@ -1301,14 +1308,18 @@ fill_default_options(Options * options)
}
if (options->escape_char == -1)
options->escape_char = '~';
if (options->system_hostfile == NULL)
options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
if (options->user_hostfile == NULL)
options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
if (options->system_hostfile2 == NULL)
options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
if (options->user_hostfile2 == NULL)
options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
if (options->num_system_hostfiles == 0) {
options->system_hostfiles[options->num_system_hostfiles++] =
xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
options->system_hostfiles[options->num_system_hostfiles++] =
xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
}
if (options->num_user_hostfiles == 0) {
options->user_hostfiles[options->num_user_hostfiles++] =
xstrdup(_PATH_SSH_USER_HOSTFILE);
options->user_hostfiles[options->num_user_hostfiles++] =
xstrdup(_PATH_SSH_USER_HOSTFILE2);
}
if (options->log_level == SYSLOG_LEVEL_NOT_SET)
options->log_level = SYSLOG_LEVEL_INFO;
if (options->clear_forwardings == 1)

View File

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.h,v 1.89 2011/05/06 21:34:32 djm Exp $ */
/* $OpenBSD: readconf.h,v 1.90 2011/05/24 07:15:47 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -27,7 +27,8 @@ typedef struct {
} Forward;
/* Data structure for representing option data. */
#define MAX_SEND_ENV 256
#define MAX_SEND_ENV 256
#define SSH_MAX_HOSTS_FILES 256
typedef struct {
int forward_agent; /* Forward authentication agent. */
@ -83,10 +84,10 @@ typedef struct {
char *user; /* User to log in as. */
int escape_char; /* Escape character; -2 = none */
char *system_hostfile;/* Path for /etc/ssh/ssh_known_hosts. */
char *user_hostfile; /* Path for $HOME/.ssh/known_hosts. */
char *system_hostfile2;
char *user_hostfile2;
u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */
char *system_hostfiles[SSH_MAX_HOSTS_FILES];
u_int num_user_hostfiles; /* Path for $HOME/.ssh/known_hosts */
char *user_hostfiles[SSH_MAX_HOSTS_FILES];
char *preferred_authentications;
char *bind_address; /* local socket address for connection to sshd */
char *pkcs11_provider; /* PKCS#11 provider */

28
ssh.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh.c,v 1.360 2011/05/06 21:38:58 djm Exp $ */
/* $OpenBSD: ssh.c,v 1.361 2011/05/24 07:15:47 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -212,6 +212,20 @@ static void main_sigchld_handler(int);
void muxclient(const char *);
void muxserver_listen(void);
/* ~/ expand a list of paths. NB. assumes path[n] is heap-allocated. */
static void
tilde_expand_paths(char **paths, u_int num_paths)
{
u_int i;
char *cp;
for (i = 0; i < num_paths; i++) {
cp = tilde_expand_filename(paths[i], original_real_uid);
xfree(paths[i]);
paths[i] = cp;
}
}
/*
* Main program for the ssh client.
*/
@ -869,15 +883,9 @@ main(int ac, char **av)
load_public_identity_files();
/* Expand ~ in known host file names. */
/* XXX mem-leaks: */
options.system_hostfile =
tilde_expand_filename(options.system_hostfile, original_real_uid);
options.user_hostfile =
tilde_expand_filename(options.user_hostfile, original_real_uid);
options.system_hostfile2 =
tilde_expand_filename(options.system_hostfile2, original_real_uid);
options.user_hostfile2 =
tilde_expand_filename(options.user_hostfile2, original_real_uid);
tilde_expand_paths(options.system_hostfiles,
options.num_system_hostfiles);
tilde_expand_paths(options.user_hostfiles, options.num_user_hostfiles);
signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
signal(SIGCHLD, main_sigchld_handler);

View File

@ -33,8 +33,8 @@
.\" (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.150 2011/05/07 23:19:39 jmc Exp $
.Dd $Mdocdate: May 7 2011 $
.\" $OpenBSD: ssh_config.5,v 1.151 2011/05/24 07:15:47 djm Exp $
.Dd $Mdocdate: May 24 2011 $
.Dt SSH_CONFIG 5
.Os
.Sh NAME
@ -517,9 +517,11 @@ or
The default is
.Dq no .
.It Cm GlobalKnownHostsFile
Specifies a file to use for the global
host key database instead of
.Pa /etc/ssh/ssh_known_hosts .
Specifies one or more files to use for the global
host key database, separated by whitespace.
The default is
.Pa /etc/ssh/ssh_known_hosts ,
.Pa /etc/ssh/ssh_known_hosts2 .
.It Cm GSSAPIAuthentication
Specifies whether user authentication based on GSSAPI is allowed.
The default is
@ -1171,9 +1173,11 @@ This can be useful when a different user name is used on different machines.
This saves the trouble of
having to remember to give the user name on the command line.
.It Cm UserKnownHostsFile
Specifies a file to use for the user
host key database instead of
.Pa ~/.ssh/known_hosts .
Specifies one or more files to use for the user
host key database, separated by whitespace.
The default is
.Pa ~/.ssh/known_hosts ,
.Pa ~/.ssh/known_hosts2 .
.It Cm VerifyHostKeyDNS
Specifies whether to verify the remote key using DNS and SSHFP resource
records.

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect.c,v 1.233 2011/05/23 03:52:55 djm Exp $ */
/* $OpenBSD: sshconnect.c,v 1.234 2011/05/24 07:15:47 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -683,28 +683,30 @@ get_hostfile_hostname_ipaddr(char *hostname, struct sockaddr *hostaddr,
/*
* check whether the supplied host key is valid, return -1 if the key
* is not valid. the user_hostfile will not be updated if 'readonly' is true.
* is not valid. user_hostfile[0] will not be updated if 'readonly' is true.
*/
#define RDRW 0
#define RDONLY 1
#define ROQUIET 2
static int
check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
Key *host_key, int readonly, char *user_hostfile,
char *system_hostfile)
Key *host_key, int readonly,
char **user_hostfiles, u_int num_user_hostfiles,
char **system_hostfiles, u_int num_system_hostfiles)
{
Key *raw_key = NULL;
const char *type;
char *ip = NULL, *host = NULL;
char hostline[1000], *hostp, *fp, *ra;
HostStatus host_status;
HostStatus ip_status;
int r, want_cert = key_is_cert(host_key), host_ip_differ = 0;
int local = sockaddr_is_local(hostaddr);
Key *raw_key = NULL;
char *ip = NULL, *host = NULL;
char hostline[1000], *hostp, *fp, *ra;
char msg[1024];
int len, cancelled_forwarding = 0;
struct hostkeys *host_hostkeys, *ip_hostkeys;
const char *type;
const struct hostkey_entry *host_found, *ip_found;
int len, cancelled_forwarding = 0;
int local = sockaddr_is_local(hostaddr);
int r, want_cert = key_is_cert(host_key), host_ip_differ = 0;
struct hostkeys *host_hostkeys, *ip_hostkeys;
u_int i;
/*
* Force accepting of the host key for loopback/localhost. The
@ -736,14 +738,18 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
options.check_host_ip = 0;
host_hostkeys = init_hostkeys();
load_hostkeys(host_hostkeys, host, user_hostfile);
load_hostkeys(host_hostkeys, host, system_hostfile);
for (i = 0; i < num_user_hostfiles; i++)
load_hostkeys(host_hostkeys, host, user_hostfiles[i]);
for (i = 0; i < num_system_hostfiles; i++)
load_hostkeys(host_hostkeys, host, system_hostfiles[i]);
ip_hostkeys = NULL;
if (!want_cert && options.check_host_ip) {
ip_hostkeys = init_hostkeys();
load_hostkeys(ip_hostkeys, ip, user_hostfile);
load_hostkeys(ip_hostkeys, ip, system_hostfile);
for (i = 0; i < num_user_hostfiles; i++)
load_hostkeys(ip_hostkeys, ip, user_hostfiles[i]);
for (i = 0; i < num_system_hostfiles; i++)
load_hostkeys(ip_hostkeys, ip, system_hostfiles[i]);
}
retry:
@ -788,11 +794,12 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
logit("%s host key for IP address "
"'%.128s' not in list of known hosts.",
type, ip);
else if (!add_host_to_hostfile(user_hostfile, ip,
else if (!add_host_to_hostfile(user_hostfiles[0], ip,
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);
"hosts (%.30s).", type, ip,
user_hostfiles[0]);
else
logit("Warning: Permanently added the %s host "
"key for IP address '%.128s' to the list "
@ -811,7 +818,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
port != SSH_DEFAULT_PORT) {
debug("checking without port identifier");
if (check_host_key(hostname, hostaddr, 0, host_key,
ROQUIET, user_hostfile, system_hostfile) == 0) {
ROQUIET, user_hostfiles, num_user_hostfiles,
system_hostfiles, num_system_hostfiles) == 0) {
debug("found matching key w/out port");
break;
}
@ -876,25 +884,25 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
hostp = hostline;
if (options.hash_known_hosts) {
/* Add hash of host and IP separately */
r = add_host_to_hostfile(user_hostfile, host,
host_key, options.hash_known_hosts) &&
add_host_to_hostfile(user_hostfile, ip,
r = add_host_to_hostfile(user_hostfiles[0],
host, host_key, options.hash_known_hosts) &&
add_host_to_hostfile(user_hostfiles[0], ip,
host_key, options.hash_known_hosts);
} else {
/* Add unhashed "host,ip" */
r = add_host_to_hostfile(user_hostfile,
r = add_host_to_hostfile(user_hostfiles[0],
hostline, host_key,
options.hash_known_hosts);
}
} else {
r = add_host_to_hostfile(user_hostfile, host, host_key,
options.hash_known_hosts);
r = add_host_to_hostfile(user_hostfiles[0], host,
host_key, options.hash_known_hosts);
hostp = host;
}
if (!r)
logit("Failed to add the host to the list of known "
"hosts (%.500s).", user_hostfile);
"hosts (%.500s).", user_hostfiles[0]);
else
logit("Warning: Permanently added '%.200s' (%s) to the "
"list of known hosts.", hostp, type);
@ -955,7 +963,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
/* The host key has changed. */
warn_changed_key(host_key);
error("Add correct host key in %.100s to get rid of this message.",
user_hostfile);
user_hostfiles[0]);
error("Offending %s key in %s:%lu", key_type(host_found->key),
host_found->file, host_found->line);
@ -1100,7 +1108,6 @@ fail:
int
verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
{
struct stat st;
int flags = 0;
char *fp;
@ -1128,16 +1135,9 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
}
}
/* return ok if the key can be found in an old keyfile */
if (stat(options.system_hostfile2, &st) == 0 ||
stat(options.user_hostfile2, &st) == 0) {
if (check_host_key(host, hostaddr, options.port, host_key,
RDONLY, options.user_hostfile2,
options.system_hostfile2) == 0)
return 0;
}
return check_host_key(host, hostaddr, options.port, host_key,
RDRW, options.user_hostfile, options.system_hostfile);
return check_host_key(host, hostaddr, options.port, host_key, RDRW,
options.user_hostfiles, options.num_user_hostfiles,
options.system_hostfiles, options.num_system_hostfiles);
}
/*

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect2.c,v 1.187 2011/05/06 02:05:41 djm Exp $ */
/* $OpenBSD: sshconnect2.c,v 1.188 2011/05/24 07:15:47 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Damien Miller. All rights reserved.
@ -109,14 +109,15 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port)
size_t maxlen;
struct hostkeys *hostkeys;
int ktype;
u_int i;
/* Find all hostkeys for this hostname */
get_hostfile_hostname_ipaddr(host, hostaddr, port, &hostname, NULL);
hostkeys = init_hostkeys();
load_hostkeys(hostkeys, hostname, options.user_hostfile2);
load_hostkeys(hostkeys, hostname, options.system_hostfile2);
load_hostkeys(hostkeys, hostname, options.user_hostfile);
load_hostkeys(hostkeys, hostname, options.system_hostfile);
for (i = 0; i < options.num_user_hostfiles; i++)
load_hostkeys(hostkeys, hostname, options.user_hostfiles[i]);
for (i = 0; i < options.num_system_hostfiles; i++)
load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]);
oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG);
maxlen = strlen(avail) + 1;