sync cvs as of 2012-11-10

This commit is contained in:
Markus Friedl
2012-11-10 16:24:59 +01:00
parent 6ac14552ea
commit 88d1ce29a9
15 changed files with 692 additions and 135 deletions

View File

@@ -9,7 +9,6 @@
/broken-pipe.sh/1.4/Mon Mar 26 21:06:58 2012//
/brokenkeys.sh/1.1/Mon Mar 26 21:06:58 2012//
/cert-hostkey.sh/1.6/Mon Mar 26 21:06:58 2012//
/cert-userkey.sh/1.8/Mon Mar 26 21:06:58 2012//
/cfgmatch.sh/1.6/Mon Mar 26 21:06:58 2012//
/conch-ciphers.sh/1.2/Mon Mar 26 21:06:58 2012//
/connect.sh/1.4/Mon Mar 26 21:06:58 2012//
@@ -62,8 +61,9 @@
/connect-privsep.sh/1.4/Thu Aug 9 18:41:57 2012//
/forwarding.sh/1.8/Thu Aug 9 18:41:57 2012//
/sftp-cmds.sh/1.12/Thu Aug 9 18:41:57 2012//
/cipher-speed.sh/1.6/Fri Oct 5 12:38:36 2012//
/multiplex.sh/1.17/Fri Oct 5 12:38:36 2012//
/sshd-log-wrapper.sh/1.2/Fri Sep 21 10:04:07 2012//
/try-ciphers.sh/1.15/Fri Oct 5 12:38:36 2012//
/cert-userkey.sh/1.9/Sat Nov 10 15:25:43 2012//
/cipher-speed.sh/1.6/Tue Oct 9 21:24:24 2012//
/multiplex.sh/1.17/Tue Oct 9 21:24:24 2012//
/try-ciphers.sh/1.15/Tue Oct 9 21:24:24 2012//
D

View File

@@ -1,4 +1,4 @@
# $OpenBSD: cert-userkey.sh,v 1.8 2011/05/17 07:13:31 djm Exp $
# $OpenBSD: cert-userkey.sh,v 1.9 2012/10/19 05:10:42 djm Exp $
# Placed in the Public Domain.
tid="certified user keys"
@@ -16,9 +16,8 @@ for ktype in rsa dsa ecdsa ; do
${SSHKEYGEN} -q -N '' -t ${ktype} \
-f $OBJ/cert_user_key_${ktype} || \
fail "ssh-keygen of cert_user_key_${ktype} failed"
${SSHKEYGEN} -q -s $OBJ/user_ca_key -I \
"regress user key for $USER" \
-n ${USER},mekmitasdigoat $OBJ/cert_user_key_${ktype} ||
${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \
-z $$ -n ${USER},mekmitasdigoat $OBJ/cert_user_key_${ktype} ||
fail "couldn't sign cert_user_key_${ktype}"
# v00 ecdsa certs do not exist
test "${ktype}" = "ecdsa" && continue

View File

@@ -1,7 +1,6 @@
/Makefile/1.15/Tue Feb 9 08:55:31 2010//
/Makefile.inc/1.39/Fri Oct 1 23:10:48 2010//
/OVERVIEW/1.11/Thu Aug 3 03:34:41 2006//
/auth.h/1.69/Mon May 23 03:30:07 2011//
/compat.h/1.43/Fri Sep 23 07:45:05 2011//
/dispatch.c/1.22/Fri Oct 31 15:05:34 2008//
/dispatch.h/1.11/Thu Apr 20 09:27:09 2006//
@@ -27,8 +26,6 @@ D/sshd////
/auth-options.c/1.56/Fri Jan 6 10:00:44 2012//
/auth-options.h/1.20/Fri Jan 6 10:00:44 2012//
/auth-rh-rsa.c/1.43/Fri Jan 6 10:00:44 2012//
/auth-rsa.c/1.80/Fri Jan 6 10:00:44 2012//
/auth1.c/1.75/Fri Jan 6 10:00:44 2012//
/auth2-chall.c/1.34/Fri Jan 6 10:00:45 2012//
/auth2-gss.c/1.17/Fri Jan 6 10:00:45 2012//
/auth2-hostbased.c/1.14/Fri Jan 6 10:00:45 2012//
@@ -36,8 +33,6 @@ D/sshd////
/auth2-kbdint.c/1.5/Fri Jan 6 10:00:45 2012//
/auth2-none.c/1.16/Fri Jan 6 10:00:45 2012//
/auth2-passwd.c/1.9/Fri Jan 6 10:00:45 2012//
/auth2-pubkey.c/1.30/Fri Jan 6 10:00:45 2012//
/auth2.c/1.124/Fri Jan 6 10:00:45 2012//
/authfd.c/1.86/Fri Jan 6 10:00:45 2012//
/authfd.h/1.37/Fri Jan 6 10:00:45 2012//
/authfile.h/1.16/Fri Jan 6 10:00:45 2012//
@@ -85,65 +80,36 @@ D/sshd////
/PROTOCOL.agent/1.6/Mon Mar 19 16:04:54 2012//
/README/1.7/Mon Mar 19 16:04:54 2012//
/addrmatch.c/1.6/Result of merge//
/atomicio.c/1.26/Mon Mar 19 16:04:54 2012//
/atomicio.h/1.11/Mon Mar 19 16:04:54 2012//
/auth-bsdauth.c/1.11/Mon Mar 19 16:04:54 2012//
/auth-chall.c/1.12/Mon Mar 19 16:04:54 2012//
/auth-krb5.c/1.19/Mon Mar 19 16:04:54 2012//
/auth-passwd.c/1.43/Mon Mar 19 16:04:54 2012//
/auth-rhosts.c/1.44/Mon Mar 19 16:04:54 2012//
/auth.c/1.96/Result of merge//
/channels.c/1.318/Result of merge//
/channels.h/1.111/Result of merge//
/cleanup.c/1.5/Mon Mar 19 16:04:54 2012//
/compress.c/1.26/Mon Jul 30 18:22:06 2012//
/compress.h/1.12/Mon Jul 30 18:22:06 2012//
/crc32.c/1.11/Mon Mar 19 16:04:54 2012//
/crc32.h/1.15/Mon Mar 19 16:04:54 2012//
/dns.h/1.12/Result of merge//
/fatal.c/1.7/Mon Mar 19 16:04:54 2012//
/groupaccess.c/1.13/Mon Mar 19 16:04:54 2012//
/groupaccess.h/1.8/Mon Mar 19 16:04:54 2012//
/gss-genr.c/1.20/Wed Mar 21 09:25:01 2012//
/gss-serv-krb5.c/1.7/Mon Mar 19 16:04:54 2012//
/gss-serv.c/1.23/Mon Mar 19 16:04:54 2012//
/jpake.h/1.2/Mon Mar 19 16:04:54 2012//
/key.h/1.34/Result of merge//
/match.h/1.15/Mon Mar 19 16:04:54 2012//
/monitor.h/1.16/Mon Mar 19 16:04:54 2012//
/monitor_fdpass.c/1.19/Mon Mar 19 16:04:54 2012//
/monitor_fdpass.h/1.4/Mon Mar 19 16:04:54 2012//
/monitor_mm.c/1.16/Mon Mar 19 16:04:54 2012//
/monitor_mm.h/1.5/Mon Mar 19 16:04:54 2012//
/msg.c/1.15/Mon Mar 19 16:04:54 2012//
/msg.h/1.4/Mon Mar 19 16:04:54 2012//
/nchan.ms/1.8/Mon Mar 19 16:04:54 2012//
/nchan2.ms/1.4/Mon Mar 19 16:04:54 2012//
/pathnames.h/1.22/Wed Apr 11 09:29:54 2012//
/pkcs11.h/1.2/Mon Mar 19 16:04:54 2012//
/progressmeter.c/1.37/Mon Mar 19 16:04:54 2012//
/progressmeter.h/1.2/Mon Mar 19 16:04:54 2012//
/readpass.c/1.48/Mon Mar 19 16:04:54 2012//
/roaming.h/1.6/Mon Mar 19 16:04:54 2012//
/roaming_common.c/1.9/Mon Mar 19 16:04:54 2012//
/sandbox-rlimit.c/1.3/Mon Mar 19 16:04:54 2012//
/schnorr.c/1.5/Wed Mar 21 09:25:01 2012//
/schnorr.h/1.1/Mon Mar 19 16:04:54 2012//
/scp.1/1.58/Mon Mar 19 16:04:54 2012//
/scp.c/1.171/Mon Mar 19 16:04:54 2012//
/serverloop.c/1.162/Result of merge//
/serverloop.h/1.6/Mon Mar 19 16:04:54 2012//
/session.c/1.260/Result of merge//
/session.h/1.30/Mon Mar 19 16:04:54 2012//
/sftp-client.h/1.20/Wed Mar 21 09:25:01 2012//
/sftp-common.c/1.23/Mon Mar 19 16:04:54 2012//
/sftp-common.h/1.11/Mon Mar 19 16:04:54 2012//
/sftp-glob.c/1.23/Mon Mar 19 16:04:54 2012//
/sftp-server-main.c/1.4/Mon Mar 19 16:04:54 2012//
/sftp-server.8/1.19/Mon Mar 19 16:04:54 2012//
/sftp-server.c/1.94/Wed Mar 21 09:25:01 2012//
/sftp.1/1.91/Mon Mar 19 16:04:54 2012//
/sftp.h/1.9/Mon Mar 19 16:04:54 2012//
/ssh-add.1/1.56/Mon Mar 19 16:04:54 2012//
/ssh-agent.1/1.53/Mon Mar 19 16:04:54 2012//
/ssh-gss.h/1.10/Mon Mar 19 16:04:54 2012//
@@ -151,25 +117,10 @@ D/sshd////
/ssh-keysign.8/1.12/Mon Mar 19 16:04:54 2012//
/ssh-pkcs11-client.c/1.3/Result of merge//
/ssh-pkcs11-helper.8/1.3/Mon Mar 19 16:04:54 2012//
/ssh-sandbox.h/1.1/Wed Apr 11 09:29:17 2012//
/ssh.h/1.79/Mon Mar 19 16:04:54 2012//
/ssh1.h/1.6/Mon Mar 19 16:04:54 2012//
/ssh2.h/1.14/Mon Mar 19 16:04:54 2012//
/ssh_config/1.26/Mon Mar 19 16:04:54 2012//
/sshconnect2.c/1.189/Result of merge//
/sshlogin.c/1.27/Mon Mar 19 16:04:54 2012//
/sshlogin.h/1.8/Mon Mar 19 16:04:54 2012//
/sshpty.c/1.28/Mon Mar 19 16:04:54 2012//
/sshpty.h/1.12/Mon Mar 19 16:04:54 2012//
/sshtty.c/1.14/Mon Mar 19 16:04:54 2012//
/ttymodes.c/1.29/Mon Mar 19 16:04:54 2012//
/ttymodes.h/1.14/Mon Mar 19 16:04:54 2012//
/uidswap.c/1.35/Mon Mar 19 16:04:54 2012//
/uidswap.h/1.13/Mon Mar 19 16:04:54 2012//
/uuencode.c/1.26/Mon Mar 19 16:04:54 2012//
/uuencode.h/1.14/Mon Mar 19 16:04:54 2012//
/xmalloc.c/1.27/Mon Mar 19 16:04:54 2012//
/xmalloc.h/1.13/Wed Mar 21 09:25:01 2012//
/PROTOCOL.certkeys/1.9/Thu Aug 9 18:41:57 2012//
/PROTOCOL.mux/1.9/Thu Aug 9 18:41:57 2012//
/authfile.c/1.93/Result of merge//
@@ -180,38 +131,87 @@ D/sshd////
/jpake.c/1.7/Thu Aug 9 18:41:57 2012//
/key.c/1.99/Result of merge//
/log.c/1.43/Result of merge//
/moduli.c/1.26/Thu Aug 9 18:41:57 2012//
/monitor.c/1.117/Result of merge//
/mux.c/1.37/Result of merge//
/packet.h/1.57/Result of merge//
/sandbox-systrace.c/1.6/Thu Aug 9 18:41:57 2012//
/servconf.c/1.230/Fri Sep 14 16:41:14 2012//
/servconf.h/1.103/Thu Aug 9 18:41:57 2012//
/sftp-client.c/1.97/Thu Aug 9 18:41:57 2012//
/ssh-keyscan.1/1.30/Thu Aug 9 18:41:57 2012//
/ssh-pkcs11-helper.c/1.4/Result of merge//
/ssh.c/1.370/Result of merge//
/sshd.c/1.393/Result of merge//
/sshd_config/1.87/Thu Aug 9 18:41:57 2012//
/version.h/1.65/Thu Aug 9 18:41:57 2012//
/kex.c/1.87/Result of merge//
/sshconnect.c/1.236/Result of merge//
/bufaux.c/1.50/Tue Sep 25 15:24:07 2012//
/bufbn.c/1.6/Tue Sep 25 15:24:07 2012//
/bufec.c/1.1/Tue Sep 25 15:24:07 2012//
/buffer.c/1.32/Tue Sep 25 15:24:07 2012//
/buffer.h/1.21/Tue Sep 25 15:24:07 2012//
/log.h/1.19/Mon Sep 17 19:41:04 2012//
/roaming_serv.c/1.1/Thu Sep 20 21:50:47 2012//
/ssh-keygen.1/1.110/Mon Sep 17 19:41:04 2012//
/packet.c/1.177/Result of merge//
/mac.c/1.19/Result of merge//
/ssh-keygen.c/1.218/Result of merge//
/monitor_wrap.c/1.74/Result of merge//
/myproposal.h/1.30/Thu Oct 4 13:30:40 2012//
/sftp.c/1.141/Result of merge//
/ssh.1/1.330/Thu Oct 4 13:30:40 2012//
/ssh_config.5/1.158/Thu Oct 4 13:30:40 2012//
/sshd.8/1.267/Thu Oct 4 13:30:40 2012//
/sshd_config.5/1.145/Thu Oct 4 13:30:40 2012//
/umac.h/1.2/Thu Oct 4 13:30:40 2012//
/atomicio.c/1.26/Fri Oct 12 15:53:54 2012//
/atomicio.h/1.11/Fri Oct 12 15:53:54 2012//
/auth-chall.c/1.12/Fri Oct 12 15:53:54 2012//
/auth-rsa.c/1.81/Result of merge//
/auth.c/1.97/Result of merge//
/auth.h/1.71/Result of merge//
/auth1.c/1.76/Result of merge//
/auth2-pubkey.c/1.32/Result of merge+Sat Nov 10 15:06:24 2012//
/auth2.c/1.125/Result of merge+Sat Nov 10 15:06:24 2012//
/bufaux.c/1.50/Fri Oct 12 15:53:55 2012//
/bufbn.c/1.6/Fri Oct 12 15:53:55 2012//
/bufec.c/1.1/Fri Oct 12 15:53:55 2012//
/buffer.c/1.32/Fri Oct 12 15:53:55 2012//
/buffer.h/1.21/Fri Oct 12 15:53:55 2012//
/cleanup.c/1.5/Fri Oct 12 15:53:55 2012//
/compress.c/1.26/Fri Oct 12 15:53:55 2012//
/compress.h/1.12/Fri Oct 12 15:53:55 2012//
/crc32.c/1.11/Fri Oct 12 15:53:55 2012//
/crc32.h/1.15/Fri Oct 12 15:53:55 2012//
/fatal.c/1.7/Fri Oct 12 15:53:55 2012//
/groupaccess.c/1.13/Fri Oct 12 15:53:55 2012//
/groupaccess.h/1.8/Fri Oct 12 15:53:55 2012//
/jpake.h/1.2/Fri Oct 12 15:53:55 2012//
/log.h/1.19/Fri Oct 12 15:53:55 2012//
/match.h/1.15/Fri Oct 12 15:53:55 2012//
/moduli.c/1.26/Fri Oct 12 15:53:55 2012//
/monitor.c/1.118/Result of merge//
/monitor_fdpass.c/1.19/Fri Oct 12 15:53:55 2012//
/monitor_fdpass.h/1.4/Fri Oct 12 15:53:55 2012//
/monitor_mm.c/1.16/Fri Oct 12 15:53:55 2012//
/monitor_mm.h/1.5/Fri Oct 12 15:53:55 2012//
/myproposal.h/1.30/Fri Oct 12 15:53:55 2012//
/pathnames.h/1.22/Fri Oct 12 15:53:55 2012//
/pkcs11.h/1.2/Fri Oct 12 15:53:55 2012//
/progressmeter.c/1.37/Fri Oct 12 15:53:55 2012//
/progressmeter.h/1.2/Fri Oct 12 15:53:55 2012//
/readpass.c/1.48/Fri Oct 12 15:53:55 2012//
/roaming_serv.c/1.1/Fri Oct 12 15:53:55 2012//
/sandbox-rlimit.c/1.3/Fri Oct 12 15:53:55 2012//
/sandbox-systrace.c/1.6/Fri Oct 12 15:53:55 2012//
/schnorr.h/1.1/Fri Oct 12 15:53:55 2012//
/scp.c/1.171/Fri Oct 12 15:53:55 2012//
/servconf.c/1.232/Result of merge+Sat Nov 10 15:06:25 2012//
/servconf.h/1.105/Result of merge//
/sftp-client.h/1.20/Fri Oct 12 15:53:55 2012//
/sftp-server-main.c/1.4/Fri Oct 12 15:53:55 2012//
/sftp.h/1.9/Fri Oct 12 15:53:55 2012//
/ssh-sandbox.h/1.1/Fri Oct 12 15:53:56 2012//
/ssh.1/1.330/Tue Oct 9 21:24:24 2012//
/ssh.h/1.79/Fri Oct 12 15:54:04 2012//
/ssh1.h/1.6/Fri Oct 12 15:53:56 2012//
/ssh2.h/1.14/Fri Oct 12 15:53:56 2012//
/ssh_config.5/1.158/Tue Oct 9 21:24:24 2012//
/sshd.8/1.267/Tue Oct 9 21:24:24 2012//
/sshd.c/1.396/Result of merge//
/sshd_config/1.88/Sat Nov 10 15:06:26 2012//
/sshd_config.5/1.149/Sat Nov 10 15:06:26 2012//
/sshlogin.h/1.8/Fri Oct 12 15:53:56 2012//
/sshpty.c/1.28/Fri Oct 12 15:53:56 2012//
/sshpty.h/1.12/Fri Oct 12 15:53:56 2012//
/sshtty.c/1.14/Fri Oct 12 15:53:56 2012//
/ttymodes.h/1.14/Fri Oct 12 15:53:56 2012//
/uidswap.c/1.35/Fri Oct 12 15:53:56 2012//
/uidswap.h/1.13/Fri Oct 12 15:53:56 2012//
/uuencode.c/1.26/Fri Oct 12 15:53:56 2012//
/uuencode.h/1.14/Fri Oct 12 15:53:56 2012//
/version.h/1.65/Fri Oct 12 15:53:56 2012//
/xmalloc.c/1.27/Fri Oct 12 15:53:56 2012//
/xmalloc.h/1.13/Fri Oct 12 15:53:56 2012//

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: auth-rsa.c,v 1.80 2011/05/23 03:30:07 djm Exp $ */
/* $OpenBSD: auth-rsa.c,v 1.81 2012/10/30 21:29:54 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -280,6 +280,8 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n,
temporarily_use_uid(pw);
for (i = 0; !allowed && i < options.num_authkeys_files; i++) {
if (strcasecmp(options.authorized_keys_files[i], "none") == 0)
continue;
file = expand_authorized_keys(
options.authorized_keys_files[i], pw);
allowed = rsa_key_allowed_in_file(pw, file, client_n, rkey);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: auth.c,v 1.96 2012/05/13 01:42:32 dtucker Exp $ */
/* $OpenBSD: auth.c,v 1.97 2012/10/30 21:29:54 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -322,41 +322,42 @@ check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host,
return host_status;
}
/*
* Check a given file for security. This is defined as all components
* Check a given path for security. This is defined as all components
* of the path to the file must be owned by either the owner of
* of the file or root and no directories must be group or world writable.
*
* XXX Should any specific check be done for sym links ?
*
* Takes an open file descriptor, the file name, a uid and and
* Takes an the file name, its stat information (preferably from fstat() to
* avoid races), the uid of the expected owner, their home directory and an
* error buffer plus max size as arguments.
*
* Returns 0 on success and -1 on failure
*/
static int
secure_filename(FILE *f, const char *file, struct passwd *pw,
char *err, size_t errlen)
int
auth_secure_path(const char *name, struct stat *stp, const char *pw_dir,
uid_t uid, char *err, size_t errlen)
{
uid_t uid = pw->pw_uid;
char buf[MAXPATHLEN], homedir[MAXPATHLEN];
char *cp;
int comparehome = 0;
struct stat st;
if (realpath(file, buf) == NULL) {
snprintf(err, errlen, "realpath %s failed: %s", file,
if (realpath(name, buf) == NULL) {
snprintf(err, errlen, "realpath %s failed: %s", name,
strerror(errno));
return -1;
}
if (realpath(pw->pw_dir, homedir) != NULL)
if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL)
comparehome = 1;
/* check the open file to avoid races */
if (fstat(fileno(f), &st) < 0 ||
(st.st_uid != 0 && st.st_uid != uid) ||
(st.st_mode & 022) != 0) {
if (!S_ISREG(stp->st_mode)) {
snprintf(err, errlen, "%s is not a regular file", buf);
return -1;
}
if ((stp->st_uid != 0 && stp->st_uid != uid) ||
(stp->st_mode & 022) != 0) {
snprintf(err, errlen, "bad ownership or modes for file %s",
buf);
return -1;
@@ -392,6 +393,28 @@ secure_filename(FILE *f, const char *file, struct passwd *pw,
return 0;
}
/*
* Version of secure_path() that accepts an open file descriptor to
* avoid races.
*
* Returns 0 on success and -1 on failure
*/
static int
secure_filename(FILE *f, const char *file, struct passwd *pw,
char *err, size_t errlen)
{
char buf[MAXPATHLEN];
struct stat st;
/* check the open file to avoid races */
if (fstat(fileno(f), &st) < 0) {
snprintf(err, errlen, "cannot stat file %s: %s",
buf, strerror(errno));
return -1;
}
return auth_secure_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen);
}
static FILE *
auth_openfile(const char *file, struct passwd *pw, int strict_modes,
int log_missing, char *file_type)

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: auth.h,v 1.69 2011/05/23 03:30:07 djm Exp $ */
/* $OpenBSD: auth.h,v 1.71 2012/11/04 11:09:15 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -58,6 +58,8 @@ struct Authctxt {
void *kbdintctxt;
void *jpake_ctx;
auth_session_t *as;
char **auth_methods; /* modified from server config */
u_int num_auth_methods;
#ifdef KRB5
krb5_context krb5_ctx;
krb5_ccache krb5_fwd_ccache;
@@ -114,6 +116,10 @@ int hostbased_key_allowed(struct passwd *, const char *, char *,
struct sshkey *);
int user_key_allowed(struct passwd *, struct sshkey *);
struct stat;
int auth_secure_path(const char *, struct stat *, const char *, uid_t,
char *, size_t);
#ifdef KRB5
int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *);
int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt);
@@ -129,6 +135,9 @@ void userauth_finish(struct ssh *, int, char *);
int auth_root_allowed(char *);
char *auth2_read_banner(void);
int auth2_methods_valid(const char *, int);
int auth2_update_methods_lists(Authctxt *, const char *);
int auth2_setup_methods_lists(Authctxt *);
void privsep_challenge_enable(void);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: auth1.c,v 1.75 2010/08/31 09:58:37 djm Exp $ */
/* $OpenBSD: auth1.c,v 1.76 2012/11/04 11:09:15 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -357,6 +357,11 @@ do_authentication(struct ssh *ssh)
authctxt->pw = fakepw();
}
/* Configuration may have changed as a result of Match */
if (options.num_auth_methods != 0)
fatal("AuthenticationMethods is not supported with SSH "
"protocol 1");
setproctitle("%s%s", authctxt->valid ? user : "unknown",
use_privsep ? " [net]" : "");

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: auth2-pubkey.c,v 1.30 2011/09/25 05:44:47 djm Exp $ */
/* $OpenBSD: auth2-pubkey.c,v 1.32 2012/11/04 10:38:43 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -26,9 +26,13 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <paths.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
@@ -279,31 +283,22 @@ match_principals_file(char *file, struct passwd *pw, struct sshkey_cert *cert)
fclose(f);
restore_uid();
return 0;
}
}
/* return 1 if user allows given key */
/*
* Checks whether key is allowed in authorized_keys-format file,
* returns 1 if the key is allowed or 0 otherwise.
*/
static int
user_key_allowed2(struct passwd *pw, struct sshkey *key, char *file)
check_authkeys_file(FILE *f, char *file, struct sshkey *key, struct passwd *pw)
{
char line[SSH_MAX_PUBKEY_BYTES];
const char *reason;
int found_key = 0;
FILE *f;
u_long linenum = 0;
struct sshkey *found = NULL;
char *fp;
/* Temporarily use the user's uid. */
temporarily_use_uid(pw);
debug("trying public key file %s", file);
f = auth_openkeyfile(file, pw, options.strict_modes);
if (!f) {
restore_uid();
return 0;
}
found_key = 0;
found = sshkey_new(sshkey_is_cert(key) ? KEY_UNSPEC : key->type);
if (found == NULL)
@@ -399,8 +394,6 @@ user_key_allowed2(struct passwd *pw, struct sshkey *key, char *file)
}
}
done:
restore_uid();
fclose(f);
if (found != NULL)
sshkey_free(found);
if (!found_key)
@@ -470,7 +463,176 @@ user_cert_trusted_ca(struct passwd *pw, struct sshkey *key)
return ret;
}
/* check whether given key is in .ssh/authorized_keys* */
/*
* Checks whether key is allowed in file.
* returns 1 if the key is allowed or 0 otherwise.
*/
static int
user_key_allowed2(struct passwd *pw, struct sshkey *key, char *file)
{
FILE *f;
int found_key = 0;
/* Temporarily use the user's uid. */
temporarily_use_uid(pw);
debug("trying public key file %s", file);
if ((f = auth_openkeyfile(file, pw, options.strict_modes)) != NULL) {
found_key = check_authkeys_file(f, file, key, pw);
fclose(f);
}
restore_uid();
return found_key;
}
/*
* Checks whether key is allowed in output of command.
* returns 1 if the key is allowed or 0 otherwise.
*/
static int
user_key_command_allowed2(struct passwd *user_pw, struct sshkey *key)
{
FILE *f;
int ok, found_key = 0;
struct passwd *pw;
struct stat st;
int status, devnull, p[2], i;
pid_t pid;
char *username, errmsg[512];
if (options.authorized_keys_command == NULL ||
options.authorized_keys_command[0] != '/')
return 0;
if (options.authorized_keys_command_user == NULL) {
error("No user for AuthorizedKeysCommand specified, skipping");
return 0;
}
username = percent_expand(options.authorized_keys_command_user,
"u", user_pw->pw_name, (char *)NULL);
pw = getpwnam(username);
if (pw == NULL) {
error("AuthorizedKeyCommandUser \"%s\" not found: %s",
options.authorized_keys_command, strerror(errno));
free(username);
return 0;
}
free(username);
temporarily_use_uid(pw);
if (stat(options.authorized_keys_command, &st) < 0) {
error("Could not stat AuthorizedKeysCommand \"%s\": %s",
options.authorized_keys_command, strerror(errno));
goto out;
}
if (auth_secure_path(options.authorized_keys_command, &st, NULL, 0,
errmsg, sizeof(errmsg)) != 0) {
error("Unsafe AuthorizedKeysCommand: %s", errmsg);
goto out;
}
if (pipe(p) != 0) {
error("%s: pipe: %s", __func__, strerror(errno));
goto out;
}
debug3("Running AuthorizedKeysCommand: \"%s\" as \"%s\"",
options.authorized_keys_command, pw->pw_name);
/*
* Don't want to call this in the child, where it can fatal() and
* run cleanup_exit() code.
*/
restore_uid();
switch ((pid = fork())) {
case -1: /* error */
error("%s: fork: %s", __func__, strerror(errno));
close(p[0]);
close(p[1]);
return 0;
case 0: /* child */
for (i = 0; i < NSIG; i++)
signal(i, SIG_DFL);
closefrom(STDERR_FILENO + 1);
/* Don't use permanently_set_uid() here to avoid fatal() */
if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) {
error("setresgid %u: %s", (u_int)pw->pw_gid,
strerror(errno));
_exit(1);
}
if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) {
error("setresuid %u: %s", (u_int)pw->pw_uid,
strerror(errno));
_exit(1);
}
close(p[0]);
if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
error("%s: open %s: %s", __func__, _PATH_DEVNULL,
strerror(errno));
_exit(1);
}
if (dup2(devnull, STDIN_FILENO) == -1 ||
dup2(p[1], STDOUT_FILENO) == -1 ||
dup2(devnull, STDERR_FILENO) == -1) {
error("%s: dup2: %s", __func__, strerror(errno));
_exit(1);
}
execl(options.authorized_keys_command,
options.authorized_keys_command, pw->pw_name, NULL);
error("AuthorizedKeysCommand %s exec failed: %s",
options.authorized_keys_command, strerror(errno));
_exit(127);
default: /* parent */
break;
}
temporarily_use_uid(pw);
close(p[1]);
if ((f = fdopen(p[0], "r")) == NULL) {
error("%s: fdopen: %s", __func__, strerror(errno));
close(p[0]);
/* Don't leave zombie child */
kill(pid, SIGTERM);
while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
;
goto out;
}
ok = check_authkeys_file(f, options.authorized_keys_command, key, pw);
fclose(f);
while (waitpid(pid, &status, 0) == -1) {
if (errno != EINTR) {
error("%s: waitpid: %s", __func__, strerror(errno));
goto out;
}
}
if (WIFSIGNALED(status)) {
error("AuthorizedKeysCommand %s exited on signal %d",
options.authorized_keys_command, WTERMSIG(status));
goto out;
} else if (WEXITSTATUS(status) != 0) {
error("AuthorizedKeysCommand %s returned status %d",
options.authorized_keys_command, WEXITSTATUS(status));
goto out;
}
found_key = ok;
out:
restore_uid();
return found_key;
}
/*
* Check whether key authenticates and authorises the user.
*/
int
user_key_allowed(struct passwd *pw, struct sshkey *key)
{
@@ -487,9 +649,17 @@ user_key_allowed(struct passwd *pw, struct sshkey *key)
if (success)
return success;
success = user_key_command_allowed2(pw, key);
if (success > 0)
return success;
for (i = 0; !success && i < options.num_authkeys_files; i++) {
if (strcasecmp(options.authorized_keys_files[i], "none") == 0)
continue;
file = expand_authorized_keys(
options.authorized_keys_files[i], pw);
success = user_key_allowed2(pw, key, file);
xfree(file);
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: auth2.c,v 1.124 2011/12/07 05:44:38 djm Exp $ */
/* $OpenBSD: auth2.c,v 1.125 2012/11/04 11:09:15 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -93,8 +93,10 @@ static int input_service_request(int, u_int32_t, struct ssh *);
static int input_userauth_request(int, u_int32_t, struct ssh *);
/* helper */
static Authmethod *authmethod_lookup(const char *);
static char *authmethods_get(void);
static Authmethod *authmethod_lookup(Authctxt *, const char *);
static char *authmethods_get(Authctxt *authctxt);
static int method_allowed(Authctxt *, const char *);
static int list_starts_with(const char *, const char *);
char *
auth2_read_banner(void)
@@ -250,6 +252,9 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
if (use_privsep)
mm_inform_authserv(service, style);
userauth_banner(ssh);
if (auth2_setup_methods_lists(authctxt) != 0)
ssh_packet_disconnect(ssh,
"no authentication methods enabled");
} else if (strcmp(user, authctxt->user) != 0 ||
strcmp(service, authctxt->service) != 0) {
ssh_packet_disconnect(ssh, "Change of username or service not allowed: "
@@ -272,7 +277,7 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
authctxt->server_caused_failure = 0;
/* try to authenticate user */
m = authmethod_lookup(method);
m = authmethod_lookup(authctxt, method);
if (m != NULL && authctxt->failures < options.max_authtries) {
debug2("input_userauth_request: try method %s", method);
authenticated = m->userauth(ssh);
@@ -292,7 +297,7 @@ userauth_finish(struct ssh *ssh, int authenticated, char *method)
{
Authctxt *authctxt = ssh->authctxt;
char *methods;
int r;
int r, partial = 0;
if (!authctxt->valid && authenticated)
fatal("INTERNAL ERROR: authenticated invalid user %s",
@@ -309,7 +314,13 @@ userauth_finish(struct ssh *ssh, int authenticated, char *method)
if (authctxt->postponed)
return;
/* XXX todo: check if multiple auth methods are needed */
if (authenticated && options.num_auth_methods != 0) {
if (!auth2_update_methods_lists(authctxt, method)) {
authenticated = 0;
partial = 1;
}
}
if (authenticated == 1) {
/* turn off userauth */
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST,
@@ -328,10 +339,12 @@ userauth_finish(struct ssh *ssh, int authenticated, char *method)
if (authctxt->failures >= options.max_authtries)
ssh_packet_disconnect(ssh, AUTH_FAIL_MSG,
authctxt->user);
methods = authmethods_get();
methods = authmethods_get(authctxt);
debug3("%s: failure partial=%d next methods=\"%s\"", __func__,
partial, methods);
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_FAILURE)) != 0 ||
(r = sshpkt_put_cstring(ssh, methods)) != 0 ||
(r = sshpkt_put_u8(ssh, 0)) != 0 || /* partial success XXX */
(r = sshpkt_put_u8(ssh, partial)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
ssh_packet_write_wait(ssh);
@@ -339,8 +352,31 @@ userauth_finish(struct ssh *ssh, int authenticated, char *method)
}
}
/*
* Checks whether method is allowed by at least one AuthenticationMethods
* methods list. Returns 1 if allowed, or no methods lists configured.
* 0 otherwise.
*/
static int
method_allowed(Authctxt *authctxt, const char *method)
{
u_int i;
/*
* NB. authctxt->num_auth_methods might be zero as a result of
* auth2_setup_methods_lists(), so check the configuration.
*/
if (options.num_auth_methods == 0)
return 1;
for (i = 0; i < authctxt->num_auth_methods; i++) {
if (list_starts_with(authctxt->auth_methods[i], method))
return 1;
}
return 0;
}
static char *
authmethods_get(void)
authmethods_get(Authctxt *authctxt)
{
struct sshbuf *b;
char *list;
@@ -354,6 +390,8 @@ authmethods_get(void)
if (authmethods[i]->enabled == NULL ||
*(authmethods[i]->enabled) == 0)
continue;
if (!method_allowed(authctxt, authmethods[i]->name))
continue;
if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) ? "," : "",
authmethods[i]->name)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
@@ -366,7 +404,7 @@ authmethods_get(void)
}
static Authmethod *
authmethod_lookup(const char *name)
authmethod_lookup(Authctxt *authctxt, const char *name)
{
int i;
@@ -374,9 +412,152 @@ authmethod_lookup(const char *name)
for (i = 0; authmethods[i] != NULL; i++)
if (authmethods[i]->enabled != NULL &&
*(authmethods[i]->enabled) != 0 &&
strcmp(name, authmethods[i]->name) == 0)
strcmp(name, authmethods[i]->name) == 0 &&
method_allowed(authctxt, authmethods[i]->name))
return authmethods[i];
debug2("Unrecognized authentication method name: %s",
name ? name : "NULL");
return NULL;
}
/*
* Check a comma-separated list of methods for validity. Is need_enable is
* non-zero, then also require that the methods are enabled.
* Returns 0 on success or -1 if the methods list is invalid.
*/
int
auth2_methods_valid(const char *_methods, int need_enable)
{
char *methods, *omethods, *method;
u_int i, found;
int ret = -1;
if (*_methods == '\0') {
error("empty authentication method list");
return -1;
}
omethods = methods = xstrdup(_methods);
while ((method = strsep(&methods, ",")) != NULL) {
for (found = i = 0; !found && authmethods[i] != NULL; i++) {
if (strcmp(method, authmethods[i]->name) != 0)
continue;
if (need_enable) {
if (authmethods[i]->enabled == NULL ||
*(authmethods[i]->enabled) == 0) {
error("Disabled method \"%s\" in "
"AuthenticationMethods list \"%s\"",
method, _methods);
goto out;
}
}
found = 1;
break;
}
if (!found) {
error("Unknown authentication method \"%s\" in list",
method);
goto out;
}
}
ret = 0;
out:
free(omethods);
return ret;
}
/*
* Prune the AuthenticationMethods supplied in the configuration, removing
* any methods lists that include disabled methods. Note that this might
* leave authctxt->num_auth_methods == 0, even when multiple required auth
* has been requested. For this reason, all tests for whether multiple is
* enabled should consult options.num_auth_methods directly.
*/
int
auth2_setup_methods_lists(Authctxt *authctxt)
{
u_int i;
if (options.num_auth_methods == 0)
return 0;
debug3("%s: checking methods", __func__);
authctxt->auth_methods = xcalloc(options.num_auth_methods,
sizeof(*authctxt->auth_methods));
authctxt->num_auth_methods = 0;
for (i = 0; i < options.num_auth_methods; i++) {
if (auth2_methods_valid(options.auth_methods[i], 1) != 0) {
logit("Authentication methods list \"%s\" contains "
"disabled method, skipping",
options.auth_methods[i]);
continue;
}
debug("authentication methods list %d: %s",
authctxt->num_auth_methods, options.auth_methods[i]);
authctxt->auth_methods[authctxt->num_auth_methods++] =
xstrdup(options.auth_methods[i]);
}
if (authctxt->num_auth_methods == 0) {
error("No AuthenticationMethods left after eliminating "
"disabled methods");
return -1;
}
return 0;
}
static int
list_starts_with(const char *methods, const char *method)
{
size_t l = strlen(method);
if (strncmp(methods, method, l) != 0)
return 0;
if (methods[l] != ',' && methods[l] != '\0')
return 0;
return 1;
}
/*
* Remove method from the start of a comma-separated list of methods.
* Returns 0 if the list of methods did not start with that method or 1
* if it did.
*/
static int
remove_method(char **methods, const char *method)
{
char *omethods = *methods;
size_t l = strlen(method);
if (!list_starts_with(omethods, method))
return 0;
*methods = xstrdup(omethods + l + (omethods[l] == ',' ? 1 : 0));
free(omethods);
return 1;
}
/*
* Called after successful authentication. Will remove the successful method
* from the start of each list in which it occurs. If it was the last method
* in any list, then authentication is deemed successful.
* Returns 1 if the method completed any authentication list or 0 otherwise.
*/
int
auth2_update_methods_lists(Authctxt *authctxt, const char *method)
{
u_int i, found = 0;
debug3("%s: updating methods list after \"%s\"", __func__, method);
for (i = 0; i < authctxt->num_auth_methods; i++) {
if (!remove_method(&(authctxt->auth_methods[i]), method))
continue;
found = 1;
if (*authctxt->auth_methods[i] == '\0') {
debug2("authentication methods list %d complete", i);
return 1;
}
debug3("authentication methods list %d remaining: \"%s\"",
i, authctxt->auth_methods[i]);
}
/* This should not happen, but would be bad if it did */
if (!found)
fatal("%s: method not in AuthenticationMethods", __func__);
return 0;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: monitor.c,v 1.117 2012/06/22 12:30:26 dtucker Exp $ */
/* $OpenBSD: monitor.c,v 1.118 2012/11/04 11:09:15 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -275,6 +275,21 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
while (!authenticated) {
auth_method = "unknown";
authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1);
/* Special handling for multiple required authentications */
if (options.num_auth_methods != 0) {
if (!compat20)
fatal("AuthenticationMethods is not supported"
"with SSH protocol 1");
if (authenticated &&
!auth2_update_methods_lists(authctxt,
auth_method)) {
debug3("%s: method %s: partial", __func__,
auth_method);
authenticated = 0;
}
}
if (authenticated) {
if (!(ent->flags & MON_AUTHDECIDE))
fatal("%s: unexpected authentication from %d",
@@ -283,7 +298,6 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
!auth_root_allowed(auth_method))
authenticated = 0;
}
if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) {
auth_log(authctxt, authenticated, auth_method,
compat20 ? " ssh2" : "");
@@ -704,7 +718,17 @@ mm_answer_pwnamallow(int sock, struct sshbuf *m)
COPY_MATCH_STRING_OPTS();
#undef M_CP_STROPT
#undef M_CP_STRARRAYOPT
/* Create valid auth method lists */
if (compat20 && auth2_setup_methods_lists(authctxt) != 0) {
/*
* The monitor will continue long enough to let the child
* run to it's packet_disconnect(), but it must not allow any
* authentication to succeed.
*/
debug("%s: no valid authentication method lists", __func__);
}
debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed);
mm_request_send(sock, MONITOR_ANS_PWNAM, m);
@@ -843,7 +867,10 @@ mm_answer_bsdauthrespond(int sock, struct sshbuf *m)
debug3("%s: sending authenticated: %d", __func__, authok);
mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m);
auth_method = "bsdauth";
if (compat20)
auth_method = "keyboard-interactive";
else
auth_method = "bsdauth";
return (authok != 0);
}

View File

@@ -1,5 +1,5 @@
/* $OpenBSD: servconf.c,v 1.230 2012/09/13 23:37:36 dtucker Exp $ */
/* $OpenBSD: servconf.c,v 1.232 2012/11/04 11:09:15 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -47,6 +47,8 @@
#include "canohost.h"
#include "packet.h"
#include "err.h"
#include "hostfile.h"
#include "auth.h"
static void add_listen_addr(ServerOptions *, char *, int);
static void add_one_listen_addr(ServerOptions *, char *, int);
@@ -129,6 +131,8 @@ initialize_server_options(ServerOptions *options)
options->num_permitted_opens = -1;
options->adm_forced_command = NULL;
options->chroot_directory = NULL;
options->authorized_keys_command = NULL;
options->authorized_keys_command_user = NULL;
options->zero_knowledge_password_authentication = -1;
options->revoked_keys_file = NULL;
options->trusted_user_ca_keys = NULL;
@@ -303,6 +307,8 @@ typedef enum {
sZeroKnowledgePasswordAuthentication, sHostCertificate,
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
sKexAlgorithms, sIPQoS, sVersionAddendum,
sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
sAuthenticationMethods,
sDeprecated, sUnsupported
} ServerOpCodes;
@@ -415,7 +421,10 @@ static struct {
{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
{ "ipqos", sIPQoS, SSHCFG_ALL },
{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
{ "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
{ NULL, sBadOption, 0 }
};
@@ -1455,6 +1464,43 @@ process_server_config_line(ServerOptions *options, char *line,
}
return 0;
case sAuthorizedKeysCommand:
len = strspn(cp, WHITESPACE);
if (*activep && options->authorized_keys_command == NULL) {
if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0)
fatal("%.200s line %d: AuthorizedKeysCommand "
"must be an absolute path",
filename, linenum);
options->authorized_keys_command = xstrdup(cp + len);
}
return 0;
case sAuthorizedKeysCommandUser:
charptr = &options->authorized_keys_command_user;
arg = strdelim(&cp);
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
break;
case sAuthenticationMethods:
if (*activep && options->num_auth_methods == 0) {
while ((arg = strdelim(&cp)) && *arg != '\0') {
if (options->num_auth_methods >=
MAX_AUTH_METHODS)
fatal("%s line %d: "
"too many authentication methods.",
filename, linenum);
if (auth2_methods_valid(arg, 0) != 0)
fatal("%s line %d: invalid "
"authentication method list.",
filename, linenum);
options->auth_methods[
options->num_auth_methods++] = xstrdup(arg);
}
}
return 0;
case sDeprecated:
logit("%s line %d: Deprecated option %s",
filename, linenum, arg);
@@ -1606,6 +1652,8 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
M_CP_INTOPT(hostbased_uses_name_from_packet_only);
M_CP_INTOPT(kbd_interactive_authentication);
M_CP_INTOPT(zero_knowledge_password_authentication);
M_CP_STROPT(authorized_keys_command);
M_CP_STROPT(authorized_keys_command_user);
M_CP_INTOPT(permit_root_login);
M_CP_INTOPT(permit_empty_passwd);
@@ -1861,6 +1909,8 @@ dump_config(ServerOptions *o)
dump_cfg_string(sAuthorizedPrincipalsFile,
o->authorized_principals_file);
dump_cfg_string(sVersionAddendum, o->version_addendum);
dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
/* string arguments requiring a lookup */
dump_cfg_string(sLogLevel, log_level_name(o->log_level));
@@ -1878,6 +1928,8 @@ dump_config(ServerOptions *o)
dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
dump_cfg_strarray_oneline(sAuthenticationMethods,
o->num_auth_methods, o->auth_methods);
/* other arguments */
for (i = 0; i < o->num_subsystems; i++)

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: servconf.h,v 1.103 2012/07/10 02:19:15 djm Exp $ */
/* $OpenBSD: servconf.h,v 1.105 2012/11/04 11:09:15 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -28,6 +28,7 @@
#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. */
#define MAX_AUTH_METHODS 256 /* Max # of AuthenticationMethods. */
/* permit_root_login */
#define PERMIT_NOT_SET -1
@@ -164,8 +165,13 @@ typedef struct {
char *revoked_keys_file;
char *trusted_user_ca_keys;
char *authorized_principals_file;
char *authorized_keys_command;
char *authorized_keys_command_user;
char *version_addendum; /* Appended to SSH banner */
u_int num_auth_methods;
char *auth_methods[MAX_AUTH_METHODS];
} ServerOptions;
/* Information about the incoming connection as used by Match */
@@ -195,6 +201,7 @@ struct connection_info {
M_CP_STRARRAYOPT(allow_groups, num_allow_groups); \
M_CP_STRARRAYOPT(deny_groups, num_deny_groups); \
M_CP_STRARRAYOPT(accept_env, num_accept_env); \
M_CP_STRARRAYOPT(auth_methods, num_auth_methods); \
} while (0)
struct sshbuf;

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: sshd.c,v 1.393 2012/07/10 02:19:15 djm Exp $ */
/* $OpenBSD: sshd.c,v 1.396 2012/11/04 11:09:15 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -337,6 +337,15 @@ grace_alarm_handler(int sig)
if (use_privsep && pmonitor != NULL && pmonitor->m_pid > 0)
kill(pmonitor->m_pid, SIGALRM);
/*
* Try to kill any processes that we have spawned, E.g. authorized
* keys command helpers.
*/
if (getpgid(0) == getpid()) {
signal(SIGTERM, SIG_IGN);
killpg(0, SIGTERM);
}
/* Log error and exit. */
sigdie("Timeout before authentication for %s",
ssh_remote_ipaddr(active_state));
@@ -1333,6 +1342,7 @@ main(int ac, char **av)
int r, remote_port;
char *line;
int config_s[2] = { -1 , -1 };
u_int n;
u_int64_t ibytes, obytes;
mode_t new_umask;
struct sshkey *key;
@@ -1522,6 +1532,33 @@ main(int ac, char **av)
if (options.challenge_response_authentication)
options.kbd_interactive_authentication = 1;
/* Check that options are sensible */
if (options.authorized_keys_command_user == NULL &&
(options.authorized_keys_command != NULL &&
strcasecmp(options.authorized_keys_command, "none") != 0))
fatal("AuthorizedKeysCommand set without "
"AuthorizedKeysCommandUser");
/*
* Check whether there is any path through configured auth methods.
* Unfortunately it is not possible to verify this generally before
* daemonisation in the presence of Match block, but this catches
* and warns for trivial misconfigurations that could break login.
*/
if (options.num_auth_methods != 0) {
if ((options.protocol & SSH_PROTO_1))
fatal("AuthenticationMethods is not supported with "
"SSH protocol 1");
for (n = 0; n < options.num_auth_methods; n++) {
if (auth2_methods_valid(options.auth_methods[n],
1) == 0)
break;
}
if (n >= options.num_auth_methods)
fatal("AuthenticationMethods cannot be satisfied by "
"enabled authentication methods");
}
/* set default channel AF */
channel_set_af(options.address_family);

View File

@@ -1,4 +1,4 @@
# $OpenBSD: sshd_config,v 1.87 2012/07/10 02:19:15 djm Exp $
# $OpenBSD: sshd_config,v 1.88 2012/10/30 21:29:55 djm Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
@@ -49,6 +49,9 @@ AuthorizedKeysFile .ssh/authorized_keys
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#RhostsRSAAuthentication no
# similar for protocol version 2

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: sshd_config.5,v 1.145 2012/10/04 13:21:50 markus Exp $
.Dd $Mdocdate: October 4 2012 $
.\" $OpenBSD: sshd_config.5,v 1.149 2012/11/04 11:09:15 djm Exp $
.Dd $Mdocdate: November 4 2012 $
.Dt SSHD_CONFIG 5
.Os
.Sh NAME
@@ -151,6 +151,45 @@ See
in
.Xr ssh_config 5
for more information on patterns.
.It Cm AuthenticationMethods
Specifies the authentication methods that must be successfully completed
for a user to be granted access.
This option must be followed by one or more comma-separated lists of
authentication method names.
Successful authentication requires completion of every method in at least
one of these lists.
.Pp
For example, an argument of
.Dq publickey,password publickey,keyboard-interactive
would require the user to complete public key authentication, followed by
either password or keyboard interactive authentication.
Only methods that are next in one or more lists are offered at each stage,
so for this example, it would not be possible to attempt password or
keyboard-interactive authentication before public key.
.Pp
This option is only available for SSH protocol 2 and will yield a fatal
error if enabled if protocol 1 is also enabled.
Note that each authentication method listed should also be explicitly enabled
in the configuration.
The default is not to require multiple authentication; successful completion
of a single authentication method is sufficient.
.It Cm AuthorizedKeysCommand
Specifies a program to be used to look up the user's public keys.
The program will be invoked with a single argument of the username
being authenticated, and should produce on standard output zero or
more lines of authorized_keys output (see
.Sx AUTHORIZED_KEYS
in
.Xr sshd 8 ) .
If a key supplied by AuthorizedKeysCommand does not successfully authenticate
and authorize the user then public key authentication continues using the usual
.Cm AuthorizedKeysFile
files.
By default, no AuthorizedKeysCommand is run.
.It Cm AuthorizedKeysCommandUser
Specifies the user under whose account the AuthorizedKeysCommand is run.
It is recommended to use a dedicated user that has no other role on the host
than running authorized keys commands.
.It Cm AuthorizedKeysFile
Specifies the file that contains the public keys that can be used
for user authentication.
@@ -712,6 +751,9 @@ Available keywords are
.Cm AllowGroups ,
.Cm AllowTcpForwarding ,
.Cm AllowUsers ,
.Cm AuthenticationMethods ,
.Cm AuthorizedKeysCommand ,
.Cm AuthorizedKeysCommandUser ,
.Cm AuthorizedKeysFile ,
.Cm AuthorizedPrincipalsFile ,
.Cm Banner ,