mirror of
https://github.com/openssh/libopenssh
synced 2026-04-15 17:26:14 +00:00
sync cvs as of 2012-11-10
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
138
ssh/CVS/Entries
138
ssh/CVS/Entries
@@ -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//
|
||||
|
||||
@@ -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);
|
||||
|
||||
53
ssh/auth.c
53
ssh/auth.c
@@ -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)
|
||||
|
||||
11
ssh/auth.h
11
ssh/auth.h
@@ -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);
|
||||
|
||||
|
||||
@@ -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]" : "");
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
203
ssh/auth2.c
203
ssh/auth2.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -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;
|
||||
|
||||
39
ssh/sshd.c
39
ssh/sshd.c
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
Reference in New Issue
Block a user