- djm@cvs.openbsd.org 2011/05/23 03:30:07
     [auth-rsa.c auth.c auth.h auth2-pubkey.c monitor.c monitor_wrap.c pathnames.h servconf.c servconf.h sshd.8 sshd_config sshd_config.5]
     allow AuthorizedKeysFile to specify multiple files, separated by spaces.
     Bring back authorized_keys2 as a default search path (to avoid breaking
     existing users of this file), but override this in sshd_config so it will
     be no longer used on fresh installs. Maybe in 2015 we can remove it
     entierly :)

     feedback and ok markus@ dtucker@
This commit is contained in:
Damien Miller 2011-05-29 21:39:36 +10:00
Родитель acacced70b
Коммит d8478b6a9b
13 изменённых файлов: 151 добавлений и 74 удалений

Просмотреть файл

@ -1,3 +1,16 @@
20110529
- (djm) OpenBSD CVS Sync
- djm@cvs.openbsd.org 2011/05/23 03:30:07
[auth-rsa.c auth.c auth.h auth2-pubkey.c monitor.c monitor_wrap.c]
[pathnames.h servconf.c servconf.h sshd.8 sshd_config sshd_config.5]
allow AuthorizedKeysFile to specify multiple files, separated by spaces.
Bring back authorized_keys2 as a default search path (to avoid breaking
existing users of this file), but override this in sshd_config so it will
be no longer used on fresh installs. Maybe in 2015 we can remove it
entierly :)
feedback and ok markus@ dtucker@
20110520
- (djm) [session.c] call setexeccon() before executing passwd for pw
changes; bz#1891 reported by jchadima AT redhat.com; ok dtucker@

Просмотреть файл

@ -1,4 +1,4 @@
/* $OpenBSD: auth-rsa.c,v 1.79 2010/12/03 23:55:27 djm Exp $ */
/* $OpenBSD: auth-rsa.c,v 1.80 2011/05/23 03:30:07 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -160,44 +160,27 @@ auth_rsa_challenge_dialog(Key *key)
return (success);
}
/*
* check if there's user key matching client_n,
* return key if login is allowed, NULL otherwise
*/
int
auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
static int
rsa_key_allowed_in_file(struct passwd *pw, char *file,
const BIGNUM *client_n, Key **rkey)
{
char line[SSH_MAX_PUBKEY_BYTES], *file;
char line[SSH_MAX_PUBKEY_BYTES];
int allowed = 0;
u_int bits;
FILE *f;
u_long linenum = 0;
Key *key;
/* Temporarily use the user's uid. */
temporarily_use_uid(pw);
/* The authorized keys. */
file = authorized_keys_file(pw);
debug("trying public RSA key file %s", file);
f = auth_openkeyfile(file, pw, options.strict_modes);
if (!f) {
xfree(file);
restore_uid();
return (0);
}
/* Flag indicating whether the key is allowed. */
allowed = 0;
key = key_new(KEY_RSA1);
if ((f = auth_openkeyfile(file, pw, options.strict_modes)) == NULL)
return 0;
/*
* Go though the accepted keys, looking for the current key. If
* found, perform a challenge-response dialog to verify that the
* user really has the corresponding private key.
*/
key = key_new(KEY_RSA1);
while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
char *cp;
char *key_options;
@ -235,7 +218,10 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
}
/* cp now points to the comment part. */
/* Check if the we have found the desired key (identified by its modulus). */
/*
* Check if the we have found the desired key (identified
* by its modulus).
*/
if (BN_cmp(key->rsa->n, client_n) != 0)
continue;
@ -264,11 +250,7 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
break;
}
/* Restore the privileged uid. */
restore_uid();
/* Close the file. */
xfree(file);
fclose(f);
/* return key if allowed */
@ -276,7 +258,33 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
*rkey = key;
else
key_free(key);
return (allowed);
return allowed;
}
/*
* check if there's user key matching client_n,
* return key if login is allowed, NULL otherwise
*/
int
auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
{
char *file;
u_int i, allowed = 0;
temporarily_use_uid(pw);
for (i = 0; !allowed && i < options.num_authkeys_files; i++) {
file = expand_authorized_keys(
options.authorized_keys_files[i], pw);
allowed = rsa_key_allowed_in_file(pw, file, client_n, rkey);
xfree(file);
}
restore_uid();
return allowed;
}
/*

10
auth.c
Просмотреть файл

@ -1,4 +1,4 @@
/* $OpenBSD: auth.c,v 1.92 2011/05/11 04:47:06 djm Exp $ */
/* $OpenBSD: auth.c,v 1.93 2011/05/23 03:30:07 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -331,7 +331,7 @@ auth_root_allowed(char *method)
*
* This returns a buffer allocated by xmalloc.
*/
static char *
char *
expand_authorized_keys(const char *filename, struct passwd *pw)
{
char *file, ret[MAXPATHLEN];
@ -354,12 +354,6 @@ expand_authorized_keys(const char *filename, struct passwd *pw)
return (xstrdup(ret));
}
char *
authorized_keys_file(struct passwd *pw)
{
return expand_authorized_keys(options.authorized_keys_file, pw);
}
char *
authorized_principals_file(struct passwd *pw)
{

4
auth.h
Просмотреть файл

@ -1,4 +1,4 @@
/* $OpenBSD: auth.h,v 1.68 2011/05/11 04:47:06 djm Exp $ */
/* $OpenBSD: auth.h,v 1.69 2011/05/23 03:30:07 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -168,7 +168,7 @@ char *get_challenge(Authctxt *);
int verify_response(Authctxt *, const char *);
void abandon_challenge_response(Authctxt *);
char *authorized_keys_file(struct passwd *);
char *expand_authorized_keys(const char *, struct passwd *pw);
char *authorized_principals_file(struct passwd *);
FILE *auth_openkeyfile(const char *, struct passwd *, int);

Просмотреть файл

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-pubkey.c,v 1.28 2011/05/11 04:47:06 djm Exp $ */
/* $OpenBSD: auth2-pubkey.c,v 1.29 2011/05/23 03:30:07 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -436,7 +436,7 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
int
user_key_allowed(struct passwd *pw, Key *key)
{
int success;
u_int success, i;
char *file;
if (auth_key_is_revoked(key))
@ -448,9 +448,12 @@ user_key_allowed(struct passwd *pw, Key *key)
if (success)
return success;
file = authorized_keys_file(pw);
success = user_key_allowed2(pw, key, file);
xfree(file);
for (i = 0; !success && i < options.num_authkeys_files; i++) {
file = expand_authorized_keys(
options.authorized_keys_files[i], pw);
success = user_key_allowed2(pw, key, file);
xfree(file);
}
return success;
}

Просмотреть файл

@ -1,4 +1,4 @@
/* $OpenBSD: monitor.c,v 1.112 2011/05/20 03:25:45 djm Exp $ */
/* $OpenBSD: monitor.c,v 1.113 2011/05/23 03:30:07 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -632,6 +632,7 @@ mm_answer_pwnamallow(int sock, Buffer *m)
char *username;
struct passwd *pwent;
int allowed = 0;
u_int i;
debug3("%s", __func__);
@ -676,9 +677,14 @@ mm_answer_pwnamallow(int sock, Buffer *m)
if (options.x != NULL) \
buffer_put_cstring(m, options.x); \
} while (0)
#define M_CP_STRARRAYOPT(x, nx) do { \
for (i = 0; i < options.nx; i++) \
buffer_put_cstring(m, options.x[i]); \
} while (0)
/* See comment in servconf.h */
COPY_MATCH_STRING_OPTS();
#undef M_CP_STROPT
#undef M_CP_STRARRAYOPT
debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed);
mm_request_send(sock, MONITOR_ANS_PWNAM, m);
@ -691,7 +697,6 @@ mm_answer_pwnamallow(int sock, Buffer *m)
monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
}
#ifdef USE_PAM
if (options.use_pam)
monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1);

Просмотреть файл

@ -1,4 +1,4 @@
/* $OpenBSD: monitor_wrap.c,v 1.71 2011/05/20 03:25:45 djm Exp $ */
/* $OpenBSD: monitor_wrap.c,v 1.72 2011/05/23 03:30:07 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -211,7 +211,7 @@ mm_getpwnamallow(const char *username)
{
Buffer m;
struct passwd *pw;
u_int len;
u_int len, i;
ServerOptions *newopts;
debug3("%s entering", __func__);
@ -250,9 +250,14 @@ out:
if (newopts->x != NULL) \
newopts->x = buffer_get_string(&m, NULL); \
} while (0)
#define M_CP_STRARRAYOPT(x, nx) do { \
for (i = 0; i < newopts->nx; i++) \
newopts->x[i] = buffer_get_string(&m, NULL); \
} while (0)
/* See comment in servconf.h */
COPY_MATCH_STRING_OPTS();
#undef M_CP_STROPT
#undef M_CP_STRARRAYOPT
copy_set_server_options(&options, newopts, 1);
xfree(newopts);

Просмотреть файл

@ -1,4 +1,4 @@
/* $OpenBSD: pathnames.h,v 1.21 2011/05/11 04:47:06 djm Exp $ */
/* $OpenBSD: pathnames.h,v 1.22 2011/05/23 03:30:07 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -96,6 +96,9 @@
*/
#define _PATH_SSH_USER_PERMITTED_KEYS ".ssh/authorized_keys"
/* backward compat for protocol v2 */
#define _PATH_SSH_USER_PERMITTED_KEYS2 ".ssh/authorized_keys2"
/*
* Per-user and system-wide ssh "rc" files. These files are executed with
* /bin/sh before starting the shell or command if they exist. They will be

Просмотреть файл

@ -1,4 +1,4 @@
/* $OpenBSD: servconf.c,v 1.218 2011/05/20 03:25:45 djm Exp $ */
/* $OpenBSD: servconf.c,v 1.219 2011/05/23 03:30:07 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -126,7 +126,7 @@ initialize_server_options(ServerOptions *options)
options->use_dns = -1;
options->client_alive_interval = -1;
options->client_alive_count_max = -1;
options->authorized_keys_file = NULL;
options->num_authkeys_files = 0;
options->num_accept_env = 0;
options->permit_tun = -1;
options->num_permitted_opens = -1;
@ -263,8 +263,12 @@ fill_default_server_options(ServerOptions *options)
options->client_alive_interval = 0;
if (options->client_alive_count_max == -1)
options->client_alive_count_max = 3;
if (options->authorized_keys_file == NULL)
options->authorized_keys_file = xstrdup(_PATH_SSH_USER_PERMITTED_KEYS);
if (options->num_authkeys_files == 0) {
options->authorized_keys_files[options->num_authkeys_files++] =
xstrdup(_PATH_SSH_USER_PERMITTED_KEYS);
options->authorized_keys_files[options->num_authkeys_files++] =
xstrdup(_PATH_SSH_USER_PERMITTED_KEYS2);
}
if (options->permit_tun == -1)
options->permit_tun = SSH_TUNMODE_NO;
if (options->zero_knowledge_password_authentication == -1)
@ -430,6 +434,7 @@ static struct {
{ "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
{ "authorizedkeysfile2", sDeprecated, SSHCFG_ALL },
{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL},
{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
{ "permittunnel", sPermitTunnel, SSHCFG_ALL },
@ -1241,11 +1246,22 @@ process_server_config_line(ServerOptions *options, char *line,
* AuthorizedKeysFile /etc/ssh_keys/%u
*/
case sAuthorizedKeysFile:
charptr = &options->authorized_keys_file;
goto parse_tilde_filename;
if (*activep && options->num_authkeys_files == 0) {
while ((arg = strdelim(&cp)) && *arg != '\0') {
if (options->num_authkeys_files >=
MAX_AUTHKEYS_FILES)
fatal("%s line %d: "
"too many authorized keys files.",
filename, linenum);
options->authorized_keys_files[
options->num_authkeys_files++] =
tilde_expand_filename(arg, getuid());
}
}
return 0;
case sAuthorizedPrincipalsFile:
charptr = &options->authorized_principals_file;
parse_tilde_filename:
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing file name.",
@ -1464,6 +1480,12 @@ parse_server_match_config(ServerOptions *options, const char *user,
dst->n = src->n; \
} \
} while(0)
#define M_CP_STRARRAYOPT(n, num_n) do {\
if (src->num_n != 0) { \
for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \
dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \
} \
} while(0)
/*
* Copy any supported values that are set.
@ -1508,12 +1530,14 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
*/
if (preauth)
return;
M_CP_STROPT(adm_forced_command);
M_CP_STROPT(chroot_directory);
}
#undef M_CP_INTOPT
#undef M_CP_STROPT
#undef M_CP_STRARRAYOPT
void
parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
@ -1627,7 +1651,18 @@ dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
u_int i;
for (i = 0; i < count; i++)
printf("%s %s\n", lookup_opcode_name(code), vals[i]);
printf("%s %s\n", lookup_opcode_name(code), vals[i]);
}
static void
dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
{
u_int i;
printf("%s", lookup_opcode_name(code));
for (i = 0; i < count; i++)
printf(" %s", vals[i]);
printf("\n");
}
void
@ -1725,7 +1760,6 @@ dump_config(ServerOptions *o)
dump_cfg_string(sCiphers, o->ciphers);
dump_cfg_string(sMacs, o->macs);
dump_cfg_string(sBanner, o->banner);
dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file);
dump_cfg_string(sForceCommand, o->adm_forced_command);
dump_cfg_string(sChrootDirectory, o->chroot_directory);
dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
@ -1738,6 +1772,8 @@ dump_config(ServerOptions *o)
dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
/* string array arguments */
dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files,
o->authorized_keys_files);
dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
o->host_key_files);
dump_cfg_strarray(sHostKeyFile, o->num_host_cert_files,

Просмотреть файл

@ -1,4 +1,4 @@
/* $OpenBSD: servconf.h,v 1.97 2011/05/20 03:25:45 djm Exp $ */
/* $OpenBSD: servconf.h,v 1.98 2011/05/23 03:30:07 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -27,6 +27,7 @@
#define MAX_HOSTCERTS 256 /* Max # host certificates. */
#define MAX_ACCEPT_ENV 256 /* Max # of env vars. */
#define MAX_MATCH_GROUPS 256 /* Max # of groups for Match. */
#define MAX_AUTHKEYS_FILES 256 /* Max # of authorized_keys files. */
/* permit_root_login */
#define PERMIT_NOT_SET -1
@ -145,7 +146,8 @@ typedef struct {
* disconnect the session
*/
char *authorized_keys_file; /* File containing public keys */
u_int num_authkeys_files; /* Files containing public keys */
char *authorized_keys_files[MAX_AUTHKEYS_FILES];
char *adm_forced_command;
@ -171,8 +173,8 @@ typedef struct {
M_CP_STROPT(banner); \
M_CP_STROPT(trusted_user_ca_keys); \
M_CP_STROPT(revoked_keys_file); \
M_CP_STROPT(authorized_keys_file); \
M_CP_STROPT(authorized_principals_file); \
M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \
} while (0)
void initialize_server_options(ServerOptions *);

12
sshd.8
Просмотреть файл

@ -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: sshd.8,v 1.260 2010/10/28 18:33:28 jmc Exp $
.Dd $Mdocdate: October 28 2010 $
.\" $OpenBSD: sshd.8,v 1.261 2011/05/23 03:30:07 djm Exp $
.Dd $Mdocdate: May 23 2011 $
.Dt SSHD 8
.Os
.Sh NAME
@ -462,10 +462,12 @@ is run, and if that
does not exist either, xauth is used to add the cookie.
.Sh AUTHORIZED_KEYS FILE FORMAT
.Cm AuthorizedKeysFile
specifies the file containing public keys for
specifies the file or files containing public keys for
public key authentication;
if none is specified, the default is
.Pa ~/.ssh/authorized_keys .
if none is specified, the default is both
.Pa ~/.ssh/authorized_keys
and
.Pa ~/.ssh/authorized_keys2 .
Each line of the file contains one
key (empty lines and lines starting with a
.Ql #

Просмотреть файл

@ -1,4 +1,4 @@
# $OpenBSD: sshd_config,v 1.83 2011/05/06 01:03:35 dtucker Exp $
# $OpenBSD: sshd_config,v 1.84 2011/05/23 03:30:07 djm Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
@ -44,7 +44,10 @@
#RSAAuthentication yes
#PubkeyAuthentication yes
#AuthorizedKeysFile .ssh/authorized_keys
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#RhostsRSAAuthentication no

Просмотреть файл

@ -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: sshd_config.5,v 1.131 2010/12/08 04:02:47 djm Exp $
.Dd $Mdocdate: December 8 2010 $
.\" $OpenBSD: sshd_config.5,v 1.132 2011/05/23 03:30:07 djm Exp $
.Dd $Mdocdate: May 23 2011 $
.Dt SSHD_CONFIG 5
.Os
.Sh NAME
@ -168,8 +168,11 @@ After expansion,
.Cm AuthorizedKeysFile
is taken to be an absolute path or one relative to the user's home
directory.
The default is
.Dq .ssh/authorized_keys .
The default is both
.Dq .ssh/authorized_keys
and
.Dq .ssh/authorized_keys2 .
Multiple files may be listed separated by whitespace.
.It Cm AuthorizedPrincipalsFile
Specifies a file that lists principal names that are accepted for
certificate authentication.