Upgrade to OpenSSH 5.9p1.

MFC after:	3 months
This commit is contained in:
Dag-Erling Smørgrav 2011-10-05 22:08:17 +00:00
commit e146993e33
87 changed files with 2774 additions and 1998 deletions

View File

@ -1,13 +1,463 @@
20110403
- (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec]
[contrib/suse/openssh.spec] Prepare for 5.8p2 release.
- (djm) [version.h] crank version
- Release 5.8p2
20110906
- (djm) [README version.h] Correct version
- (djm) [contrib/redhat/openssh.spec] Correct restorcon => restorecon
- (djm) Respin OpenSSH-5.9p1 release
20110905
- (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec]
[contrib/suse/openssh.spec] Update version numbers.
20110904
- (djm) [regress/connect-privsep.sh regress/test-exec.sh] demote fatal
regress errors for the sandbox to warnings. ok tim dtucker
- (dtucker) [ssh-keygen.c ssh-pkcs11.c] Bug #1929: add null implementations
ofsh-pkcs11.cpkcs_init and pkcs_terminate for building without dlopen
support.
20110829
- (djm) [openbsd-compat/port-linux.c] Suppress logging when attempting
to switch SELinux context away from unconfined_t, based on patch from
Jan Chadima; bz#1919 ok dtucker@
20110827
- (dtucker) [auth-skey.c] Add log.h to fix build --with-skey.
20110818
- (tim) [configure.ac] Typo in error message spotted by Andy Tsouladze
20110817
- (tim) [mac.c myproposal.h] Wrap SHA256 and SHA512 in ifdefs for
OpenSSL 0.9.7. ok djm
- (djm) [ openbsd-compat/bsd-cygwin_util.c openbsd-compat/bsd-cygwin_util.h]
binary_pipe is no longer required on Cygwin; patch from Corinna Vinschen
- (djm) [configure.ac] error out if the host lacks the necessary bits for
an explicitly requested sandbox type
- (djm) [contrib/ssh-copy-id] Missing backlslash; spotted by
bisson AT archlinux.org
- (djm) OpenBSD CVS Sync
- dtucker@cvs.openbsd.org 2011/06/03 05:35:10
[regress/cfgmatch.sh]
use OBJ to find test configs, patch from Tim Rice
- markus@cvs.openbsd.org 2011/06/30 22:44:43
[regress/connect-privsep.sh]
test with sandbox enabled; ok djm@
- djm@cvs.openbsd.org 2011/08/02 01:23:41
[regress/cipher-speed.sh regress/try-ciphers.sh]
add SHA256/SHA512 based HMAC modes
- (djm) [regress/cipher-speed.sh regress/try-ciphers.sh] disable HMAC-SHA2
MAC tests for platforms that hack EVP_SHA2 support
20110812
- (dtucker) [openbsd-compat/port-linux.c] Bug 1924: Improve selinux context
change error by reporting old and new context names Patch from
jchadima at redhat.
- (djm) [contrib/redhat/openssh.spec contrib/redhat/sshd.init]
[contrib/suse/openssh.spec contrib/suse/rc.sshd] Updated RHEL and SLES
init scrips from imorgan AT nas.nasa.gov; bz#1920
- (djm) [contrib/ssh-copy-id] Fix failure for cases where the path to the
identify file contained whitespace. bz#1828 patch from gwenael.lambrouin
AT gmail.com; ok dtucker@
20110807
- (dtucker) OpenBSD CVS Sync
- jmc@cvs.openbsd.org 2008/06/26 06:59:39
[moduli.5]
tweak previous;
- sobrado@cvs.openbsd.org 2009/10/28 08:56:54
[moduli.5]
"Diffie-Hellman" is the usual spelling for the cryptographic protocol
first published by Whitfield Diffie and Martin Hellman in 1976.
ok jmc@
- jmc@cvs.openbsd.org 2010/10/14 20:41:28
[moduli.5]
probabalistic -> probabilistic; from naddy
- dtucker@cvs.openbsd.org 2011/08/07 12:55:30
[sftp.1]
typo, fix from Laurent Gautrot
20110805
- OpenBSD CVS Sync
- djm@cvs.openbsd.org 2011/06/23 23:35:42
[monitor.c]
ignore EINTR errors from poll()
- tedu@cvs.openbsd.org 2011/07/06 18:09:21
[authfd.c]
bzero the agent address. the kernel was for a while very cranky about
these things. evne though that's fixed, always good to initialize
memory. ok deraadt djm
- djm@cvs.openbsd.org 2011/07/29 14:42:45
[sandbox-systrace.c]
fail open(2) with EPERM rather than SIGKILLing the whole process. libc
will call open() to do strerror() when NLS is enabled;
feedback and ok markus@
- markus@cvs.openbsd.org 2011/08/01 19:18:15
[gss-serv.c]
prevent post-auth resource exhaustion (int overflow leading to 4GB malloc);
report Adam Zabrock; ok djm@, deraadt@
- djm@cvs.openbsd.org 2011/08/02 01:22:11
[mac.c myproposal.h ssh.1 ssh_config.5 sshd.8 sshd_config.5]
Add new SHA256 and SHA512 based HMAC modes from
http://www.ietf.org/id/draft-dbider-sha2-mac-for-ssh-02.txt
Patch from mdb AT juniper.net; feedback and ok markus@
- djm@cvs.openbsd.org 2011/08/02 23:13:01
[version.h]
crank now, release later
- djm@cvs.openbsd.org 2011/08/02 23:15:03
[ssh.c]
typo in comment
20110624
- (djm) [configure.ac Makefile.in sandbox-darwin.c] Add a sandbox for
Darwin/OS X using sandbox_init() + setrlimit(); feedback and testing
markus@
20110623
- OpenBSD CVS Sync
- djm@cvs.openbsd.org 2011/06/22 21:47:28
[servconf.c]
reuse the multistate option arrays to pretty-print options for "sshd -T"
- djm@cvs.openbsd.org 2011/06/22 21:57:01
[servconf.c servconf.h sshd.c sshd_config.5]
[configure.ac Makefile.in]
introduce sandboxing of the pre-auth privsep child using systrace(4).
This introduces a new "UsePrivilegeSeparation=sandbox" option for
sshd_config that applies mandatory restrictions on the syscalls the
privsep child can perform. This prevents a compromised privsep child
from being used to attack other hosts (by opening sockets and proxying)
or probing local kernel attack surface.
The sandbox is implemented using systrace(4) in unsupervised "fast-path"
mode, where a list of permitted syscalls is supplied. Any syscall not
on the list results in SIGKILL being sent to the privsep child. Note
that this requires a kernel with the new SYSTR_POLICY_KILL option.
UsePrivilegeSeparation=sandbox will become the default in the future
so please start testing it now.
feedback dtucker@; ok markus@
- djm@cvs.openbsd.org 2011/06/22 22:08:42
[channels.c channels.h clientloop.c clientloop.h mux.c ssh.c]
hook up a channel confirm callback to warn the user then requested X11
forwarding was refused by the server; ok markus@
- djm@cvs.openbsd.org 2011/06/23 09:34:13
[sshd.c ssh-sandbox.h sandbox.h sandbox-rlimit.c sandbox-systrace.c]
[sandbox-null.c]
rename sandbox.h => ssh-sandbox.h to make things easier for portable
- (djm) [sandbox-null.c] Dummy sandbox for platforms that don't support
setrlimit(2)
20110620
- OpenBSD CVS Sync
- djm@cvs.openbsd.org 2011/06/04 00:10:26
[ssh_config.5]
explain IdentifyFile's semantics a little better, prompted by bz#1898
ok dtucker jmc
- markus@cvs.openbsd.org 2011/06/14 22:49:18
[authfile.c]
make sure key_parse_public/private_rsa1() no longer consumes its input
buffer. fixes ssh-add for passphrase-protected ssh1-keys;
noted by naddy@; ok djm@
- djm@cvs.openbsd.org 2011/06/17 21:44:31
[log.c log.h monitor.c monitor.h monitor_wrap.c monitor_wrap.h sshd.c]
make the pre-auth privsep slave log via a socketpair shared with the
monitor rather than /var/empty/dev/log; ok dtucker@ deraadt@ markus@
- djm@cvs.openbsd.org 2011/06/17 21:46:16
[sftp-server.c]
the protocol version should be unsigned; bz#1913 reported by mb AT
smartftp.com
- djm@cvs.openbsd.org 2011/06/17 21:47:35
[servconf.c]
factor out multi-choice option parsing into a parse_multistate label
and some support structures; ok dtucker@
- djm@cvs.openbsd.org 2011/06/17 21:57:25
[clientloop.c]
setproctitle for a mux master that has been gracefully stopped;
bz#1911 from Bert.Wesarg AT googlemail.com
20110603
- (dtucker) [README version.h contrib/caldera/openssh.spec
contrib/redhat/openssh.spec contrib/suse/openssh.spec] Pull the version
bumps from the 5.8p2 branch into HEAD. ok djm.
- (tim) [configure.ac defines.h] Run test program to detect system mail
directory. Add --with-maildir option to override. Fixed OpenServer 6
getting it wrong. Fixed many systems having MAIL=/var/mail//username
ok dtucker
- (dtucker) [monitor.c] Remove the !HAVE_SOCKETPAIR case. We use socketpair
unconditionally in other places and the survey data we have does not show
any systems that use it. "nuke it" djm@
- (djm) [configure.ac] enable setproctitle emulation for OS X
- (djm) OpenBSD CVS Sync
- djm@cvs.openbsd.org 2011/06/03 00:54:38
[ssh.c]
bz#1883 - setproctitle() to identify mux master; patch from Bert.Wesarg
AT googlemail.com; ok dtucker@
NB. includes additional portability code to enable setproctitle emulation
on platforms that don't support it.
- dtucker@cvs.openbsd.org 2011/06/03 01:37:40
[ssh-agent.c]
Check current parent process ID against saved one to determine if the parent
has exited, rather than attempting to send a zero signal, since the latter
won't work if the parent has changed privs. bz#1905, patch from Daniel Kahn
Gillmor, ok djm@
- dtucker@cvs.openbsd.org 2011/05/31 02:01:58
[regress/dynamic-forward.sh]
back out revs 1.6 and 1.5 since it's not reliable
- dtucker@cvs.openbsd.org 2011/05/31 02:03:34
[regress/dynamic-forward.sh]
work around startup and teardown races; caught by deraadt
- dtucker@cvs.openbsd.org 2011/06/03 00:29:52
[regress/dynamic-forward.sh]
Retry establishing the port forwarding after a small delay, should make
the tests less flaky when the previous test is slow to shut down and free
up the port.
- (tim) [regress/cfgmatch.sh] Build/test out of tree fix.
20110529
- (djm) OpenBSD CVS Sync
- djm@cvs.openbsd.org 2011/05/23 03:30:07
[auth-rsa.c auth.c auth.h auth2-pubkey.c monitor.c monitor_wrap.c]
[pathnames.h servconf.c servconf.h sshd.8 sshd_config sshd_config.5]
allow AuthorizedKeysFile to specify multiple files, separated by spaces.
Bring back authorized_keys2 as a default search path (to avoid breaking
existing users of this file), but override this in sshd_config so it will
be no longer used on fresh installs. Maybe in 2015 we can remove it
entierly :)
feedback and ok markus@ dtucker@
- djm@cvs.openbsd.org 2011/05/23 03:33:38
[auth.c]
make secure_filename() spam debug logs less
- djm@cvs.openbsd.org 2011/05/23 03:52:55
[sshconnect.c]
remove extra newline
- jmc@cvs.openbsd.org 2011/05/23 07:10:21
[sshd.8 sshd_config.5]
tweak previous; ok djm
- djm@cvs.openbsd.org 2011/05/23 07:24:57
[authfile.c]
read in key comments for v.2 keys (though note that these are not
passed over the agent protocol); bz#439, based on patch from binder
AT arago.de; ok markus@
- djm@cvs.openbsd.org 2011/05/24 07:15:47
[readconf.c readconf.h ssh.c ssh_config.5 sshconnect.c sshconnect2.c]
Remove undocumented legacy options UserKnownHostsFile2 and
GlobalKnownHostsFile2 by making UserKnownHostsFile/GlobalKnownHostsFile
accept multiple paths per line and making their defaults include
known_hosts2; ok markus
- djm@cvs.openbsd.org 2011/05/23 03:31:31
[regress/cfgmatch.sh]
include testing of multiple/overridden AuthorizedKeysFiles
refactor to simply daemon start/stop and get rid of racy constructs
20110520
- (djm) [session.c] call setexeccon() before executing passwd for pw
changes; bz#1891 reported by jchadima AT redhat.com; ok dtucker@
- (djm) [aclocal.m4 configure.ac] since gcc-4.x ignores all -Wno-options
options, we should corresponding -W-option when trying to determine
whether it is accepted. Also includes a warning fix on the program
fragment uses (bad main() return type).
bz#1900 and bz#1901 reported by g.esp AT free.fr; ok dtucker@
- (djm) [servconf.c] remove leftover droppings of AuthorizedKeysFile2
- OpenBSD CVS Sync
- djm@cvs.openbsd.org 2011/05/15 08:09:01
[authfd.c monitor.c serverloop.c]
use FD_CLOEXEC consistently; patch from zion AT x96.org
- djm@cvs.openbsd.org 2011/05/17 07:13:31
[key.c]
fatal() if asked to generate a legacy ECDSA cert (these don't exist)
and fix the regress test that was trying to generate them :)
- djm@cvs.openbsd.org 2011/05/20 00:55:02
[servconf.c]
the options TrustedUserCAKeys, RevokedKeysFile, AuthorizedKeysFile
and AuthorizedPrincipalsFile were not being correctly applied in
Match blocks, despite being overridable there; ok dtucker@
- dtucker@cvs.openbsd.org 2011/05/20 02:00:19
[servconf.c]
Add comment documenting what should be after the preauth check. ok djm
- djm@cvs.openbsd.org 2011/05/20 03:25:45
[monitor.c monitor_wrap.c servconf.c servconf.h]
use a macro to define which string options to copy between configs
for Match. This avoids problems caused by forgetting to keep three
code locations in perfect sync and ordering
"this is at once beautiful and horrible" + ok dtucker@
- djm@cvs.openbsd.org 2011/05/17 07:13:31
[regress/cert-userkey.sh]
fatal() if asked to generate a legacy ECDSA cert (these don't exist)
and fix the regress test that was trying to generate them :)
- djm@cvs.openbsd.org 2011/05/20 02:43:36
[cert-hostkey.sh]
another attempt to generate a v00 ECDSA key that broke the test
ID sync only - portable already had this somehow
- dtucker@cvs.openbsd.org 2011/05/20 05:19:50
[dynamic-forward.sh]
Prevent races in dynamic forwarding test; ok djm
- dtucker@cvs.openbsd.org 2011/05/20 06:32:30
[dynamic-forward.sh]
fix dumb error in dynamic-forward test
20110515
- (djm) OpenBSD CVS Sync
- djm@cvs.openbsd.org 2011/05/05 05:12:08
[mux.c]
gracefully fall back when ControlPath is too large for a
sockaddr_un. ok markus@ as part of a larger diff
- dtucker@cvs.openbsd.org 2011/05/06 01:03:35
[sshd_config]
clarify language about overriding defaults. bz#1892, from Petr Cerny
- djm@cvs.openbsd.org 2011/05/06 01:09:53
[sftp.1]
mention that IPv6 addresses must be enclosed in square brackets;
bz#1845
- djm@cvs.openbsd.org 2011/05/06 02:05:41
[sshconnect2.c]
fix memory leak; bz#1849 ok dtucker@
- djm@cvs.openbsd.org 2011/05/06 21:14:05
[packet.c packet.h]
set traffic class for IPv6 traffic as we do for IPv4 TOS;
patch from lionel AT mamane.lu via Colin Watson in bz#1855;
ok markus@
- djm@cvs.openbsd.org 2011/05/06 21:18:02
[ssh.c ssh_config.5]
add a %L expansion (short-form of the local host name) for ControlPath;
sync some more expansions with LocalCommand; ok markus@
- djm@cvs.openbsd.org 2011/05/06 21:31:38
[readconf.c ssh_config.5]
support negated Host matching, e.g.
Host *.example.org !c.example.org
User mekmitasdigoat
Will match "a.example.org", "b.example.org", but not "c.example.org"
ok markus@
- djm@cvs.openbsd.org 2011/05/06 21:34:32
[clientloop.c mux.c readconf.c readconf.h ssh.c ssh_config.5]
Add a RequestTTY ssh_config option to allow configuration-based
control over tty allocation (like -t/-T); ok markus@
- djm@cvs.openbsd.org 2011/05/06 21:38:58
[ssh.c]
fix dropping from previous diff
- djm@cvs.openbsd.org 2011/05/06 22:20:10
[PROTOCOL.mux]
fix numbering; from bert.wesarg AT googlemail.com
- jmc@cvs.openbsd.org 2011/05/07 23:19:39
[ssh_config.5]
- tweak previous
- come consistency fixes
ok djm
- jmc@cvs.openbsd.org 2011/05/07 23:20:25
[ssh.1]
+.It RequestTTY
- djm@cvs.openbsd.org 2011/05/08 12:52:01
[PROTOCOL.mux clientloop.c clientloop.h mux.c]
improve our behaviour when TTY allocation fails: if we are in
RequestTTY=auto mode (the default), then do not treat at TTY
allocation error as fatal but rather just restore the local TTY
to cooked mode and continue. This is more graceful on devices that
never allocate TTYs.
If RequestTTY is set to "yes" or "force", then failure to allocate
a TTY is fatal.
ok markus@
- djm@cvs.openbsd.org 2011/05/10 05:46:46
[authfile.c]
despam debug() logs by detecting that we are trying to load a private key
in key_try_load_public() and returning early; ok markus@
- djm@cvs.openbsd.org 2011/05/11 04:47:06
[auth.c auth.h auth2-pubkey.c pathnames.h servconf.c servconf.h]
remove support for authorized_keys2; it is a relic from the early days
of protocol v.2 support and has been undocumented for many years;
ok markus@
- djm@cvs.openbsd.org 2011/05/13 00:05:36
[authfile.c]
warn on unexpected key type in key_parse_private_type()
- (djm) [packet.c] unbreak portability #endif
20110510
- (dtucker) [openbsd-compat/openssl-compat.{c,h}] Bug #1882: fix
--with-ssl-engine which was broken with the change from deprecated
SSLeay_add_all_algorithms(). ok djm
20110506
- (dtucker) [openbsd-compat/regress/closefromtest.c] Bug #1875: add prototype
for closefrom() in test code. Report from Dan Wallis via Gentoo.
20110505
- (djm) [defines.h] Move up include of netinet/ip.h for IPTOS
definitions. From des AT des.no
- (djm) [Makefile.in WARNING.RNG aclocal.m4 buildpkg.sh.in configure.ac]
[entropy.c ssh-add.c ssh-agent.c ssh-keygen.c ssh-keyscan.c]
[ssh-keysign.c ssh-pkcs11-helper.c ssh-rand-helper.8 ssh-rand-helper.c]
[ssh.c ssh_prng_cmds.in sshd.c contrib/aix/buildbff.sh]
[regress/README.regress] Remove ssh-rand-helper and all its
tentacles. PRNGd seeding has been rolled into entropy.c directly.
Thanks to tim@ for testing on affected platforms.
- OpenBSD CVS Sync
- djm@cvs.openbsd.org 2011/03/10 02:52:57
[auth2-gss.c auth2.c auth.h]
allow GSSAPI authentication to detect when a server-side failure causes
authentication failure and don't count such failures against MaxAuthTries;
bz#1244 from simon AT sxw.org.uk; ok markus@ before lock
- okan@cvs.openbsd.org 2011/03/15 10:36:02
[ssh-keyscan.c]
use timerclear macro
ok djm@
- stevesk@cvs.openbsd.org 2011/03/23 15:16:22
[ssh-keygen.1 ssh-keygen.c]
Add -A option. For each of the key types (rsa1, rsa, dsa and ecdsa)
for which host keys do not exist, generate the host keys with the
default key file path, an empty passphrase, default bits for the key
type, and default comment. This will be used by /etc/rc to generate
new host keys. Idea from deraadt.
ok deraadt
- stevesk@cvs.openbsd.org 2011/03/23 16:24:56
[ssh-keygen.1]
-q not used in /etc/rc now so remove statement.
- stevesk@cvs.openbsd.org 2011/03/23 16:50:04
[ssh-keygen.c]
remove -d, documentation removed >10 years ago; ok markus
- jmc@cvs.openbsd.org 2011/03/24 15:29:30
[ssh-keygen.1]
zap trailing whitespace;
- stevesk@cvs.openbsd.org 2011/03/24 22:14:54
[ssh-keygen.c]
use strcasecmp() for "clear" cert permission option also; ok djm
- stevesk@cvs.openbsd.org 2011/03/29 18:54:17
[misc.c misc.h servconf.c]
print ipqos friendly string for sshd -T; ok markus
# sshd -Tf sshd_config|grep ipqos
ipqos lowdelay throughput
- djm@cvs.openbsd.org 2011/04/12 04:23:50
[ssh-keygen.c]
fix -Wshadow
- djm@cvs.openbsd.org 2011/04/12 05:32:49
[sshd.c]
exit with 0 status on SIGTERM; bz#1879
- djm@cvs.openbsd.org 2011/04/13 04:02:48
[ssh-keygen.1]
improve wording; bz#1861
- djm@cvs.openbsd.org 2011/04/13 04:09:37
[ssh-keygen.1]
mention valid -b sizes for ECDSA keys; bz#1862
- djm@cvs.openbsd.org 2011/04/17 22:42:42
[PROTOCOL.mux clientloop.c clientloop.h mux.c ssh.1 ssh.c]
allow graceful shutdown of multiplexing: request that a mux server
removes its listener socket and refuse future multiplexing requests;
ok markus@
- djm@cvs.openbsd.org 2011/04/18 00:46:05
[ssh-keygen.c]
certificate options are supposed to be packed in lexical order of
option name (though we don't actually enforce this at present).
Move one up that was out of sequence
- djm@cvs.openbsd.org 2011/05/04 21:15:29
[authfile.c authfile.h ssh-add.c]
allow "ssh-add - < key"; feedback and ok markus@
- (tim) [configure.ac] Add AC_LANG_SOURCE to OPENSSH_CHECK_CFLAG_COMPILE
so autoreconf 2.68 is happy.
- (tim) [defines.h] Deal with platforms that do not have S_IFSOCK ok djm@
20110329
- (djm) [entropy.c] closefrom() before running ssh-rand-helper; leftover fds
noticed by tmraz AT redhat.com
20110221
- (dtucker) [contrib/cygwin/ssh-host-config] From Corinna: revamp of the
Cygwin-specific service installer script ssh-host-config. The actual
@ -19,6 +469,13 @@
The new script also is more thorough to inform the user why the
script failed. Patch from vinschen at redhat com.
20110218
- OpenBSD CVS Sync
- djm@cvs.openbsd.org 2011/02/16 00:31:14
[ssh-keysign.c]
make hostbased auth with ECDSA keys work correctly. Based on patch
by harvey.eneman AT oracle.com in bz#1858; ok markus@ (pre-lock)
20110206
- (dtucker) [openbsd-compat/port-linux.c] Bug #1851: fix syntax error in
selinux code. Patch from Leonardo Chiquitto
@ -46,6 +503,14 @@
succeeded before using its result. Patch from cjwatson AT debian.org;
bz#1851
20110127
- (tim) [config.guess config.sub] Sync with upstream.
- (tim) [configure.ac] Consistent M4 quoting throughout, updated obsolete
AC_TRY_COMPILE with AC_COMPILE_IFELSE, updated obsolete AC_TRY_LINK with
AC_LINK_IFELSE, updated obsolete AC_TRY_RUN with AC_RUN_IFELSE, misc white
space changes for consistency/readability. Makes autoconf 2.68 happy.
"Nice work" djm
20110125
- (djm) [configure.ac Makefile.in ssh.c openbsd-compat/port-linux.c
openbsd-compat/port-linux.h] Move SELinux-specific code from ssh.c to
@ -1256,4 +1721,3 @@
(use "ssh-keygen -t v00 -s ca_key ..." to generate a v00 certificate)
ok markus@

View File

@ -16,9 +16,7 @@ The remaining items are optional.
NB. If you operating system supports /dev/random, you should configure
OpenSSL to use it. OpenSSH relies on OpenSSL's direct support of
/dev/random, or failing that, either prngd or egd. If you don't have
any of these you will have to rely on ssh-rand-helper, which is inferior
to a good kernel-based solution or prngd.
/dev/random, or failing that, either prngd or egd
PRNGD:
@ -262,4 +260,4 @@ Please refer to the "reporting bugs" section of the webpage at
http://www.openssh.com/
$Id: INSTALL,v 1.85 2010/02/11 22:34:22 djm Exp $
$Id: INSTALL,v 1.86 2011/05/05 03:48:37 djm Exp $

View File

@ -73,6 +73,13 @@ non-multiplexed ssh(1) connection. Two additional cases that the
client must cope with are it receiving a signal itself and the
server disconnecting without sending an exit message.
A master may also send a MUX_S_TTY_ALLOC_FAIL before MUX_S_EXIT_MESSAGE
if remote TTY allocation was unsuccessful. The client may use this to
return its local tty to "cooked" mode.
uint32 MUX_S_TTY_ALLOC_FAIL
uint32 session id
3. Health checks
The client may request a health check/PID report from a server:
@ -149,10 +156,21 @@ The client then sends its standard input and output file descriptors
The contents of "reserved" are currently ignored.
A server may reply with a MUX_S_SESSION_OPEED, a MUX_S_PERMISSION_DENIED
A server may reply with a MUX_S_SESSION_OPENED, a MUX_S_PERMISSION_DENIED
or a MUX_S_FAILURE.
8. Status messages
8. Requesting shutdown of mux listener
A client may request the master to stop accepting new multiplexing requests
and remove its listener socket.
uint32 MUX_C_STOP_LISTENING
uint32 request id
A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a
MUX_S_FAILURE.
9. Status messages
The MUX_S_OK message is empty:
@ -169,7 +187,7 @@ The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason:
uint32 client request id
string reason
9. Protocol numbers
10. Protocol numbers
#define MUX_MSG_HELLO 0x00000001
#define MUX_C_NEW_SESSION 0x10000002
@ -178,6 +196,7 @@ The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason:
#define MUX_C_OPEN_FWD 0x10000006
#define MUX_C_CLOSE_FWD 0x10000007
#define MUX_C_NEW_STDIO_FWD 0x10000008
#define MUX_C_STOP_LISTENING 0x10000009
#define MUX_S_OK 0x80000001
#define MUX_S_PERMISSION_DENIED 0x80000002
#define MUX_S_FAILURE 0x80000003
@ -185,6 +204,7 @@ The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason:
#define MUX_S_ALIVE 0x80000005
#define MUX_S_SESSION_OPENED 0x80000006
#define MUX_S_REMOTE_PORT 0x80000007
#define MUX_S_TTY_ALLOC_FAIL 0x80000008
#define MUX_FWD_LOCAL 1
#define MUX_FWD_REMOTE 2
@ -192,12 +212,10 @@ The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason:
XXX TODO
XXX extended status (e.g. report open channels / forwards)
XXX graceful close (delete listening socket, but keep existing sessions active)
XXX lock (maybe)
XXX watch in/out traffic (pre/post crypto)
XXX inject packet (what about replies)
XXX server->client error/warning notifications
XXX port0 rfwd (need custom response message)
XXX send signals via mux
$OpenBSD: PROTOCOL.mux,v 1.4 2011/01/31 21:42:15 djm Exp $
$OpenBSD: PROTOCOL.mux,v 1.7 2011/05/08 12:52:01 djm Exp $

View File

@ -1,4 +1,4 @@
See http://www.openssh.com/txt/release-5.8p2 for the release notes.
See http://www.openssh.com/txt/release-5.9 for the release notes.
- A Japanese translation of this document and of the OpenSSH FAQ is
- available at http://www.unixuser.org/~haruyama/security/openssh/index.html
@ -62,4 +62,4 @@ References -
[6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9
[7] http://www.openssh.com/faq.html
$Id: README,v 1.75.4.2 2011/05/03 00:04:21 djm Exp $
$Id: README,v 1.77.2.2 2011/09/06 23:11:20 djm Exp $

View File

@ -1,95 +0,0 @@
This document contains a description of portable OpenSSH's random
number collection code. An alternate reading of this text could
well be titled "Why I should pressure my system vendor to supply
/dev/random in their OS".
Why is this important? OpenSSH depends on good, unpredictable numbers
for generating keys, performing digital signatures and forming
cryptographic challenges. If the random numbers that it uses are
predictable, then the strength of the whole system is compromised.
A particularly pernicious problem arises with DSA keys (used by the
ssh2 protocol). Performing a DSA signature (which is required for
authentication), entails the use of a 160 bit random number. If an
attacker can predict this number, then they can deduce your *private*
key and impersonate you or your hosts.
If you are using the builtin random number support (configure will
tell you if this is the case), then read this document in its entirety.
Alternately, you can use Lutz Jaenicke's PRNGd - a small daemon which
collects random numbers and makes them available by a socket.
Please also request that your OS vendor provides a kernel-based random
number collector (/dev/random) in future versions of your operating
systems by default.
On to the description...
The portable OpenSSH contains random number collection support for
systems which lack a kernel entropy pool (/dev/random).
This collector (as of 3.1 and beyond) comes as an external application
that allows the local admin to decide on how to implement entropy
collection.
The default entropy collector operates by executing the programs listed
in ($etcdir)/ssh_prng_cmds, reading their output and adding it to the
PRNG supplied by OpenSSL (which is hash-based). It also stirs in the
output of several system calls and timings from the execution of the
programs that it runs.
The ssh_prng_cmds file also specifies a 'rate' for each program. This
represents the number of bits of randomness per byte of output from
the specified program.
The random number code will also read and save a seed file to
~/.ssh/prng_seed. This contents of this file are added to the random
number generator at startup. The goal here is to maintain as much
randomness between sessions as possible.
The default entropy collection code has two main problems:
1. It is slow.
Executing each program in the list can take a large amount of time,
especially on slower machines. Additionally some program can take a
disproportionate time to execute.
Tuning the random helper can be done by running ./ssh-random-helper in
very verbose mode ("-vvv") and identifying the commands that are taking
excessive amounts of time or hanging altogher. Any problem commands can
be modified or removed from ssh_prng_cmds.
The default entropy collector will timeout programs which take too long
to execute, the actual timeout used can be adjusted with the
--with-entropy-timeout configure option. OpenSSH will not try to
re-execute programs which have not been found, have had a non-zero
exit status or have timed out more than a couple of times.
2. Estimating the real 'rate' of program outputs is non-trivial
The shear volume of the task is problematic: there are currently
around 50 commands in the ssh_prng_cmds list, portable OpenSSH
supports at least 12 different OSs. That is already 600 sets of data
to be analysed, without taking into account the numerous differences
between versions of each OS.
On top of this, the different commands can produce varying amounts of
usable data depending on how busy the machine is, how long it has been
up and various other factors.
To make matters even more complex, some of the commands are reporting
largely the same data as other commands (eg. the various "ps" calls).
How to avoid the default entropy code?
The best way is to read the OpenSSL documentation and recompile OpenSSL
to use prngd or egd. Some platforms (like earily solaris) have 3rd
party /dev/random devices that can be also used for this task.
If you are forced to use ssh-rand-helper consider still downloading
prngd/egd and configure OpenSSH using --with-prngd-port=xx or
--with-prngd-socket=xx (refer to INSTALL for more information).
$Id: WARNING.RNG,v 1.8 2005/05/26 01:47:54 djm Exp $

View File

@ -1,8 +1,26 @@
dnl $Id: aclocal.m4,v 1.6 2005/09/19 16:33:39 tim Exp $
dnl $Id: aclocal.m4,v 1.8 2011/05/20 01:45:25 djm Exp $
dnl
dnl OpenSSH-specific autoconf macros
dnl
dnl OSSH_CHECK_CFLAG_COMPILE(check_flag[, define_flag])
dnl Check that $CC accepts a flag 'check_flag'. If it is supported append
dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append
dnl 'check_flag'.
AC_DEFUN([OSSH_CHECK_CFLAG_COMPILE], [{
AC_MSG_CHECKING([if $CC supports $1])
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $1"
_define_flag="$2"
test "x$_define_flag" = "x" && _define_flag="$1"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int main(void) { return 0; }]])],
[ AC_MSG_RESULT([yes])
CFLAGS="$saved_CFLAGS $_define_flag"],
[ AC_MSG_RESULT([no])
CFLAGS="$saved_CFLAGS" ]
)
}])
dnl OSSH_CHECK_HEADER_FOR_FIELD(field, header, symbol)
dnl Does AC_EGREP_HEADER on 'header' for the string 'field'
@ -33,16 +51,6 @@ AC_DEFUN(OSSH_CHECK_HEADER_FOR_FIELD, [
fi
])
dnl OSSH_PATH_ENTROPY_PROG(variablename, command):
dnl Tidiness function, sets 'undef' if not found, and does the AC_SUBST
AC_DEFUN(OSSH_PATH_ENTROPY_PROG, [
AC_PATH_PROG($1, $2)
if test -z "[$]$1" ; then
$1="undef"
fi
AC_SUBST($1)
])
dnl Check for socklen_t: historically on BSD it is an int, and in
dnl POSIX 1g it is a type of its own, but some platforms use different
dnl types for the argument to getsockopt, getpeername, etc. So we

View File

@ -1,4 +1,4 @@
/* $Id$ */
/* $Id: audit-linux.c,v 1.1 2011/01/17 10:15:30 dtucker Exp $ */
/*
* Copyright 2010 Red Hat, Inc. All rights reserved.

View File

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

View File

@ -39,6 +39,7 @@
#include "hostfile.h"
#include "auth.h"
#include "ssh-gss.h"
#include "log.h"
#include "monitor_wrap.h"
static void *

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth.c,v 1.91 2010/11/29 23:45:51 djm Exp $ */
/* $OpenBSD: auth.c,v 1.94 2011/05/23 03:33:38 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -332,7 +332,7 @@ auth_root_allowed(char *method)
*
* This returns a buffer allocated by xmalloc.
*/
static char *
char *
expand_authorized_keys(const char *filename, struct passwd *pw)
{
char *file, ret[MAXPATHLEN];
@ -355,18 +355,6 @@ expand_authorized_keys(const char *filename, struct passwd *pw)
return (xstrdup(ret));
}
char *
authorized_keys_file(struct passwd *pw)
{
return expand_authorized_keys(options.authorized_keys_file, pw);
}
char *
authorized_keys_file2(struct passwd *pw)
{
return expand_authorized_keys(options.authorized_keys_file2, pw);
}
char *
authorized_principals_file(struct passwd *pw)
{
@ -469,7 +457,6 @@ secure_filename(FILE *f, const char *file, struct passwd *pw,
}
strlcpy(buf, cp, sizeof(buf));
debug3("secure_filename: checking '%s'", buf);
if (stat(buf, &st) < 0 ||
(st.st_uid != 0 && st.st_uid != uid) ||
(st.st_mode & 022) != 0) {
@ -479,11 +466,9 @@ secure_filename(FILE *f, const char *file, struct passwd *pw,
}
/* If are past the homedir then we can stop */
if (comparehome && strcmp(homedir, buf) == 0) {
debug3("secure_filename: terminating check at '%s'",
buf);
if (comparehome && strcmp(homedir, buf) == 0)
break;
}
/*
* dirname should always complete with a "/" path,
* but we can be paranoid and check for "." too

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth.h,v 1.66 2010/05/07 11:30:29 djm Exp $ */
/* $OpenBSD: auth.h,v 1.69 2011/05/23 03:30:07 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -53,6 +53,7 @@ struct Authctxt {
int valid; /* user exists and is allowed to login */
int attempt;
int failures;
int server_caused_failure;
int force_pwchange;
char *user; /* username sent by the client */
char *service;
@ -167,8 +168,7 @@ char *get_challenge(Authctxt *);
int verify_response(Authctxt *, const char *);
void abandon_challenge_response(Authctxt *);
char *authorized_keys_file(struct passwd *);
char *authorized_keys_file2(struct passwd *);
char *expand_authorized_keys(const char *, struct passwd *pw);
char *authorized_principals_file(struct passwd *);
FILE *auth_openkeyfile(const char *, struct passwd *, int);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-gss.c,v 1.16 2007/10/29 00:52:45 dtucker Exp $ */
/* $OpenBSD: auth2-gss.c,v 1.17 2011/03/10 02:52:57 djm Exp $ */
/*
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@ -102,6 +102,7 @@ userauth_gssapi(Authctxt *authctxt)
if (!present) {
xfree(doid);
authctxt->server_caused_failure = 1;
return (0);
}
@ -109,6 +110,7 @@ userauth_gssapi(Authctxt *authctxt)
if (ctxt != NULL)
ssh_gssapi_delete_ctx(&ctxt);
xfree(doid);
authctxt->server_caused_failure = 1;
return (0);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-pubkey.c,v 1.27 2010/11/20 05:12:38 deraadt Exp $ */
/* $OpenBSD: auth2-pubkey.c,v 1.29 2011/05/23 03:30:07 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -436,7 +436,7 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
int
user_key_allowed(struct passwd *pw, Key *key)
{
int success;
u_int success, i;
char *file;
if (auth_key_is_revoked(key))
@ -448,16 +448,13 @@ user_key_allowed(struct passwd *pw, Key *key)
if (success)
return success;
file = authorized_keys_file(pw);
success = user_key_allowed2(pw, key, file);
xfree(file);
if (success)
return success;
for (i = 0; !success && i < options.num_authkeys_files; i++) {
file = expand_authorized_keys(
options.authorized_keys_files[i], pw);
success = user_key_allowed2(pw, key, file);
xfree(file);
}
/* try suffix "2" for backward compat, too */
file = authorized_keys_file2(pw);
success = user_key_allowed2(pw, key, file);
xfree(file);
return success;
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth2.c,v 1.122 2010/08/31 09:58:37 djm Exp $ */
/* $OpenBSD: auth2.c,v 1.123 2011/03/10 02:52:57 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -304,6 +304,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
#endif
authctxt->postponed = 0;
authctxt->server_caused_failure = 0;
/* try to authenticate user */
m = authmethod_lookup(method);
@ -376,7 +377,8 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
} else {
/* Allow initial try of "none" auth without failure penalty */
if (authctxt->attempt > 1 || strcmp(method, "none") != 0)
if (!authctxt->server_caused_failure &&
(authctxt->attempt > 1 || strcmp(method, "none") != 0))
authctxt->failures++;
if (authctxt->failures >= options.max_authtries) {
#ifdef SSH_AUDIT_EVENTS

View File

@ -1,4 +1,4 @@
/* $OpenBSD: authfd.c,v 1.84 2010/08/31 11:54:45 djm Exp $ */
/* $OpenBSD: authfd.c,v 1.86 2011/07/06 18:09:21 tedu Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -102,6 +102,7 @@ ssh_get_authentication_socket(void)
if (!authsocket)
return -1;
bzero(&sunaddr, sizeof(sunaddr));
sunaddr.sun_family = AF_UNIX;
strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path));
@ -110,7 +111,7 @@ ssh_get_authentication_socket(void)
return -1;
/* close on exec */
if (fcntl(sock, F_SETFD, 1) == -1) {
if (fcntl(sock, F_SETFD, FD_CLOEXEC) == -1) {
close(sock);
return -1;
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: authfile.c,v 1.87 2010/11/29 18:57:04 markus Exp $ */
/* $OpenBSD: authfile.c,v 1.92 2011/06/14 22:49:18 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -69,6 +69,8 @@
#include "misc.h"
#include "atomicio.h"
#define MAX_KEY_FILE_SIZE (1024 * 1024)
/* Version identification string for SSH v1 identity files. */
static const char authfile_id_string[] =
"SSH PRIVATE KEY FILE FORMAT 1.1\n";
@ -277,6 +279,7 @@ static Key *
key_parse_public_rsa1(Buffer *blob, char **commentp)
{
Key *pub;
Buffer copy;
/* Check that it is at least big enough to contain the ID string. */
if (buffer_len(blob) < sizeof(authfile_id_string)) {
@ -293,31 +296,33 @@ key_parse_public_rsa1(Buffer *blob, char **commentp)
debug3("Incorrect RSA1 identifier");
return NULL;
}
buffer_consume(blob, sizeof(authfile_id_string));
buffer_init(&copy);
buffer_append(&copy, buffer_ptr(blob), buffer_len(blob));
buffer_consume(&copy, sizeof(authfile_id_string));
/* Skip cipher type and reserved data. */
(void) buffer_get_char(blob); /* cipher type */
(void) buffer_get_int(blob); /* reserved */
(void) buffer_get_char(&copy); /* cipher type */
(void) buffer_get_int(&copy); /* reserved */
/* Read the public key from the buffer. */
(void) buffer_get_int(blob);
(void) buffer_get_int(&copy);
pub = key_new(KEY_RSA1);
buffer_get_bignum(blob, pub->rsa->n);
buffer_get_bignum(blob, pub->rsa->e);
buffer_get_bignum(&copy, pub->rsa->n);
buffer_get_bignum(&copy, pub->rsa->e);
if (commentp)
*commentp = buffer_get_string(blob, NULL);
*commentp = buffer_get_string(&copy, NULL);
/* The encrypted private part is not parsed by this function. */
buffer_clear(blob);
buffer_free(&copy);
return pub;
}
/* Load the contents of a key file into a buffer */
static int
/* Load a key from a fd into a buffer */
int
key_load_file(int fd, const char *filename, Buffer *blob)
{
u_char buf[1024];
size_t len;
u_char *cp;
struct stat st;
if (fstat(fd, &st) < 0) {
@ -325,30 +330,45 @@ key_load_file(int fd, const char *filename, Buffer *blob)
filename == NULL ? "" : filename,
filename == NULL ? "" : " ",
strerror(errno));
close(fd);
return 0;
}
if (st.st_size > 1*1024*1024) {
if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
st.st_size > MAX_KEY_FILE_SIZE) {
toobig:
error("%s: key file %.200s%stoo large", __func__,
filename == NULL ? "" : filename,
filename == NULL ? "" : " ");
close(fd);
return 0;
}
len = (size_t)st.st_size; /* truncated */
buffer_init(blob);
cp = buffer_append_space(blob, len);
if (atomicio(read, fd, cp, len) != len) {
debug("%s: read from key file %.200s%sfailed: %.100s", __func__,
filename == NULL ? "" : filename,
filename == NULL ? "" : " ",
strerror(errno));
for (;;) {
if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
if (errno == EPIPE)
break;
debug("%s: read from key file %.200s%sfailed: %.100s",
__func__, filename == NULL ? "" : filename,
filename == NULL ? "" : " ", strerror(errno));
buffer_clear(blob);
bzero(buf, sizeof(buf));
return 0;
}
buffer_append(blob, buf, len);
if (buffer_len(blob) > MAX_KEY_FILE_SIZE) {
buffer_clear(blob);
bzero(buf, sizeof(buf));
goto toobig;
}
}
bzero(buf, sizeof(buf));
if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
st.st_size != buffer_len(blob)) {
debug("%s: key file %.200s%schanged size while reading",
__func__, filename == NULL ? "" : filename,
filename == NULL ? "" : " ");
buffer_clear(blob);
close(fd);
return 0;
}
return 1;
}
@ -403,6 +423,7 @@ key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp)
CipherContext ciphercontext;
Cipher *cipher;
Key *prv = NULL;
Buffer copy;
/* Check that it is at least big enough to contain the ID string. */
if (buffer_len(blob) < sizeof(authfile_id_string)) {
@ -419,41 +440,44 @@ key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp)
debug3("Incorrect RSA1 identifier");
return NULL;
}
buffer_consume(blob, sizeof(authfile_id_string));
buffer_init(&copy);
buffer_append(&copy, buffer_ptr(blob), buffer_len(blob));
buffer_consume(&copy, sizeof(authfile_id_string));
/* Read cipher type. */
cipher_type = buffer_get_char(blob);
(void) buffer_get_int(blob); /* Reserved data. */
cipher_type = buffer_get_char(&copy);
(void) buffer_get_int(&copy); /* Reserved data. */
/* Read the public key from the buffer. */
(void) buffer_get_int(blob);
(void) buffer_get_int(&copy);
prv = key_new_private(KEY_RSA1);
buffer_get_bignum(blob, prv->rsa->n);
buffer_get_bignum(blob, prv->rsa->e);
buffer_get_bignum(&copy, prv->rsa->n);
buffer_get_bignum(&copy, prv->rsa->e);
if (commentp)
*commentp = buffer_get_string(blob, NULL);
*commentp = buffer_get_string(&copy, NULL);
else
(void)buffer_get_string_ptr(blob, NULL);
(void)buffer_get_string_ptr(&copy, NULL);
/* Check that it is a supported cipher. */
cipher = cipher_by_number(cipher_type);
if (cipher == NULL) {
debug("Unsupported RSA1 cipher %d", cipher_type);
buffer_free(&copy);
goto fail;
}
/* Initialize space for decrypted data. */
buffer_init(&decrypted);
cp = buffer_append_space(&decrypted, buffer_len(blob));
cp = buffer_append_space(&decrypted, buffer_len(&copy));
/* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
cipher_set_key_string(&ciphercontext, cipher, passphrase,
CIPHER_DECRYPT);
cipher_crypt(&ciphercontext, cp,
buffer_ptr(blob), buffer_len(blob));
buffer_ptr(&copy), buffer_len(&copy));
cipher_cleanup(&ciphercontext);
memset(&ciphercontext, 0, sizeof(ciphercontext));
buffer_clear(blob);
buffer_free(&copy);
check1 = buffer_get_char(&decrypted);
check2 = buffer_get_char(&decrypted);
@ -606,7 +630,7 @@ key_perm_ok(int fd, const char *filename)
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
error("Permissions 0%3.3o for '%s' are too open.",
(u_int)st.st_mode & 0777, filename);
error("It is recommended that your private key files are NOT accessible by others.");
error("It is required that your private key files are NOT accessible by others.");
error("This private key will be ignored.");
return 0;
}
@ -626,6 +650,7 @@ key_parse_private_type(Buffer *blob, int type, const char *passphrase,
case KEY_UNSPEC:
return key_parse_private_pem(blob, type, passphrase, commentp);
default:
error("%s: cannot parse key type %d", __func__, type);
break;
}
return NULL;
@ -669,12 +694,35 @@ key_load_private_type(int type, const char *filename, const char *passphrase,
return ret;
}
Key *
key_parse_private(Buffer *buffer, const char *filename,
const char *passphrase, char **commentp)
{
Key *pub, *prv;
/* it's a SSH v1 key if the public key part is readable */
pub = key_parse_public_rsa1(buffer, commentp);
if (pub == NULL) {
prv = key_parse_private_type(buffer, KEY_UNSPEC,
passphrase, NULL);
/* use the filename as a comment for PEM */
if (commentp && prv)
*commentp = xstrdup(filename);
} else {
key_free(pub);
/* key_parse_public_rsa1() has already loaded the comment */
prv = key_parse_private_type(buffer, KEY_RSA1, passphrase,
NULL);
}
return prv;
}
Key *
key_load_private(const char *filename, const char *passphrase,
char **commentp)
{
Key *pub, *prv;
Buffer buffer, pubcopy;
Key *prv;
Buffer buffer;
int fd;
fd = open(filename, O_RDONLY);
@ -697,23 +745,7 @@ key_load_private(const char *filename, const char *passphrase,
}
close(fd);
buffer_init(&pubcopy);
buffer_append(&pubcopy, buffer_ptr(&buffer), buffer_len(&buffer));
/* it's a SSH v1 key if the public key part is readable */
pub = key_parse_public_rsa1(&pubcopy, commentp);
buffer_free(&pubcopy);
if (pub == NULL) {
prv = key_parse_private_type(&buffer, KEY_UNSPEC,
passphrase, NULL);
/* use the filename as a comment for PEM */
if (commentp && prv)
*commentp = xstrdup(filename);
} else {
key_free(pub);
/* key_parse_public_rsa1() has already loaded the comment */
prv = key_parse_private_type(&buffer, KEY_RSA1, passphrase,
NULL);
}
prv = key_parse_private(&buffer, filename, passphrase, commentp);
buffer_free(&buffer);
return prv;
}
@ -737,13 +769,19 @@ key_try_load_public(Key *k, const char *filename, char **commentp)
case '\0':
continue;
}
/* Abort loading if this looks like a private key */
if (strncmp(cp, "-----BEGIN", 10) == 0)
break;
/* Skip leading whitespace. */
for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
;
if (*cp) {
if (key_read(k, &cp) == 1) {
if (commentp)
*commentp=xstrdup(filename);
cp[strcspn(cp, "\r\n")] = '\0';
if (commentp) {
*commentp = xstrdup(*cp ?
cp : filename);
}
fclose(f);
return 1;
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: authfile.h,v 1.15 2010/08/04 05:42:47 djm Exp $ */
/* $OpenBSD: authfile.h,v 1.16 2011/05/04 21:15:29 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -16,9 +16,11 @@
#define AUTHFILE_H
int key_save_private(Key *, const char *, const char *, const char *);
int key_load_file(int, const char *, Buffer *);
Key *key_load_cert(const char *);
Key *key_load_public(const char *, char **);
Key *key_load_public_type(int, const char *, char **);
Key *key_parse_private(Buffer *, const char *, const char *, char **);
Key *key_load_private(const char *, const char *, char **);
Key *key_load_private_cert(int, const char *, const char *, int *);
Key *key_load_private_type(int, const char *, const char *, char **, int *);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: channels.c,v 1.310 2010/11/24 01:24:14 djm Exp $ */
/* $OpenBSD: channels.c,v 1.311 2011/06/22 22:08:42 djm Exp $ */
/* $FreeBSD$ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -3638,7 +3638,7 @@ deny_input_open(int type, u_int32_t seq, void *ctxt)
*/
void
x11_request_forwarding_with_spoofing(int client_session_id, const char *disp,
const char *proto, const char *data)
const char *proto, const char *data, int want_reply)
{
u_int data_len = (u_int) strlen(data) / 2;
u_int i, value;
@ -3691,7 +3691,7 @@ x11_request_forwarding_with_spoofing(int client_session_id, const char *disp,
/* Send the request packet. */
if (compat20) {
channel_request_start(client_session_id, "x11-req", 0);
channel_request_start(client_session_id, "x11-req", want_reply);
packet_put_char(0); /* XXX bool single connection */
} else {
packet_start(SSH_CMSG_X11_REQUEST_FORWARDING);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: channels.h,v 1.104 2010/05/14 23:29:23 djm Exp $ */
/* $OpenBSD: channels.h,v 1.105 2011/06/22 22:08:42 djm Exp $ */
/* $FreeBSD$ */
/*
@ -278,7 +278,7 @@ int x11_connect_display(void);
int x11_create_display_inet(int, int, int, u_int *, int **);
void x11_input_open(int, u_int32_t, void *);
void x11_request_forwarding_with_spoofing(int, const char *, const char *,
const char *);
const char *, int);
void deny_input_open(int, u_int32_t, void *);
/* agent forwarding */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: clientloop.c,v 1.231 2011/01/16 12:05:59 djm Exp $ */
/* $OpenBSD: clientloop.c,v 1.236 2011/06/22 22:08:42 djm Exp $ */
/* $FreeBSD$ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -131,9 +131,6 @@ extern int muxserver_sock; /* XXX use mux_client_cleanup() instead */
*/
extern char *host;
/* Force TTY allocation */
extern int force_tty_flag;
/*
* Flag to indicate that we have received a window change signal which has
* not yet been processed. This will cause a message indicating the new
@ -180,7 +177,8 @@ struct escape_filter_ctx {
/* Context for channel confirmation replies */
struct channel_reply_ctx {
const char *request_type;
int id, do_close;
int id;
enum confirm_action action;
};
/* Global request success/failure callbacks */
@ -266,10 +264,10 @@ static void
set_control_persist_exit_time(void)
{
if (muxserver_sock == -1 || !options.control_persist
|| options.control_persist_timeout == 0)
|| options.control_persist_timeout == 0) {
/* not using a ControlPersist timeout */
control_persist_exit_time = 0;
else if (channel_still_open()) {
} else if (channel_still_open()) {
/* some client connections are still open */
if (control_persist_exit_time > 0)
debug2("%s: cancel scheduled exit", __func__);
@ -663,7 +661,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
atomicio(vwrite, fileno(stderr), buffer_ptr(berr),
buffer_len(berr));
leave_raw_mode(force_tty_flag);
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
/*
* Free (and clear) the buffer to reduce the amount of data that gets
@ -684,7 +682,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
buffer_init(bout);
buffer_init(berr);
enter_raw_mode(force_tty_flag);
enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
}
static void
@ -743,6 +741,15 @@ client_status_confirm(int type, Channel *c, void *ctx)
char errmsg[256];
int tochan;
/*
* If a TTY was explicitly requested, then a failure to allocate
* one is fatal.
*/
if (cr->action == CONFIRM_TTY &&
(options.request_tty == REQUEST_TTY_FORCE ||
options.request_tty == REQUEST_TTY_YES))
cr->action = CONFIRM_CLOSE;
/* XXX supress on mux _client_ quietmode */
tochan = options.log_level >= SYSLOG_LEVEL_ERROR &&
c->ctl_chan != -1 && c->extended_usage == CHAN_EXTENDED_WRITE;
@ -760,14 +767,27 @@ client_status_confirm(int type, Channel *c, void *ctx)
cr->request_type, c->self);
}
/* If error occurred on primary session channel, then exit */
if (cr->do_close && c->self == session_ident)
if (cr->action == CONFIRM_CLOSE && c->self == session_ident)
fatal("%s", errmsg);
/* If error occurred on mux client, append to their stderr */
if (tochan)
buffer_append(&c->extended, errmsg, strlen(errmsg));
else
/*
* If error occurred on mux client, append to
* their stderr.
*/
if (tochan) {
buffer_append(&c->extended, errmsg,
strlen(errmsg));
} else
error("%s", errmsg);
if (cr->do_close) {
if (cr->action == CONFIRM_TTY) {
/*
* If a TTY allocation error occurred, then arrange
* for the correct TTY to leave raw mode.
*/
if (c->self == session_ident)
leave_raw_mode(0);
else
mux_tty_alloc_failed(c);
} else if (cr->action == CONFIRM_CLOSE) {
chan_read_failed(c);
chan_write_failed(c);
}
@ -781,13 +801,14 @@ client_abandon_status_confirm(Channel *c, void *ctx)
xfree(ctx);
}
static void
client_expect_confirm(int id, const char *request, int do_close)
void
client_expect_confirm(int id, const char *request,
enum confirm_action action)
{
struct channel_reply_ctx *cr = xmalloc(sizeof(*cr));
cr->request_type = request;
cr->do_close = do_close;
cr->action = action;
channel_register_status_confirm(id, client_status_confirm,
client_abandon_status_confirm, cr);
@ -827,7 +848,7 @@ process_cmdline(void)
bzero(&fwd, sizeof(fwd));
fwd.listen_host = fwd.connect_host = NULL;
leave_raw_mode(force_tty_flag);
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
handler = signal(SIGINT, SIG_IGN);
cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
if (s == NULL)
@ -931,7 +952,7 @@ process_cmdline(void)
out:
signal(SIGINT, handler);
enter_raw_mode(force_tty_flag);
enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
if (cmd)
xfree(cmd);
if (fwd.listen_host != NULL)
@ -1050,7 +1071,8 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
* more new connections).
*/
/* Restore tty modes. */
leave_raw_mode(force_tty_flag);
leave_raw_mode(
options.request_tty == REQUEST_TTY_FORCE);
/* Stop listening for new connections. */
channel_stop_listening();
@ -1345,7 +1367,7 @@ client_channel_closed(int id, void *arg)
{
channel_cancel_cleanup(id);
session_closed = 1;
leave_raw_mode(force_tty_flag);
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
}
/*
@ -1416,18 +1438,21 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
signal(SIGWINCH, window_change_handler);
if (have_pty)
enter_raw_mode(force_tty_flag);
enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
if (compat20) {
session_ident = ssh2_chan_id;
if (escape_char_arg != SSH_ESCAPECHAR_NONE)
channel_register_filter(session_ident,
client_simple_escape_filter, NULL,
client_filter_cleanup,
client_new_escape_filter_ctx(escape_char_arg));
if (session_ident != -1)
if (session_ident != -1) {
if (escape_char_arg != SSH_ESCAPECHAR_NONE) {
channel_register_filter(session_ident,
client_simple_escape_filter, NULL,
client_filter_cleanup,
client_new_escape_filter_ctx(
escape_char_arg));
}
channel_register_cleanup(session_ident,
client_channel_closed, 0);
}
} else {
/* Check if we should immediately send eof on stdin. */
client_check_initial_eof_on_stdin();
@ -1557,7 +1582,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
channel_free_all();
if (have_pty)
leave_raw_mode(force_tty_flag);
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
/* restore blocking io */
if (!isatty(fileno(stdin)))
@ -2000,7 +2025,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
memset(&ws, 0, sizeof(ws));
channel_request_start(id, "pty-req", 1);
client_expect_confirm(id, "PTY allocation", 1);
client_expect_confirm(id, "PTY allocation", CONFIRM_TTY);
packet_put_cstring(term != NULL ? term : "");
packet_put_int((u_int)ws.ws_col);
packet_put_int((u_int)ws.ws_row);
@ -2059,18 +2084,18 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
debug("Sending subsystem: %.*s",
len, (u_char*)buffer_ptr(cmd));
channel_request_start(id, "subsystem", 1);
client_expect_confirm(id, "subsystem", 1);
client_expect_confirm(id, "subsystem", CONFIRM_CLOSE);
} else {
debug("Sending command: %.*s",
len, (u_char*)buffer_ptr(cmd));
channel_request_start(id, "exec", 1);
client_expect_confirm(id, "exec", 1);
client_expect_confirm(id, "exec", CONFIRM_CLOSE);
}
packet_put_string(buffer_ptr(cmd), buffer_len(cmd));
packet_send();
} else {
channel_request_start(id, "shell", 1);
client_expect_confirm(id, "shell", 1);
client_expect_confirm(id, "shell", CONFIRM_CLOSE);
packet_send();
}
}
@ -2140,11 +2165,26 @@ client_init_dispatch(void)
client_init_dispatch_15();
}
void
client_stop_mux(void)
{
if (options.control_path != NULL && muxserver_sock != -1)
unlink(options.control_path);
/*
* If we are in persist mode, signal that we should close when all
* active channels are closed.
*/
if (options.control_persist) {
session_closed = 1;
setproctitle("[stopped mux]");
}
}
/* client specific fatal cleanup */
void
cleanup_exit(int i)
{
leave_raw_mode(force_tty_flag);
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
leave_non_blocking();
if (options.control_path != NULL && muxserver_sock != -1)
unlink(options.control_path);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: clientloop.h,v 1.25 2010/06/25 23:15:36 djm Exp $ */
/* $OpenBSD: clientloop.h,v 1.28 2011/06/22 22:08:42 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -45,6 +45,7 @@ void client_global_request_reply_fwd(int, u_int32_t, void *);
void client_session2_setup(int, int, int, const char *, struct termios *,
int, Buffer *, char **);
int client_request_tun_fwd(int, int, int);
void client_stop_mux(void);
/* Escape filter for protocol 2 sessions */
void *client_new_escape_filter_ctx(int);
@ -55,6 +56,10 @@ int client_simple_escape_filter(Channel *, char *, int);
typedef void global_confirm_cb(int, u_int32_t seq, void *);
void client_register_global_confirm(global_confirm_cb *, void *);
/* Channel request confirmation callbacks */
enum confirm_action { CONFIRM_WARN = 0, CONFIRM_CLOSE, CONFIRM_TTY };
void client_expect_confirm(int, const char *, enum confirm_action);
/* Multiplexing protocol version */
#define SSHMUX_VER 4
@ -64,7 +69,10 @@ void client_register_global_confirm(global_confirm_cb *, void *);
#define SSHMUX_COMMAND_TERMINATE 3 /* Ask master to exit */
#define SSHMUX_COMMAND_STDIO_FWD 4 /* Open stdio fwd (ssh -W) */
#define SSHMUX_COMMAND_FORWARD 5 /* Forward only, no command */
#define SSHMUX_COMMAND_STOP 6 /* Disable mux but not conn */
void muxserver_listen(void);
void muxclient(const char *);
void mux_exit_message(Channel *, int);
void mux_tty_alloc_failed(Channel *);

View File

@ -1,10 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
# Free Software Foundation, Inc.
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011 Free Software Foundation, Inc.
timestamp='2009-12-30'
timestamp='2011-01-23'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@ -57,7 +57,7 @@ GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
@ -270,7 +270,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
exit ;;
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
exitcode=$?
trap '' 0
exit $exitcode ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
@ -552,7 +555,7 @@ EOF
echo rs6000-ibm-aix3.2
fi
exit ;;
*:AIX:*:[456])
*:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
@ -968,6 +971,9 @@ EOF
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
tile*:Linux:*:*)
echo ${UNAME_MACHINE}-tilera-linux-gnu
exit ;;
vax:Linux:*:*)
echo ${UNAME_MACHINE}-dec-linux-gnu
exit ;;
@ -1231,6 +1237,9 @@ EOF
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
NEO-?:NONSTOP_KERNEL:*:*)
echo neo-tandem-nsk${UNAME_RELEASE}
exit ;;
NSE-?:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;

View File

@ -126,9 +126,6 @@
/* Enable for PKCS#11 support */
#define ENABLE_PKCS11 /**/
/* Builtin PRNG command timeout */
#define ENTROPY_TIMEOUT_MSEC 200
/* File names may not contain backslash characters */
/* #undef FILESYSTEM_NO_BACKSLASH */
@ -754,6 +751,9 @@
/* Define to 1 if you have the `recvmsg' function. */
#define HAVE_RECVMSG 1
/* sys/resource.h has RLIMIT_NPROC */
#define HAVE_RLIMIT_NPROC /**/
/* Define to 1 if you have the <rpc/types.h> header file. */
#define HAVE_RPC_TYPES_H 1
@ -766,6 +766,12 @@
/* Define to 1 if you have the `RSA_get_default_method' function. */
#define HAVE_RSA_GET_DEFAULT_METHOD 1
/* Define to 1 if you have the <sandbox.h> header file. */
/* #undef HAVE_SANDBOX_H */
/* Define to 1 if you have the `sandbox_init' function. */
/* #undef HAVE_SANDBOX_INIT */
/* define if you have sa_family_t data type */
#define HAVE_SA_FAMILY_T 1
@ -1263,7 +1269,7 @@
from environment and PATH */
#define LOGIN_PROGRAM_FALLBACK "/usr/bin/login"
/* Set this to your mail directory if you don't have maillock.h */
/* Set this to your mail directory if you do not have _PATH_MAILDIR */
/* #undef MAIL_DIRECTORY */
/* Define on *nto-qnx systems */
@ -1336,6 +1342,18 @@
/* read(1) can return 0 for a non-closed fd */
/* #undef PTY_ZEROREAD */
/* Sandbox using Darwin sandbox_init(3) */
/* #undef SANDBOX_DARWIN */
/* no privsep sandboxing */
/* #undef SANDBOX_NULL */
/* Sandbox using setrlimit(2) */
#define SANDBOX_RLIMIT 1
/* Sandbox using systrace(4) */
/* #undef SANDBOX_SYSTRACE */
/* Define if your platform breaks doing a seteuid before a setuid */
/* #undef SETEUID_BREAKS_SETUID */
@ -1469,10 +1487,14 @@
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
#elif ! defined __LITTLE_ENDIAN__
/* # undef WORDS_BIGENDIAN */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Define if xauth is found in your path */

View File

@ -1,5 +1,8 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
/* Define if you have a getaddrinfo that fails for the all-zeros IPv6 address
*/
#undef AIX_GETNAMEINFO_HACK
@ -122,9 +125,6 @@
/* Enable for PKCS#11 support */
#undef ENABLE_PKCS11
/* Builtin PRNG command timeout */
#undef ENTROPY_TIMEOUT_MSEC
/* File names may not contain backslash characters */
#undef FILESYSTEM_NO_BACKSLASH
@ -750,6 +750,9 @@
/* Define to 1 if you have the `recvmsg' function. */
#undef HAVE_RECVMSG
/* sys/resource.h has RLIMIT_NPROC */
#undef HAVE_RLIMIT_NPROC
/* Define to 1 if you have the <rpc/types.h> header file. */
#undef HAVE_RPC_TYPES_H
@ -762,6 +765,12 @@
/* Define to 1 if you have the `RSA_get_default_method' function. */
#undef HAVE_RSA_GET_DEFAULT_METHOD
/* Define to 1 if you have the <sandbox.h> header file. */
#undef HAVE_SANDBOX_H
/* Define to 1 if you have the `sandbox_init' function. */
#undef HAVE_SANDBOX_INIT
/* define if you have sa_family_t data type */
#undef HAVE_SA_FAMILY_T
@ -948,13 +957,13 @@
/* define if you have struct sockaddr_in6 data type */
#undef HAVE_STRUCT_SOCKADDR_IN6
/* Define to 1 if `sin6_scope_id' is member of `struct sockaddr_in6'. */
/* Define to 1 if `sin6_scope_id' is a member of `struct sockaddr_in6'. */
#undef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
/* define if you have struct sockaddr_storage data type */
#undef HAVE_STRUCT_SOCKADDR_STORAGE
/* Define to 1 if `st_blksize' is member of `struct stat'. */
/* Define to 1 if `st_blksize' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_BLKSIZE
/* Define to 1 if the system has the type `struct timespec'. */
@ -1259,7 +1268,7 @@
from environment and PATH */
#undef LOGIN_PROGRAM_FALLBACK
/* Set this to your mail directory if you don't have maillock.h */
/* Set this to your mail directory if you do not have _PATH_MAILDIR */
#undef MAIL_DIRECTORY
/* Define on *nto-qnx systems */
@ -1307,6 +1316,9 @@
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
@ -1329,6 +1341,18 @@
/* read(1) can return 0 for a non-closed fd */
#undef PTY_ZEROREAD
/* Sandbox using Darwin sandbox_init(3) */
#undef SANDBOX_DARWIN
/* no privsep sandboxing */
#undef SANDBOX_NULL
/* Sandbox using setrlimit(2) */
#undef SANDBOX_RLIMIT
/* Sandbox using systrace(4) */
#undef SANDBOX_SYSTRACE
/* Define if your platform breaks doing a seteuid before a setuid */
#undef SETEUID_BREAKS_SETUID
@ -1460,9 +1484,17 @@
/* Define if you want SELinux support. */
#undef WITH_SELINUX
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
# undef WORDS_BIGENDIAN
# endif
#endif
/* Define if xauth is found in your path */
#undef XAUTH_PATH

View File

@ -25,7 +25,7 @@
#ifndef _DEFINES_H
#define _DEFINES_H
/* $Id: defines.h,v 1.165 2011/05/05 01:19:15 djm Exp $ */
/* $Id: defines.h,v 1.167 2011/06/03 01:17:49 tim Exp $ */
/* Constants */
@ -131,6 +131,10 @@ enum
# define O_NONBLOCK 00004 /* Non Blocking Open */
#endif
#ifndef S_IFSOCK
# define S_IFSOCK 0
#endif /* S_IFSOCK */
#ifndef S_ISDIR
# define S_ISDIR(mode) (((mode) & (_S_IFMT)) == (_S_IFDIR))
#endif /* S_ISDIR */
@ -385,18 +389,15 @@ struct winsize {
# define _PATH_DEVNULL "/dev/null"
#endif
#ifndef MAIL_DIRECTORY
# define MAIL_DIRECTORY "/var/spool/mail"
#endif
/* user may have set a different path */
#if defined(_PATH_MAILDIR) && defined(MAIL_DIRECTORY)
# undef _PATH_MAILDIR MAILDIR
#endif /* defined(_PATH_MAILDIR) && defined(MAIL_DIRECTORY) */
#ifndef MAILDIR
# define MAILDIR MAIL_DIRECTORY
#ifdef MAIL_DIRECTORY
# define _PATH_MAILDIR MAIL_DIRECTORY
#endif
#if !defined(_PATH_MAILDIR) && defined(MAILDIR)
# define _PATH_MAILDIR MAILDIR
#endif /* !defined(_PATH_MAILDIR) && defined(MAILDIR) */
#ifndef _PATH_NOLOGIN
# define _PATH_NOLOGIN "/etc/nologin"
#endif

View File

@ -25,19 +25,19 @@
#include "includes.h"
#include <sys/types.h>
#include <sys/wait.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_UN_H
# include <sys/un.h>
#endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#include <stdarg.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <stddef.h> /* for offsetof */
#include <openssl/rand.h>
#include <openssl/crypto.h>
@ -54,119 +54,128 @@
/*
* Portable OpenSSH PRNG seeding:
* If OpenSSL has not "internally seeded" itself (e.g. pulled data from
* /dev/random), then we execute a "ssh-rand-helper" program which
* collects entropy and writes it to stdout. The child program must
* write at least RANDOM_SEED_SIZE bytes. The child is run with stderr
* attached, so error/debugging output should be visible.
*
* XXX: we should tell the child how many bytes we need.
* /dev/random), then collect RANDOM_SEED_SIZE bytes of randomness from
* PRNGd.
*/
#ifndef OPENSSL_PRNG_ONLY
#define RANDOM_SEED_SIZE 48
static uid_t original_uid, original_euid;
#endif
void
seed_rng(void)
/*
* Collect 'len' bytes of entropy into 'buf' from PRNGD/EGD daemon
* listening either on 'tcp_port', or via Unix domain socket at *
* 'socket_path'.
* Either a non-zero tcp_port or a non-null socket_path must be
* supplied.
* Returns 0 on success, -1 on error
*/
int
get_random_bytes_prngd(unsigned char *buf, int len,
unsigned short tcp_port, char *socket_path)
{
#ifndef OPENSSL_PRNG_ONLY
int devnull;
int p[2];
pid_t pid;
int ret;
unsigned char buf[RANDOM_SEED_SIZE];
mysig_t old_sigchld;
int fd, addr_len, rval, errors;
u_char msg[2];
struct sockaddr_storage addr;
struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr;
struct sockaddr_un *addr_un = (struct sockaddr_un *)&addr;
mysig_t old_sigpipe;
if (RAND_status() == 1) {
debug3("RNG is ready, skipping seeding");
return;
/* Sanity checks */
if (socket_path == NULL && tcp_port == 0)
fatal("You must specify a port or a socket");
if (socket_path != NULL &&
strlen(socket_path) >= sizeof(addr_un->sun_path))
fatal("Random pool path is too long");
if (len <= 0 || len > 255)
fatal("Too many bytes (%d) to read from PRNGD", len);
memset(&addr, '\0', sizeof(addr));
if (tcp_port != 0) {
addr_in->sin_family = AF_INET;
addr_in->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr_in->sin_port = htons(tcp_port);
addr_len = sizeof(*addr_in);
} else {
addr_un->sun_family = AF_UNIX;
strlcpy(addr_un->sun_path, socket_path,
sizeof(addr_un->sun_path));
addr_len = offsetof(struct sockaddr_un, sun_path) +
strlen(socket_path) + 1;
}
debug3("Seeding PRNG from %s", SSH_RAND_HELPER);
old_sigpipe = mysignal(SIGPIPE, SIG_IGN);
if ((devnull = open("/dev/null", O_RDWR)) == -1)
fatal("Couldn't open /dev/null: %s", strerror(errno));
if (pipe(p) == -1)
fatal("pipe: %s", strerror(errno));
errors = 0;
rval = -1;
reopen:
fd = socket(addr.ss_family, SOCK_STREAM, 0);
if (fd == -1) {
error("Couldn't create socket: %s", strerror(errno));
goto done;
}
old_sigchld = signal(SIGCHLD, SIG_DFL);
if ((pid = fork()) == -1)
fatal("Couldn't fork: %s", strerror(errno));
if (pid == 0) {
dup2(devnull, STDIN_FILENO);
dup2(p[1], STDOUT_FILENO);
/* Keep stderr open for errors */
close(p[0]);
close(p[1]);
close(devnull);
closefrom(STDERR_FILENO + 1);
if (original_uid != original_euid &&
( seteuid(getuid()) == -1 ||
setuid(original_uid) == -1) ) {
fprintf(stderr, "(rand child) setuid(%li): %s\n",
(long int)original_uid, strerror(errno));
_exit(1);
if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) {
if (tcp_port != 0) {
error("Couldn't connect to PRNGD port %d: %s",
tcp_port, strerror(errno));
} else {
error("Couldn't connect to PRNGD socket \"%s\": %s",
addr_un->sun_path, strerror(errno));
}
execl(SSH_RAND_HELPER, "ssh-rand-helper", NULL);
fprintf(stderr, "(rand child) Couldn't exec '%s': %s\n",
SSH_RAND_HELPER, strerror(errno));
_exit(1);
goto done;
}
close(devnull);
close(p[1]);
/* Send blocking read request to PRNGD */
msg[0] = 0x02;
msg[1] = len;
memset(buf, '\0', sizeof(buf));
ret = atomicio(read, p[0], buf, sizeof(buf));
if (ret == -1)
fatal("Couldn't read from ssh-rand-helper: %s",
if (atomicio(vwrite, fd, msg, sizeof(msg)) != sizeof(msg)) {
if (errno == EPIPE && errors < 10) {
close(fd);
errors++;
goto reopen;
}
error("Couldn't write to PRNGD socket: %s",
strerror(errno));
if (ret != sizeof(buf))
fatal("ssh-rand-helper child produced insufficient data");
goto done;
}
close(p[0]);
if (waitpid(pid, &ret, 0) == -1)
fatal("Couldn't wait for ssh-rand-helper completion: %s",
if (atomicio(read, fd, buf, len) != (size_t)len) {
if (errno == EPIPE && errors < 10) {
close(fd);
errors++;
goto reopen;
}
error("Couldn't read from PRNGD socket: %s",
strerror(errno));
signal(SIGCHLD, old_sigchld);
goto done;
}
/* We don't mind if the child exits upon a SIGPIPE */
if (!WIFEXITED(ret) &&
(!WIFSIGNALED(ret) || WTERMSIG(ret) != SIGPIPE))
fatal("ssh-rand-helper terminated abnormally");
if (WEXITSTATUS(ret) != 0)
fatal("ssh-rand-helper exit with exit status %d", ret);
RAND_add(buf, sizeof(buf), sizeof(buf));
memset(buf, '\0', sizeof(buf));
#endif /* OPENSSL_PRNG_ONLY */
if (RAND_status() != 1)
fatal("PRNG is not seeded");
rval = 0;
done:
mysignal(SIGPIPE, old_sigpipe);
if (fd != -1)
close(fd);
return rval;
}
void
init_rng(void)
static int
seed_from_prngd(unsigned char *buf, size_t bytes)
{
/*
* OpenSSL version numbers: MNNFFPPS: major minor fix patch status
* We match major, minor, fix and status (not patch)
*/
if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & ~0xff0L)
fatal("OpenSSL version mismatch. Built against %lx, you "
"have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay());
#ifndef OPENSSL_PRNG_ONLY
original_uid = getuid();
original_euid = geteuid();
#ifdef PRNGD_PORT
debug("trying egd/prngd port %d", PRNGD_PORT);
if (get_random_bytes_prngd(buf, bytes, PRNGD_PORT, NULL) == 0)
return 0;
#endif
#ifdef PRNGD_SOCKET
debug("trying egd/prngd socket %s", PRNGD_SOCKET);
if (get_random_bytes_prngd(buf, bytes, 0, PRNGD_SOCKET) == 0)
return 0;
#endif
return -1;
}
#ifndef OPENSSL_PRNG_ONLY
void
rexec_send_rng_seed(Buffer *m)
{
@ -192,4 +201,34 @@ rexec_recv_rng_seed(Buffer *m)
RAND_add(buf, len, len);
}
}
#endif /* OPENSSL_PRNG_ONLY */
void
seed_rng(void)
{
#ifndef OPENSSL_PRNG_ONLY
unsigned char buf[RANDOM_SEED_SIZE];
#endif
/*
* OpenSSL version numbers: MNNFFPPS: major minor fix patch status
* We match major, minor, fix and status (not patch)
*/
if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & ~0xff0L)
fatal("OpenSSL version mismatch. Built against %lx, you "
"have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay());
#ifndef OPENSSL_PRNG_ONLY
if (RAND_status() == 1) {
debug3("RNG is ready, skipping seeding");
return;
}
if (seed_from_prngd(buf, sizeof(buf)) == -1)
fatal("Could not obtain seed from PRNGd");
RAND_add(buf, sizeof(buf), sizeof(buf));
memset(buf, '\0', sizeof(buf));
#endif /* OPENSSL_PRNG_ONLY */
if (RAND_status() != 1)
fatal("PRNG is not seeded");
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: gss-serv.c,v 1.22 2008/05/08 12:02:23 djm Exp $ */
/* $OpenBSD: gss-serv.c,v 1.23 2011/08/01 19:18:15 markus Exp $ */
/*
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@ -229,6 +229,8 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name)
name->length = get_u32(tok+offset);
offset += 4;
if (UINT_MAX - offset < name->length)
return GSS_S_FAILURE;
if (ename->length < offset+name->length)
return GSS_S_FAILURE;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: key.c,v 1.96 2011/02/04 00:44:21 djm Exp $ */
/* $OpenBSD: key.c,v 1.97 2011/05/17 07:13:31 djm Exp $ */
/*
* read_bignum():
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -1817,6 +1817,9 @@ key_to_certified(Key *k, int legacy)
k->type = legacy ? KEY_DSA_CERT_V00 : KEY_DSA_CERT;
return 0;
case KEY_ECDSA:
if (legacy)
fatal("%s: legacy ECDSA certificates are not supported",
__func__);
k->cert = cert_new();
k->type = KEY_ECDSA_CERT;
return 0;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: log.c,v 1.41 2008/06/10 04:50:25 dtucker Exp $ */
/* $OpenBSD: log.c,v 1.42 2011/06/17 21:44:30 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -56,6 +56,8 @@ static LogLevel log_level = SYSLOG_LEVEL_INFO;
static int log_on_stderr = 1;
static int log_facility = LOG_AUTH;
static char *argv0;
static log_handler_fn *log_handler;
static void *log_handler_ctx;
extern char *__progname;
@ -260,6 +262,9 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
exit(1);
}
log_handler = NULL;
log_handler_ctx = NULL;
log_on_stderr = on_stderr;
if (on_stderr)
return;
@ -326,6 +331,23 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
#define MSGBUFSIZ 1024
void
set_log_handler(log_handler_fn *handler, void *ctx)
{
log_handler = handler;
log_handler_ctx = ctx;
}
void
do_log2(LogLevel level, const char *fmt,...)
{
va_list args;
va_start(args, fmt);
do_log(level, fmt, args);
va_end(args);
}
void
do_log(LogLevel level, const char *fmt, va_list args)
{
@ -337,6 +359,7 @@ do_log(LogLevel level, const char *fmt, va_list args)
char *txt = NULL;
int pri = LOG_INFO;
int saved_errno = errno;
log_handler_fn *tmp_handler;
if (level > log_level)
return;
@ -375,7 +398,7 @@ do_log(LogLevel level, const char *fmt, va_list args)
pri = LOG_ERR;
break;
}
if (txt != NULL) {
if (txt != NULL && log_handler == NULL) {
snprintf(fmtbuf, sizeof(fmtbuf), "%s: %s", txt, fmt);
vsnprintf(msgbuf, sizeof(msgbuf), fmtbuf, args);
} else {
@ -383,7 +406,13 @@ do_log(LogLevel level, const char *fmt, va_list args)
}
strnvis(fmtbuf, msgbuf, sizeof(fmtbuf),
log_on_stderr ? LOG_STDERR_VIS : LOG_SYSLOG_VIS);
if (log_on_stderr) {
if (log_handler != NULL) {
/* Avoid recursion */
tmp_handler = log_handler;
log_handler = NULL;
tmp_handler(level, fmtbuf, log_handler_ctx);
log_handler = tmp_handler;
} else if (log_on_stderr) {
snprintf(msgbuf, sizeof msgbuf, "%s\r\n", fmtbuf);
write(STDERR_FILENO, msgbuf, strlen(msgbuf));
} else {

View File

@ -1,4 +1,4 @@
/* $OpenBSD: log.h,v 1.17 2008/06/13 00:12:02 dtucker Exp $ */
/* $OpenBSD: log.h,v 1.18 2011/06/17 21:44:30 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -46,6 +46,8 @@ typedef enum {
SYSLOG_LEVEL_NOT_SET = -1
} LogLevel;
typedef void (log_handler_fn)(LogLevel, const char *, void *);
void log_init(char *, LogLevel, SyslogFacility, int);
SyslogFacility log_facility_number(char *);
@ -64,6 +66,10 @@ void debug(const char *, ...) __attribute__((format(printf, 1, 2)));
void debug2(const char *, ...) __attribute__((format(printf, 1, 2)));
void debug3(const char *, ...) __attribute__((format(printf, 1, 2)));
void set_log_handler(log_handler_fn *, void *);
void do_log2(LogLevel, const char *, ...)
__attribute__((format(printf, 2, 3)));
void do_log(LogLevel, const char *, va_list);
void cleanup_exit(int) __attribute__((noreturn));
#endif

View File

@ -1,4 +1,4 @@
/* $OpenBSD: mac.c,v 1.15 2008/06/13 00:51:47 dtucker Exp $ */
/* $OpenBSD: mac.c,v 1.16 2011/08/02 01:22:11 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@ -57,6 +57,12 @@ struct {
} macs[] = {
{ "hmac-sha1", SSH_EVP, EVP_sha1, 0, -1, -1 },
{ "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, -1, -1 },
#ifdef HAVE_EVP_SHA256
{ "hmac-sha2-256", SSH_EVP, EVP_sha256, 0, -1, -1 },
{ "hmac-sha2-256-96", SSH_EVP, EVP_sha256, 96, -1, -1 },
{ "hmac-sha2-512", SSH_EVP, EVP_sha512, 0, -1, -1 },
{ "hmac-sha2-512-96", SSH_EVP, EVP_sha512, 96, -1, -1 },
#endif
{ "hmac-md5", SSH_EVP, EVP_md5, 0, -1, -1 },
{ "hmac-md5-96", SSH_EVP, EVP_md5, 96, -1, -1 },
{ "hmac-ripemd160", SSH_EVP, EVP_ripemd160, 0, -1, -1 },

View File

@ -1,4 +1,4 @@
/* $OpenBSD: misc.c,v 1.84 2010/11/21 01:01:13 djm Exp $ */
/* $OpenBSD: misc.c,v 1.85 2011/03/29 18:54:17 stevesk Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -986,6 +986,19 @@ parse_ipqos(const char *cp)
return val;
}
const char *
iptos2str(int iptos)
{
int i;
static char iptos_str[sizeof "0xff"];
for (i = 0; ipqos[i].name != NULL; i++) {
if (ipqos[i].value == iptos)
return ipqos[i].name;
}
snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos);
return iptos_str;
}
void
sock_set_v6only(int s)
{

View File

@ -1,4 +1,4 @@
/* $OpenBSD: misc.h,v 1.47 2010/11/21 01:01:13 djm Exp $ */
/* $OpenBSD: misc.h,v 1.48 2011/03/29 18:54:17 stevesk Exp $ */
/* $FreeBSD$ */
/*
@ -91,6 +91,7 @@ void bandwidth_limit_init(struct bwlimit *, u_int64_t, size_t);
void bandwidth_limit(struct bwlimit *, size_t);
int parse_ipqos(const char *);
const char *iptos2str(int);
void mktemp_proto(char *, size_t);
/* readpass.c */

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: moduli.5,v 1.12 2008/06/26 05:57:54 djm Exp $
.\" $OpenBSD: moduli.5,v 1.15 2010/10/14 20:41:28 jmc Exp $
.\"
.\" Copyright (c) 2008 Damien Miller <djm@mindrot.org>
.\"
@ -13,16 +13,16 @@
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.Dd June 26, 2008
.Dd October 14, 2010
.Dt MODULI 5
.Os
.Sh NAME
.Nm moduli
.Nd Diffie Hellman moduli
.Nd Diffie-Hellman moduli
.Sh DESCRIPTION
The
.Pa /etc/moduli
file contains prime numbers and generators for use by
file contains prime numbers and generators for use by
.Xr sshd 8
in the Diffie-Hellman Group Exchange key exchange method.
.Pp
@ -31,24 +31,23 @@ New moduli may be generated with
using a two-step process.
An initial
.Em candidate generation
pass, using
pass, using
.Ic ssh-keygen -G ,
calculates numbers that are likely to be useful.
A second
.Em primality testing
pass, using
.Ic ssh-keygen -T
.Ic ssh-keygen -T ,
provides a high degree of assurance that the numbers are prime and are
safe for use in Diffie Hellman operations by
safe for use in Diffie-Hellman operations by
.Xr sshd 8 .
This
.Nm
format is used as the output from each pass.
.Pp
The file consists of newline-separated records, one per modulus,
containing seven space separated fields.
containing seven space-separated fields.
These fields are as follows:
.Pp
.Bl -tag -width Description -offset indent
.It timestamp
The time that the modulus was last processed as YYYYMMDDHHMMSS.
@ -58,7 +57,7 @@ Supported types are:
.Pp
.Bl -tag -width 0x00 -compact
.It 0
Unknown, not tested
Unknown, not tested.
.It 2
"Safe" prime; (p-1)/2 is also prime.
.It 4
@ -68,7 +67,7 @@ Sophie Germain; (p+1)*2 is also prime.
Moduli candidates initially produced by
.Xr ssh-keygen 1
are Sophie Germain primes (type 4).
Futher primality testing with
Further primality testing with
.Xr ssh-keygen 1
produces safe prime moduli (type 2) that are ready for use in
.Xr sshd 8 .
@ -79,13 +78,13 @@ has been subjected to represented as a bitmask of the following values:
.Pp
.Bl -tag -width 0x00 -compact
.It 0x00
Not tested
Not tested.
.It 0x01
Composite number - not prime.
Composite number \(en not prime.
.It 0x02
Sieve of Eratosthenes
Sieve of Eratosthenes.
.It 0x04
Probabalistic Miller-Rabin primality tests.
Probabilistic Miller-Rabin primality tests.
.El
.Pp
The
@ -95,8 +94,8 @@ Subsequent
.Xr ssh-keygen 1
primality tests are Miller-Rabin tests (flag 0x04).
.It trials
Decimal number indicating of primaility trials that have been performed
on the modulus.
Decimal number indicating the number of primality trials
that have been performed on the modulus.
.It size
Decimal number indicating the size of the prime in bits.
.It generator
@ -105,18 +104,17 @@ The recommended generator for use with this modulus (hexadecimal).
The modulus itself in hexadecimal.
.El
.Pp
When performing Diffie Hellman Group Exchange,
When performing Diffie-Hellman Group Exchange,
.Xr sshd 8
first estimates the size of the modulus required to produce enough
Diffie Hellman output to sufficiently key the selected symmetric cipher.
Diffie-Hellman output to sufficiently key the selected symmetric cipher.
.Xr sshd 8
then randomly selects a modulus from
.Fa /etc/moduli
that best meets the size requirement.
.Pp
.Sh SEE ALSO
.Xr ssh-keygen 1 ,
.Xr sshd 8 ,
.Xr sshd 8
.Rs
.%R RFC 4419
.%T "Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol"

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor.c,v 1.110 2010/09/09 10:45:45 djm Exp $ */
/* $OpenBSD: monitor.c,v 1.115 2011/06/23 23:35:42 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -44,6 +44,13 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef HAVE_POLL_H
#include <poll.h>
#else
# ifdef HAVE_SYS_POLL_H
# include <sys/poll.h>
# endif
#endif
#ifdef SKEY
#include <skey.h>
@ -52,6 +59,7 @@
#include <openssl/dh.h>
#include "openbsd-compat/sys-queue.h"
#include "atomicio.h"
#include "xmalloc.h"
#include "ssh.h"
#include "key.h"
@ -179,6 +187,8 @@ int mm_answer_audit_event(int, Buffer *);
int mm_answer_audit_command(int, Buffer *);
#endif
static int monitor_read_log(struct monitor *);
static Authctxt *authctxt;
static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */
@ -346,6 +356,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
debug3("preauth child monitor started");
close(pmonitor->m_recvfd);
close(pmonitor->m_log_sendfd);
pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1;
authctxt = _authctxt;
memset(authctxt, 0, sizeof(*authctxt));
@ -405,6 +419,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
#endif
}
/* Drain any buffered messages from the child */
while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0)
;
if (!authctxt->valid)
fatal("%s: authenticated invalid user", __func__);
if (strcmp(auth_method, "unknown") == 0)
@ -414,6 +432,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
__func__, authctxt->user);
mm_get_keystate(pmonitor);
close(pmonitor->m_sendfd);
close(pmonitor->m_log_recvfd);
pmonitor->m_sendfd = pmonitor->m_log_recvfd = -1;
}
static void
@ -431,6 +453,9 @@ monitor_child_handler(int sig)
void
monitor_child_postauth(struct monitor *pmonitor)
{
close(pmonitor->m_recvfd);
pmonitor->m_recvfd = -1;
monitor_set_child_handler(pmonitor->m_pid);
signal(SIGHUP, &monitor_child_handler);
signal(SIGTERM, &monitor_child_handler);
@ -454,6 +479,9 @@ monitor_child_postauth(struct monitor *pmonitor)
for (;;)
monitor_read(pmonitor, mon_dispatch, NULL);
close(pmonitor->m_sendfd);
pmonitor->m_sendfd = -1;
}
void
@ -465,6 +493,52 @@ monitor_sync(struct monitor *pmonitor)
}
}
static int
monitor_read_log(struct monitor *pmonitor)
{
Buffer logmsg;
u_int len, level;
char *msg;
buffer_init(&logmsg);
/* Read length */
buffer_append_space(&logmsg, 4);
if (atomicio(read, pmonitor->m_log_recvfd,
buffer_ptr(&logmsg), buffer_len(&logmsg)) != buffer_len(&logmsg)) {
if (errno == EPIPE) {
debug("%s: child log fd closed", __func__);
close(pmonitor->m_log_recvfd);
pmonitor->m_log_recvfd = -1;
return -1;
}
fatal("%s: log fd read: %s", __func__, strerror(errno));
}
len = buffer_get_int(&logmsg);
if (len <= 4 || len > 8192)
fatal("%s: invalid log message length %u", __func__, len);
/* Read severity, message */
buffer_clear(&logmsg);
buffer_append_space(&logmsg, len);
if (atomicio(read, pmonitor->m_log_recvfd,
buffer_ptr(&logmsg), buffer_len(&logmsg)) != buffer_len(&logmsg))
fatal("%s: log fd read: %s", __func__, strerror(errno));
/* Log it */
level = buffer_get_int(&logmsg);
msg = buffer_get_string(&logmsg, NULL);
if (log_level_name(level) == NULL)
fatal("%s: invalid log level %u (corrupted message?)",
__func__, level);
do_log2(level, "%s [preauth]", msg);
buffer_free(&logmsg);
xfree(msg);
return 0;
}
int
monitor_read(struct monitor *pmonitor, struct mon_table *ent,
struct mon_table **pent)
@ -472,6 +546,30 @@ monitor_read(struct monitor *pmonitor, struct mon_table *ent,
Buffer m;
int ret;
u_char type;
struct pollfd pfd[2];
for (;;) {
bzero(&pfd, sizeof(pfd));
pfd[0].fd = pmonitor->m_sendfd;
pfd[0].events = POLLIN;
pfd[1].fd = pmonitor->m_log_recvfd;
pfd[1].events = pfd[1].fd == -1 ? 0 : POLLIN;
if (poll(pfd, pfd[1].fd == -1 ? 1 : 2, -1) == -1) {
if (errno == EINTR || errno == EAGAIN)
continue;
fatal("%s: poll: %s", __func__, strerror(errno));
}
if (pfd[1].revents) {
/*
* Drain all log messages before processing next
* monitor request.
*/
monitor_read_log(pmonitor);
continue;
}
if (pfd[0].revents)
break; /* Continues below */
}
buffer_init(&m);
@ -632,6 +730,7 @@ mm_answer_pwnamallow(int sock, Buffer *m)
char *username;
struct passwd *pwent;
int allowed = 0;
u_int i;
debug3("%s", __func__);
@ -671,8 +770,20 @@ mm_answer_pwnamallow(int sock, Buffer *m)
out:
buffer_put_string(m, &options, sizeof(options));
if (options.banner != NULL)
buffer_put_cstring(m, options.banner);
#define M_CP_STROPT(x) do { \
if (options.x != NULL) \
buffer_put_cstring(m, options.x); \
} while (0)
#define M_CP_STRARRAYOPT(x, nx) do { \
for (i = 0; i < options.nx; i++) \
buffer_put_cstring(m, options.x[i]); \
} while (0)
/* See comment in servconf.h */
COPY_MATCH_STRING_OPTS();
#undef M_CP_STROPT
#undef M_CP_STRARRAYOPT
debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed);
mm_request_send(sock, MONITOR_ANS_PWNAM, m);
@ -684,7 +795,6 @@ mm_answer_pwnamallow(int sock, Buffer *m)
monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
}
#ifdef USE_PAM
if (options.use_pam)
monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1);
@ -1834,22 +1944,31 @@ mm_init_compression(struct mm_master *mm)
/* XXX */
#define FD_CLOSEONEXEC(x) do { \
if (fcntl(x, F_SETFD, 1) == -1) \
if (fcntl(x, F_SETFD, FD_CLOEXEC) == -1) \
fatal("fcntl(%d, F_SETFD)", x); \
} while (0)
static void
monitor_socketpair(int *pair)
monitor_openfds(struct monitor *mon, int do_logfds)
{
#ifdef HAVE_SOCKETPAIR
int pair[2];
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
fatal("%s: socketpair", __func__);
#else
fatal("%s: UsePrivilegeSeparation=yes not supported",
__func__);
#endif
fatal("%s: socketpair: %s", __func__, strerror(errno));
FD_CLOSEONEXEC(pair[0]);
FD_CLOSEONEXEC(pair[1]);
mon->m_recvfd = pair[0];
mon->m_sendfd = pair[1];
if (do_logfds) {
if (pipe(pair) == -1)
fatal("%s: pipe: %s", __func__, strerror(errno));
FD_CLOSEONEXEC(pair[0]);
FD_CLOSEONEXEC(pair[1]);
mon->m_log_recvfd = pair[0];
mon->m_log_sendfd = pair[1];
} else
mon->m_log_recvfd = mon->m_log_sendfd = -1;
}
#define MM_MEMSIZE 65536
@ -1858,14 +1977,10 @@ struct monitor *
monitor_init(void)
{
struct monitor *mon;
int pair[2];
mon = xcalloc(1, sizeof(*mon));
monitor_socketpair(pair);
mon->m_recvfd = pair[0];
mon->m_sendfd = pair[1];
monitor_openfds(mon, 1);
/* Used to share zlib space across processes */
if (options.compression) {
@ -1882,12 +1997,7 @@ monitor_init(void)
void
monitor_reinit(struct monitor *mon)
{
int pair[2];
monitor_socketpair(pair);
mon->m_recvfd = pair[0];
mon->m_sendfd = pair[1];
monitor_openfds(mon, 0);
}
#ifdef GSSAPI

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor.h,v 1.15 2008/11/04 08:22:13 djm Exp $ */
/* $OpenBSD: monitor.h,v 1.16 2011/06/17 21:44:31 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
@ -72,6 +72,8 @@ struct mm_master;
struct monitor {
int m_recvfd;
int m_sendfd;
int m_log_recvfd;
int m_log_sendfd;
struct mm_master *m_zback;
struct mm_master *m_zlib;
struct Kex **m_pkex;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor_wrap.c,v 1.70 2010/08/31 11:54:45 djm Exp $ */
/* $OpenBSD: monitor_wrap.c,v 1.73 2011/06/17 21:44:31 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -88,6 +88,32 @@ extern struct monitor *pmonitor;
extern Buffer loginmsg;
extern ServerOptions options;
void
mm_log_handler(LogLevel level, const char *msg, void *ctx)
{
Buffer log_msg;
struct monitor *mon = (struct monitor *)ctx;
if (mon->m_log_sendfd == -1)
fatal("%s: no log channel", __func__);
buffer_init(&log_msg);
/*
* Placeholder for packet length. Will be filled in with the actual
* packet length once the packet has been constucted. This saves
* fragile math.
*/
buffer_put_int(&log_msg, 0);
buffer_put_int(&log_msg, level);
buffer_put_cstring(&log_msg, msg);
put_u32(buffer_ptr(&log_msg), buffer_len(&log_msg) - 4);
if (atomicio(vwrite, mon->m_log_sendfd, buffer_ptr(&log_msg),
buffer_len(&log_msg)) != buffer_len(&log_msg))
fatal("%s: write: %s", __func__, strerror(errno));
buffer_free(&log_msg);
}
int
mm_is_monitor(void)
{
@ -211,7 +237,7 @@ mm_getpwnamallow(const char *username)
{
Buffer m;
struct passwd *pw;
u_int len;
u_int len, i;
ServerOptions *newopts;
debug3("%s entering", __func__);
@ -245,8 +271,20 @@ mm_getpwnamallow(const char *username)
newopts = buffer_get_string(&m, &len);
if (len != sizeof(*newopts))
fatal("%s: option block size mismatch", __func__);
if (newopts->banner != NULL)
newopts->banner = buffer_get_string(&m, NULL);
#define M_CP_STROPT(x) do { \
if (newopts->x != NULL) \
newopts->x = buffer_get_string(&m, NULL); \
} while (0)
#define M_CP_STRARRAYOPT(x, nx) do { \
for (i = 0; i < newopts->nx; i++) \
newopts->x[i] = buffer_get_string(&m, NULL); \
} while (0)
/* See comment in servconf.h */
COPY_MATCH_STRING_OPTS();
#undef M_CP_STROPT
#undef M_CP_STRARRAYOPT
copy_set_server_options(&options, newopts, 1);
xfree(newopts);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor_wrap.h,v 1.22 2009/03/05 07:18:19 djm Exp $ */
/* $OpenBSD: monitor_wrap.h,v 1.23 2011/06/17 21:44:31 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
@ -37,6 +37,7 @@ struct monitor;
struct mm_master;
struct Authctxt;
void mm_log_handler(LogLevel, const char *, void *);
int mm_is_monitor(void);
DH *mm_choose_dh(int, int, int);
int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: mux.c,v 1.24 2011/01/13 21:54:53 djm Exp $ */
/* $OpenBSD: mux.c,v 1.29 2011/06/22 22:08:42 djm Exp $ */
/*
* Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
*
@ -87,7 +87,6 @@
/* from ssh.c */
extern int tty_flag;
extern int force_tty_flag;
extern Options options;
extern int stdin_null_flag;
extern char *host;
@ -146,6 +145,7 @@ struct mux_master_state {
#define MUX_C_OPEN_FWD 0x10000006
#define MUX_C_CLOSE_FWD 0x10000007
#define MUX_C_NEW_STDIO_FWD 0x10000008
#define MUX_C_STOP_LISTENING 0x10000009
#define MUX_S_OK 0x80000001
#define MUX_S_PERMISSION_DENIED 0x80000002
#define MUX_S_FAILURE 0x80000003
@ -153,6 +153,7 @@ struct mux_master_state {
#define MUX_S_ALIVE 0x80000005
#define MUX_S_SESSION_OPENED 0x80000006
#define MUX_S_REMOTE_PORT 0x80000007
#define MUX_S_TTY_ALLOC_FAIL 0x80000008
/* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */
#define MUX_FWD_LOCAL 1
@ -168,6 +169,7 @@ static int process_mux_terminate(u_int, Channel *, Buffer *, Buffer *);
static int process_mux_open_fwd(u_int, Channel *, Buffer *, Buffer *);
static int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *);
static int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *);
static int process_mux_stop_listening(u_int, Channel *, Buffer *, Buffer *);
static const struct {
u_int type;
@ -180,6 +182,7 @@ static const struct {
{ MUX_C_OPEN_FWD, process_mux_open_fwd },
{ MUX_C_CLOSE_FWD, process_mux_close_fwd },
{ MUX_C_NEW_STDIO_FWD, process_mux_stdio_fwd },
{ MUX_C_STOP_LISTENING, process_mux_stop_listening },
{ 0, NULL }
};
@ -915,6 +918,39 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
return 0;
}
static int
process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r)
{
debug("%s: channel %d: stop listening", __func__, c->self);
if (options.control_master == SSHCTL_MASTER_ASK ||
options.control_master == SSHCTL_MASTER_AUTO_ASK) {
if (!ask_permission("Disable further multiplexing on shared "
"connection to %s? ", host)) {
debug2("%s: stop listen refused by user", __func__);
buffer_put_int(r, MUX_S_PERMISSION_DENIED);
buffer_put_int(r, rid);
buffer_put_cstring(r, "Permission denied");
return 0;
}
}
if (mux_listener_channel != NULL) {
channel_free(mux_listener_channel);
client_stop_mux();
xfree(options.control_path);
options.control_path = NULL;
mux_listener_channel = NULL;
muxserver_sock = -1;
}
/* prepare reply */
buffer_put_int(r, MUX_S_OK);
buffer_put_int(r, rid);
return 0;
}
/* Channel callbacks fired on read/write from mux slave fd */
static int
mux_master_read_cb(Channel *c)
@ -1019,6 +1055,27 @@ mux_exit_message(Channel *c, int exitval)
buffer_free(&m);
}
void
mux_tty_alloc_failed(Channel *c)
{
Buffer m;
Channel *mux_chan;
debug3("%s: channel %d: TTY alloc failed", __func__, c->self);
if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL)
fatal("%s: channel %d missing mux channel %d",
__func__, c->self, c->ctl_chan);
/* Append exit message packet to control socket output queue */
buffer_init(&m);
buffer_put_int(&m, MUX_S_TTY_ALLOC_FAIL);
buffer_put_int(&m, c->self);
buffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m));
buffer_free(&m);
}
/* Prepare a mux master to listen on a Unix domain socket. */
void
muxserver_listen(void)
@ -1059,21 +1116,25 @@ muxserver_listen(void)
strlen(options.control_path) + 1;
if (strlcpy(addr.sun_path, options.control_path,
sizeof(addr.sun_path)) >= sizeof(addr.sun_path))
fatal("ControlPath too long");
sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) {
error("ControlPath \"%s\" too long for Unix domain socket",
options.control_path);
goto disable_mux_master;
}
if ((muxserver_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
fatal("%s socket(): %s", __func__, strerror(errno));
old_umask = umask(0177);
if (bind(muxserver_sock, (struct sockaddr *)&addr, sun_len) == -1) {
muxserver_sock = -1;
if (errno == EINVAL || errno == EADDRINUSE) {
error("ControlSocket %s already exists, "
"disabling multiplexing", options.control_path);
disable_mux_master:
close(muxserver_sock);
muxserver_sock = -1;
if (muxserver_sock != -1) {
close(muxserver_sock);
muxserver_sock = -1;
}
xfree(options.control_path);
options.control_path = NULL;
options.control_master = SSHCTL_MASTER_NO;
@ -1153,8 +1214,10 @@ mux_session_confirm(int id, int success, void *arg)
/* Request forwarding with authentication spoofing. */
debug("Requesting X11 forwarding with authentication "
"spoofing.");
x11_request_forwarding_with_spoofing(id, display, proto, data);
/* XXX wait for reply */
x11_request_forwarding_with_spoofing(id, display, proto,
data, 1);
client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN);
/* XXX exit_on_forward_failure */
}
if (cctx->want_agent_fwd && options.forward_agent) {
@ -1573,7 +1636,7 @@ mux_client_request_session(int fd)
char *e, *term;
u_int i, rid, sid, esid, exitval, type, exitval_seen;
extern char **environ;
int devnull;
int devnull, rawmode;
debug3("%s: entering", __func__);
@ -1669,8 +1732,9 @@ mux_client_request_session(int fd)
signal(SIGTERM, control_client_sighandler);
signal(SIGWINCH, control_client_sigrelay);
rawmode = tty_flag;
if (tty_flag)
enter_raw_mode(force_tty_flag);
enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
/*
* Stick around until the controlee closes the client_fd.
@ -1684,22 +1748,35 @@ mux_client_request_session(int fd)
if (mux_client_read_packet(fd, &m) != 0)
break;
type = buffer_get_int(&m);
if (type != MUX_S_EXIT_MESSAGE) {
switch (type) {
case MUX_S_TTY_ALLOC_FAIL:
if ((esid = buffer_get_int(&m)) != sid)
fatal("%s: tty alloc fail on unknown session: "
"my id %u theirs %u",
__func__, sid, esid);
leave_raw_mode(options.request_tty ==
REQUEST_TTY_FORCE);
rawmode = 0;
continue;
case MUX_S_EXIT_MESSAGE:
if ((esid = buffer_get_int(&m)) != sid)
fatal("%s: exit on unknown session: "
"my id %u theirs %u",
__func__, sid, esid);
if (exitval_seen)
fatal("%s: exitval sent twice", __func__);
exitval = buffer_get_int(&m);
exitval_seen = 1;
continue;
default:
e = buffer_get_string(&m, NULL);
fatal("%s: master returned error: %s", __func__, e);
}
if ((esid = buffer_get_int(&m)) != sid)
fatal("%s: exit on unknown session: my id %u theirs %u",
__func__, sid, esid);
debug("%s: master session id: %u", __func__, sid);
if (exitval_seen)
fatal("%s: exitval sent twice", __func__);
exitval = buffer_get_int(&m);
exitval_seen = 1;
}
close(fd);
leave_raw_mode(force_tty_flag);
if (rawmode)
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
if (muxclient_terminate) {
debug2("Exiting on signal %d", muxclient_terminate);
@ -1813,6 +1890,50 @@ mux_client_request_stdio_fwd(int fd)
fatal("%s: master returned unexpected message %u", __func__, type);
}
static void
mux_client_request_stop_listening(int fd)
{
Buffer m;
char *e;
u_int type, rid;
debug3("%s: entering", __func__);
buffer_init(&m);
buffer_put_int(&m, MUX_C_STOP_LISTENING);
buffer_put_int(&m, muxclient_request_id);
if (mux_client_write_packet(fd, &m) != 0)
fatal("%s: write packet: %s", __func__, strerror(errno));
buffer_clear(&m);
/* Read their reply */
if (mux_client_read_packet(fd, &m) != 0)
fatal("%s: read from master failed: %s",
__func__, strerror(errno));
type = buffer_get_int(&m);
if ((rid = buffer_get_int(&m)) != muxclient_request_id)
fatal("%s: out of sequence reply: my id %u theirs %u",
__func__, muxclient_request_id, rid);
switch (type) {
case MUX_S_OK:
break;
case MUX_S_PERMISSION_DENIED:
e = buffer_get_string(&m, NULL);
fatal("Master refused stop listening request: %s", e);
case MUX_S_FAILURE:
e = buffer_get_string(&m, NULL);
fatal("%s: stop listening request failed: %s", __func__, e);
default:
fatal("%s: unexpected response from master 0x%08x",
__func__, type);
}
buffer_free(&m);
muxclient_request_id++;
}
/* Multiplex client main loop. */
void
muxclient(const char *path)
@ -1906,6 +2027,10 @@ muxclient(const char *path)
case SSHMUX_COMMAND_STDIO_FWD:
mux_client_request_stdio_fwd(sock);
exit(0);
case SSHMUX_COMMAND_STOP:
mux_client_request_stop_listening(sock);
fprintf(stderr, "Stop listening request sent.\r\n");
exit(0);
default:
fatal("unrecognised muxclient_command %d", muxclient_command);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: myproposal.h,v 1.27 2010/09/01 22:42:13 djm Exp $ */
/* $OpenBSD: myproposal.h,v 1.28 2011/08/02 01:22:11 djm Exp $ */
/* $FreeBSD$ */
/*
@ -80,10 +80,25 @@
#define KEX_ENCRYPT_INCLUDE_NONE KEX_DEFAULT_ENCRYPT \
",none"
#endif
#ifdef HAVE_EVP_SHA256
#define SHA2_HMAC_MODES \
"hmac-sha2-256," \
"hmac-sha2-256-96," \
"hmac-sha2-512," \
"hmac-sha2-512-96,"
#else
# define SHA2_HMAC_MODES
#endif
#define KEX_DEFAULT_MAC \
"hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160," \
"hmac-md5," \
"hmac-sha1," \
"umac-64@openssh.com," \
SHA2_HMAC_MODES \
"hmac-ripemd160," \
"hmac-ripemd160@openssh.com," \
"hmac-sha1-96,hmac-md5-96"
"hmac-sha1-96," \
"hmac-md5-96"
#define KEX_DEFAULT_COMP "none,zlib@openssh.com,zlib"
#define KEX_DEFAULT_LANG ""

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2001, Corinna Vinschen <vinschen@cygnus.com>
* Copyright (c) 2000, 2001, 2011 Corinna Vinschen <vinschen@redhat.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -34,9 +34,6 @@
#if defined(open) && open == binary_open
# undef open
#endif
#if defined(pipe) && open == binary_pipe
# undef pipe
#endif
#include <sys/types.h>
@ -59,18 +56,6 @@ binary_open(const char *filename, int flags, ...)
return (open(filename, flags | O_BINARY, mode));
}
int
binary_pipe(int fd[2])
{
int ret = pipe(fd);
if (!ret) {
setmode(fd[0], O_BINARY);
setmode(fd[1], O_BINARY);
}
return (ret);
}
int
check_ntsec(const char *filename)
{

View File

@ -1,7 +1,7 @@
/* $Id: bsd-cygwin_util.h,v 1.12 2009/03/08 00:40:28 dtucker Exp $ */
/* $Id: bsd-cygwin_util.h,v 1.13 2011/08/17 01:31:09 djm Exp $ */
/*
* Copyright (c) 2000, 2001, Corinna Vinschen <vinschen@cygnus.com>
* Copyright (c) 2000, 2001, 2011 Corinna Vinschen <vinschen@redhat.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -41,13 +41,11 @@
#include <io.h>
int binary_open(const char *, int , ...);
int binary_pipe(int fd[2]);
int check_ntsec(const char *);
char **fetch_windows_environment(void);
void free_windows_environment(char **);
#define open binary_open
#define pipe binary_pipe
#endif /* HAVE_CYGWIN */

View File

@ -1,4 +1,4 @@
/* $Id: openssl-compat.c,v 1.13 2011/01/21 22:37:06 dtucker Exp $ */
/* $Id: openssl-compat.c,v 1.14 2011/05/10 01:13:38 dtucker Exp $ */
/*
* Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au>
@ -134,9 +134,9 @@ RSA_get_default_method(void)
#ifdef USE_OPENSSL_ENGINE
void
ssh_SSLeay_add_all_algorithms(void)
ssh_OpenSSL_add_all_algorithms(void)
{
SSLeay_add_all_algorithms();
OpenSSL_add_all_algorithms();
/* Enable use of crypto hardware */
ENGINE_load_builtin_engines();

View File

@ -1,4 +1,4 @@
/* $Id: openssl-compat.h,v 1.18 2011/01/21 22:37:06 dtucker Exp $ */
/* $Id: openssl-compat.h,v 1.19 2011/05/10 01:13:38 dtucker Exp $ */
/*
* Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au>
@ -106,10 +106,10 @@ RSA_METHOD *RSA_get_default_method(void);
# endif
# ifdef USE_OPENSSL_ENGINE
# ifdef SSLeay_add_all_algorithms
# undef SSLeay_add_all_algorithms
# ifdef OpenSSL_add_all_algorithms
# undef OpenSSL_add_all_algorithms
# endif
# define SSLeay_add_all_algorithms() ssh_SSLeay_add_all_algorithms()
# define OpenSSL_add_all_algorithms() ssh_OpenSSL_add_all_algorithms()
# endif
# ifndef HAVE_BN_IS_PRIME_EX
@ -129,6 +129,6 @@ int ssh_EVP_CipherInit(EVP_CIPHER_CTX *, const EVP_CIPHER *, unsigned char *,
unsigned char *, int);
int ssh_EVP_Cipher(EVP_CIPHER_CTX *, char *, char *, int);
int ssh_EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *);
void ssh_SSLeay_add_all_algorithms(void);
void ssh_OpenSSL_add_all_algorithms(void);
#endif /* SSH_DONT_OVERLOAD_OPENSSL_FUNCS */

View File

@ -1,4 +1,4 @@
/* $Id: port-linux.c,v 1.11.4.3 2011/02/06 02:24:17 dtucker Exp $ */
/* $Id: port-linux.c,v 1.16 2011/08/29 06:09:57 djm Exp $ */
/*
* Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>
@ -38,6 +38,10 @@
#include <selinux/flask.h>
#include <selinux/get_context_list.h>
#ifndef SSH_SELINUX_UNCONFINED_TYPE
# define SSH_SELINUX_UNCONFINED_TYPE ":unconfined_t:"
#endif
/* Wrapper around is_selinux_enabled() to log its return value once only */
int
ssh_selinux_enabled(void)
@ -177,12 +181,13 @@ ssh_selinux_change_context(const char *newname)
{
int len, newlen;
char *oldctx, *newctx, *cx;
void (*switchlog) (const char *fmt,...) = logit;
if (!ssh_selinux_enabled())
return;
if (getcon((security_context_t *)&oldctx) < 0) {
logit("%s: getcon failed with %s", __func__, strerror (errno));
logit("%s: getcon failed with %s", __func__, strerror(errno));
return;
}
if ((cx = index(oldctx, ':')) == NULL || (cx = index(cx + 1, ':')) ==
@ -191,6 +196,14 @@ ssh_selinux_change_context(const char *newname)
return;
}
/*
* Check whether we are attempting to switch away from an unconfined
* security context.
*/
if (strncmp(cx, SSH_SELINUX_UNCONFINED_TYPE,
sizeof(SSH_SELINUX_UNCONFINED_TYPE) - 1) == 0)
switchlog = debug3;
newlen = strlen(oldctx) + strlen(newname) + 1;
newctx = xmalloc(newlen);
len = cx - oldctx + 1;
@ -198,10 +211,11 @@ ssh_selinux_change_context(const char *newname)
strlcpy(newctx + len, newname, newlen - len);
if ((cx = index(cx + 1, ':')))
strlcat(newctx, cx, newlen);
debug3("%s: setting context from '%s' to '%s'", __func__, oldctx,
newctx);
debug3("%s: setting context from '%s' to '%s'", __func__,
oldctx, newctx);
if (setcon(newctx) < 0)
logit("%s: setcon failed with %s", __func__, strerror (errno));
switchlog("%s: setcon %s from %s failed with %s", __func__,
newctx, oldctx, strerror(errno));
xfree(oldctx);
xfree(newctx);
}

View File

@ -1,4 +1,4 @@
/* $Id: port-linux.h,v 1.4.10.1 2011/02/04 00:42:21 djm Exp $ */
/* $Id: port-linux.h,v 1.5 2011/01/25 01:16:18 djm Exp $ */
/*
* Copyright (c) 2006 Damien Miller <djm@openbsd.org>

0
crypto/openssh/openbsd-compat/sha2.c Executable file → Normal file
View File

0
crypto/openssh/openbsd-compat/sha2.h Executable file → Normal file
View File

View File

@ -1,4 +1,4 @@
/* $OpenBSD: packet.c,v 1.172 2010/11/13 23:27:50 djm Exp $ */
/* $OpenBSD: packet.c,v 1.173 2011/05/06 21:14:05 djm Exp $ */
/* $FreeBSD$ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -426,10 +426,8 @@ packet_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets,
state->bytes = bytes;
}
/* returns 1 if connection is via ipv4 */
int
packet_connection_is_ipv4(void)
static int
packet_connection_af(void)
{
struct sockaddr_storage to;
socklen_t tolen = sizeof(to);
@ -443,9 +441,9 @@ packet_connection_is_ipv4(void)
#ifdef IPV4_IN_IPV6
if (to.ss_family == AF_INET6 &&
IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&to)->sin6_addr))
return 1;
return AF_INET;
#endif
return 0;
return to.ss_family;
}
/* Sets the connection into non-blocking mode. */
@ -1756,16 +1754,30 @@ packet_not_very_much_data_to_write(void)
static void
packet_set_tos(int tos)
{
#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)
if (!packet_connection_is_on_socket() ||
!packet_connection_is_ipv4())
#ifndef IP_TOS_IS_BROKEN
if (!packet_connection_is_on_socket())
return;
debug3("%s: set IP_TOS 0x%02x", __func__, tos);
if (setsockopt(active_state->connection_in, IPPROTO_IP, IP_TOS, &tos,
sizeof(tos)) < 0)
error("setsockopt IP_TOS %d: %.100s:",
tos, strerror(errno));
#endif
switch (packet_connection_af()) {
# ifdef IP_TOS
case AF_INET:
debug3("%s: set IP_TOS 0x%02x", __func__, tos);
if (setsockopt(active_state->connection_in,
IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0)
error("setsockopt IP_TOS %d: %.100s:",
tos, strerror(errno));
break;
# endif /* IP_TOS */
# ifdef IPV6_TCLASS
case AF_INET6:
debug3("%s: set IPV6_TCLASS 0x%02x", __func__, tos);
if (setsockopt(active_state->connection_in,
IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)) < 0)
error("setsockopt IPV6_TCLASS %d: %.100s:",
tos, strerror(errno));
break;
# endif /* IPV6_TCLASS */
}
#endif /* IP_TOS_IS_BROKEN */
}
/* Informs that the current session is interactive. Sets IP flags for that. */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: packet.h,v 1.55 2010/11/13 23:27:50 djm Exp $ */
/* $OpenBSD: packet.h,v 1.56 2011/05/06 21:14:05 djm Exp $ */
/* $FreeBSD$ */
/*
@ -96,7 +96,6 @@ int packet_have_data_to_write(void);
int packet_not_very_much_data_to_write(void);
int packet_connection_is_on_socket(void);
int packet_connection_is_ipv4(void);
int packet_remaining(void);
void packet_send_ignore(int);
void packet_add_padding(u_char);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: pathnames.h,v 1.20 2010/08/31 11:54:45 djm Exp $ */
/* $OpenBSD: pathnames.h,v 1.22 2011/05/23 03:30:07 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>

View File

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.c,v 1.190 2010/11/13 23:27:50 djm Exp $ */
/* $OpenBSD: readconf.c,v 1.193 2011/05/24 07:15:47 djm Exp $ */
/* $FreeBSD$ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -138,7 +138,7 @@ typedef enum {
oHashKnownHosts,
oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
oKexAlgorithms, oIPQoS,
oKexAlgorithms, oIPQoS, oRequestTTY,
oHPNDisabled, oHPNBufferSize, oTcpRcvBufPoll, oTcpRcvBuf,
#ifdef NONE_CIPHER_ENABLED
oNoneEnabled, oNoneSwitch,
@ -202,9 +202,9 @@ static struct {
{ "host", oHost },
{ "escapechar", oEscapeChar },
{ "globalknownhostsfile", oGlobalKnownHostsFile },
{ "globalknownhostsfile2", oGlobalKnownHostsFile2 }, /* obsolete */
{ "globalknownhostsfile2", oDeprecated },
{ "userknownhostsfile", oUserKnownHostsFile },
{ "userknownhostsfile2", oUserKnownHostsFile2 }, /* obsolete */
{ "userknownhostsfile2", oDeprecated },
{ "connectionattempts", oConnectionAttempts },
{ "batchmode", oBatchMode },
{ "checkhostip", oCheckHostIP },
@ -254,6 +254,7 @@ static struct {
#endif
{ "kexalgorithms", oKexAlgorithms },
{ "ipqos", oIPQoS },
{ "requesttty", oRequestTTY },
{ "hpndisabled", oHPNDisabled },
{ "hpnbuffersize", oHPNBufferSize },
{ "tcprcvbufpoll", oTcpRcvBufPoll },
@ -262,7 +263,6 @@ static struct {
{ "noneenabled", oNoneEnabled },
{ "noneswitch", oNoneSwitch },
#endif
{ "versionaddendum", oVersionAddendum },
{ NULL, oBadOption }
};
@ -383,8 +383,10 @@ process_config_line(Options *options, const char *host,
char *line, const char *filename, int linenum,
int *activep)
{
char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
int opcode, *intptr, value, value2, scale;
char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
char **cpptr, fwdarg[256];
u_int *uintptr, max_entries = 0;
int negated, opcode, *intptr, value, value2, scale;
LogLevel *log_level_ptr;
long long orig, val64;
size_t len;
@ -627,26 +629,33 @@ process_config_line(Options *options, const char *host,
parse_string:
arg = strdelim(&s);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename, linenum);
fatal("%.200s line %d: Missing argument.",
filename, linenum);
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
break;
case oGlobalKnownHostsFile:
charptr = &options->system_hostfile;
goto parse_string;
cpptr = (char **)&options->system_hostfiles;
uintptr = &options->num_system_hostfiles;
max_entries = SSH_MAX_HOSTS_FILES;
parse_char_array:
if (*activep && *uintptr == 0) {
while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
if ((*uintptr) >= max_entries)
fatal("%s line %d: "
"too many authorized keys files.",
filename, linenum);
cpptr[(*uintptr)++] = xstrdup(arg);
}
}
return 0;
case oUserKnownHostsFile:
charptr = &options->user_hostfile;
goto parse_string;
case oGlobalKnownHostsFile2:
charptr = &options->system_hostfile2;
goto parse_string;
case oUserKnownHostsFile2:
charptr = &options->user_hostfile2;
goto parse_string;
cpptr = (char **)&options->user_hostfiles;
uintptr = &options->num_user_hostfiles;
max_entries = SSH_MAX_HOSTS_FILES;
goto parse_char_array;
case oHostName:
charptr = &options->hostname;
@ -823,12 +832,28 @@ process_config_line(Options *options, const char *host,
case oHost:
*activep = 0;
while ((arg = strdelim(&s)) != NULL && *arg != '\0')
arg2 = NULL;
while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
negated = *arg == '!';
if (negated)
arg++;
if (match_pattern(host, arg)) {
debug("Applying options for %.100s", arg);
if (negated) {
debug("%.200s line %d: Skipping Host "
"block because of negated match "
"for %.100s", filename, linenum,
arg);
*activep = 0;
break;
}
if (!*activep)
arg2 = arg; /* logged below */
*activep = 1;
break;
}
}
if (*activep)
debug("%.200s line %d: Applying options for %.100s",
filename, linenum, arg2);
/* Avoid garbage check below, as strdelim is done. */
return 0;
@ -1027,11 +1052,24 @@ process_config_line(Options *options, const char *host,
intptr = &options->use_roaming;
goto parse_flag;
case oVersionAddendum:
ssh_version_set_addendum(strtok(s, "\n"));
do {
arg = strdelim(&s);
} while (arg != NULL && *arg != '\0');
case oRequestTTY:
arg = strdelim(&s);
if (!arg || *arg == '\0')
fatal("%s line %d: missing argument.",
filename, linenum);
intptr = &options->request_tty;
if (strcasecmp(arg, "yes") == 0)
value = REQUEST_TTY_YES;
else if (strcasecmp(arg, "no") == 0)
value = REQUEST_TTY_NO;
else if (strcasecmp(arg, "force") == 0)
value = REQUEST_TTY_FORCE;
else if (strcasecmp(arg, "auto") == 0)
value = REQUEST_TTY_AUTO;
else
fatal("Unsupported RequestTTY \"%s\"", arg);
if (*activep && *intptr == -1)
*intptr = value;
break;
case oHPNDisabled:
@ -1075,6 +1113,13 @@ process_config_line(Options *options, const char *host,
}
#endif
case oVersionAddendum:
ssh_version_set_addendum(strtok(s, "\n"));
do {
arg = strdelim(&s);
} while (arg != NULL && *arg != '\0');
break;
case oDeprecated:
debug("%s line %d: Deprecated option \"%s\"",
filename, linenum, keyword);
@ -1199,10 +1244,8 @@ initialize_options(Options * options)
options->proxy_command = NULL;
options->user = NULL;
options->escape_char = -1;
options->system_hostfile = NULL;
options->user_hostfile = NULL;
options->system_hostfile2 = NULL;
options->user_hostfile2 = NULL;
options->num_system_hostfiles = 0;
options->num_user_hostfiles = 0;
options->local_forwards = NULL;
options->num_local_forwards = 0;
options->remote_forwards = NULL;
@ -1235,6 +1278,7 @@ initialize_options(Options * options)
options->zero_knowledge_password_authentication = -1;
options->ip_qos_interactive = -1;
options->ip_qos_bulk = -1;
options->request_tty = -1;
options->hpn_disabled = -1;
options->hpn_buffer_size = -1;
options->tcp_rcv_buf_poll = -1;
@ -1349,14 +1393,18 @@ fill_default_options(Options * options)
}
if (options->escape_char == -1)
options->escape_char = '~';
if (options->system_hostfile == NULL)
options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
if (options->user_hostfile == NULL)
options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
if (options->system_hostfile2 == NULL)
options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
if (options->user_hostfile2 == NULL)
options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
if (options->num_system_hostfiles == 0) {
options->system_hostfiles[options->num_system_hostfiles++] =
xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
options->system_hostfiles[options->num_system_hostfiles++] =
xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
}
if (options->num_user_hostfiles == 0) {
options->user_hostfiles[options->num_user_hostfiles++] =
xstrdup(_PATH_SSH_USER_HOSTFILE);
options->user_hostfiles[options->num_user_hostfiles++] =
xstrdup(_PATH_SSH_USER_HOSTFILE2);
}
if (options->log_level == SYSLOG_LEVEL_NOT_SET)
options->log_level = SYSLOG_LEVEL_INFO;
if (options->clear_forwardings == 1)
@ -1401,6 +1449,8 @@ fill_default_options(Options * options)
options->ip_qos_interactive = IPTOS_LOWDELAY;
if (options->ip_qos_bulk == -1)
options->ip_qos_bulk = IPTOS_THROUGHPUT;
if (options->request_tty == -1)
options->request_tty = REQUEST_TTY_AUTO;
/* options->local_command should not be set by default */
/* options->proxy_command should not be set by default */
/* options->user will be set in the main program if appropriate */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.h,v 1.88 2010/11/13 23:27:50 djm Exp $ */
/* $OpenBSD: readconf.h,v 1.90 2011/05/24 07:15:47 djm Exp $ */
/* $FreeBSD$ */
/*
@ -28,7 +28,8 @@ typedef struct {
} Forward;
/* Data structure for representing option data. */
#define MAX_SEND_ENV 256
#define MAX_SEND_ENV 256
#define SSH_MAX_HOSTS_FILES 256
typedef struct {
int forward_agent; /* Forward authentication agent. */
@ -84,10 +85,10 @@ typedef struct {
char *user; /* User to log in as. */
int escape_char; /* Escape character; -2 = none */
char *system_hostfile;/* Path for /etc/ssh/ssh_known_hosts. */
char *user_hostfile; /* Path for $HOME/.ssh/known_hosts. */
char *system_hostfile2;
char *user_hostfile2;
u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */
char *system_hostfiles[SSH_MAX_HOSTS_FILES];
u_int num_user_hostfiles; /* Path for $HOME/.ssh/known_hosts */
char *user_hostfiles[SSH_MAX_HOSTS_FILES];
char *preferred_authentications;
char *bind_address; /* local socket address for connection to sshd */
char *pkcs11_provider; /* PKCS#11 provider */
@ -132,6 +133,7 @@ typedef struct {
int visual_host_key;
int use_roaming;
int request_tty;
int hpn_disabled; /* Switch to disable HPN buffer management. */
int hpn_buffer_size; /* User definable size for HPN buffer
@ -152,6 +154,11 @@ typedef struct {
#define SSHCTL_MASTER_ASK 3
#define SSHCTL_MASTER_AUTO_ASK 4
#define REQUEST_TTY_AUTO 0
#define REQUEST_TTY_NO 1
#define REQUEST_TTY_YES 2
#define REQUEST_TTY_FORCE 3
void initialize_options(Options *);
void fill_default_options(Options *);
int read_config_file(const char *, const char *, Options *, int);

View File

@ -0,0 +1,98 @@
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "includes.h"
#ifdef SANDBOX_DARWIN
#include <sys/types.h>
#include <sandbox.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "log.h"
#include "sandbox.h"
#include "xmalloc.h"
/* Darwin/OS X sandbox */
struct ssh_sandbox {
pid_t child_pid;
};
struct ssh_sandbox *
ssh_sandbox_init(void)
{
struct ssh_sandbox *box;
/*
* Strictly, we don't need to maintain any state here but we need
* to return non-NULL to satisfy the API.
*/
debug3("%s: preparing Darwin sandbox", __func__);
box = xcalloc(1, sizeof(*box));
box->child_pid = 0;
return box;
}
void
ssh_sandbox_child(struct ssh_sandbox *box)
{
char *errmsg;
struct rlimit rl_zero;
debug3("%s: starting Darwin sandbox", __func__);
if (sandbox_init(kSBXProfilePureComputation, SANDBOX_NAMED,
&errmsg) == -1)
fatal("%s: sandbox_init: %s", __func__, errmsg);
/*
* The kSBXProfilePureComputation still allows sockets, so
* we must disable these using rlimit.
*/
rl_zero.rlim_cur = rl_zero.rlim_max = 0;
if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1)
fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s",
__func__, strerror(errno));
if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1)
fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s",
__func__, strerror(errno));
if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1)
fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s",
__func__, strerror(errno));
}
void
ssh_sandbox_parent_finish(struct ssh_sandbox *box)
{
free(box);
debug3("%s: finished", __func__);
}
void
ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid)
{
box->child_pid = child_pid;
}
#endif /* SANDBOX_DARWIN */

View File

@ -0,0 +1,72 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "includes.h"
#ifdef SANDBOX_NULL
#include <sys/types.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "log.h"
#include "ssh-sandbox.h"
#include "xmalloc.h"
/* dummy sandbox */
struct ssh_sandbox {
int junk;
};
struct ssh_sandbox *
ssh_sandbox_init(void)
{
struct ssh_sandbox *box;
/*
* Strictly, we don't need to maintain any state here but we need
* to return non-NULL to satisfy the API.
*/
box = xcalloc(1, sizeof(*box));
return box;
}
void
ssh_sandbox_child(struct ssh_sandbox *box)
{
/* Nothing to do here */
}
void
ssh_sandbox_parent_finish(struct ssh_sandbox *box)
{
free(box);
}
void
ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid)
{
/* Nothing to do here */
}
#endif /* SANDBOX_NULL */

View File

@ -0,0 +1,93 @@
/* $OpenBSD: sandbox-rlimit.c,v 1.3 2011/06/23 09:34:13 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "includes.h"
#ifdef SANDBOX_RLIMIT
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "log.h"
#include "ssh-sandbox.h"
#include "xmalloc.h"
/* Minimal sandbox that sets zero nfiles, nprocs and filesize rlimits */
struct ssh_sandbox {
pid_t child_pid;
};
struct ssh_sandbox *
ssh_sandbox_init(void)
{
struct ssh_sandbox *box;
/*
* Strictly, we don't need to maintain any state here but we need
* to return non-NULL to satisfy the API.
*/
debug3("%s: preparing rlimit sandbox", __func__);
box = xcalloc(1, sizeof(*box));
box->child_pid = 0;
return box;
}
void
ssh_sandbox_child(struct ssh_sandbox *box)
{
struct rlimit rl_zero;
rl_zero.rlim_cur = rl_zero.rlim_max = 0;
if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1)
fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s",
__func__, strerror(errno));
if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1)
fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s",
__func__, strerror(errno));
#ifdef HAVE_RLIMIT_NPROC
if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1)
fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s",
__func__, strerror(errno));
#endif
}
void
ssh_sandbox_parent_finish(struct ssh_sandbox *box)
{
free(box);
debug3("%s: finished", __func__);
}
void
ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid)
{
box->child_pid = child_pid;
}
#endif /* SANDBOX_RLIMIT */

View File

@ -0,0 +1,198 @@
/* $OpenBSD: sandbox-systrace.c,v 1.4 2011/07/29 14:42:45 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "includes.h"
#ifdef SANDBOX_SYSTRACE
#include <sys/types.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/syscall.h>
#include <sys/socket.h>
#include <dev/systrace.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "atomicio.h"
#include "log.h"
#include "ssh-sandbox.h"
#include "xmalloc.h"
struct sandbox_policy {
int syscall;
int action;
};
/* Permitted syscalls in preauth. Unlisted syscalls get SYSTR_POLICY_KILL */
static const struct sandbox_policy preauth_policy[] = {
{ SYS_open, SYSTR_POLICY_NEVER },
{ SYS___sysctl, SYSTR_POLICY_PERMIT },
{ SYS_close, SYSTR_POLICY_PERMIT },
{ SYS_exit, SYSTR_POLICY_PERMIT },
{ SYS_getpid, SYSTR_POLICY_PERMIT },
{ SYS_gettimeofday, SYSTR_POLICY_PERMIT },
{ SYS_madvise, SYSTR_POLICY_PERMIT },
{ SYS_mmap, SYSTR_POLICY_PERMIT },
{ SYS_mprotect, SYSTR_POLICY_PERMIT },
{ SYS_poll, SYSTR_POLICY_PERMIT },
{ SYS_munmap, SYSTR_POLICY_PERMIT },
{ SYS_read, SYSTR_POLICY_PERMIT },
{ SYS_select, SYSTR_POLICY_PERMIT },
{ SYS_sigprocmask, SYSTR_POLICY_PERMIT },
{ SYS_write, SYSTR_POLICY_PERMIT },
{ -1, -1 }
};
struct ssh_sandbox {
int child_sock;
int parent_sock;
int systrace_fd;
pid_t child_pid;
};
struct ssh_sandbox *
ssh_sandbox_init(void)
{
struct ssh_sandbox *box;
int s[2];
debug3("%s: preparing systrace sandbox", __func__);
box = xcalloc(1, sizeof(*box));
if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == -1)
fatal("%s: socketpair: %s", __func__, strerror(errno));
box->child_sock = s[0];
box->parent_sock = s[1];
box->systrace_fd = -1;
box->child_pid = 0;
return box;
}
void
ssh_sandbox_child(struct ssh_sandbox *box)
{
char whatever = 0;
close(box->parent_sock);
/* Signal parent that we are ready */
debug3("%s: ready", __func__);
if (atomicio(vwrite, box->child_sock, &whatever, 1) != 1)
fatal("%s: write: %s", __func__, strerror(errno));
/* Wait for parent to signal for us to go */
if (atomicio(read, box->child_sock, &whatever, 1) != 1)
fatal("%s: read: %s", __func__, strerror(errno));
debug3("%s: started", __func__);
close(box->child_sock);
}
static void
ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid,
const struct sandbox_policy *allowed_syscalls)
{
int dev_systrace, i, j, found;
char whatever = 0;
struct systrace_policy policy;
debug3("%s: wait for child %ld", __func__, (long)child_pid);
box->child_pid = child_pid;
close(box->child_sock);
/* Wait for child to signal that it is ready */
if (atomicio(read, box->parent_sock, &whatever, 1) != 1)
fatal("%s: read: %s", __func__, strerror(errno));
debug3("%s: child %ld ready", __func__, (long)child_pid);
/* Set up systracing of child */
if ((dev_systrace = open("/dev/systrace", O_RDONLY)) == -1)
fatal("%s: open(\"/dev/systrace\"): %s", __func__,
strerror(errno));
if (ioctl(dev_systrace, STRIOCCLONE, &box->systrace_fd) == -1)
fatal("%s: ioctl(STRIOCCLONE, %d): %s", __func__,
dev_systrace, strerror(errno));
close(dev_systrace);
debug3("%s: systrace attach, fd=%d", __func__, box->systrace_fd);
if (ioctl(box->systrace_fd, STRIOCATTACH, &child_pid) == -1)
fatal("%s: ioctl(%d, STRIOCATTACH, %d): %s", __func__,
box->systrace_fd, child_pid, strerror(errno));
/* Allocate and assign policy */
bzero(&policy, sizeof(policy));
policy.strp_op = SYSTR_POLICY_NEW;
policy.strp_maxents = SYS_MAXSYSCALL;
if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1)
fatal("%s: ioctl(%d, STRIOCPOLICY (new)): %s", __func__,
box->systrace_fd, strerror(errno));
policy.strp_op = SYSTR_POLICY_ASSIGN;
policy.strp_pid = box->child_pid;
if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1)
fatal("%s: ioctl(%d, STRIOCPOLICY (assign)): %s",
__func__, box->systrace_fd, strerror(errno));
/* Set per-syscall policy */
for (i = 0; i < SYS_MAXSYSCALL; i++) {
found = 0;
for (j = 0; allowed_syscalls[j].syscall != -1; j++) {
if (allowed_syscalls[j].syscall == i) {
found = 1;
break;
}
}
policy.strp_op = SYSTR_POLICY_MODIFY;
policy.strp_code = i;
policy.strp_policy = found ?
allowed_syscalls[j].action : SYSTR_POLICY_KILL;
if (found)
debug3("%s: policy: enable syscall %d", __func__, i);
if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1)
fatal("%s: ioctl(%d, STRIOCPOLICY (modify)): %s",
__func__, box->systrace_fd, strerror(errno));
}
/* Signal the child to start running */
debug3("%s: start child %ld", __func__, (long)child_pid);
if (atomicio(vwrite, box->parent_sock, &whatever, 1) != 1)
fatal("%s: write: %s", __func__, strerror(errno));
close(box->parent_sock);
}
void
ssh_sandbox_parent_finish(struct ssh_sandbox *box)
{
/* Closing this before the child exits will terminate it */
close(box->systrace_fd);
free(box);
debug3("%s: finished", __func__);
}
void
ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid)
{
ssh_sandbox_parent(box, child_pid, preauth_policy);
}
#endif /* SANDBOX_SYSTRACE */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: servconf.c,v 1.213 2010/11/13 23:27:50 djm Exp $ */
/* $OpenBSD: servconf.c,v 1.222 2011/06/22 21:57:01 djm Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -129,8 +129,7 @@ initialize_server_options(ServerOptions *options)
options->use_dns = -1;
options->client_alive_interval = -1;
options->client_alive_count_max = -1;
options->authorized_keys_file = NULL;
options->authorized_keys_file2 = NULL;
options->num_authkeys_files = 0;
options->num_accept_env = 0;
options->permit_tun = -1;
options->num_permitted_opens = -1;
@ -273,15 +272,12 @@ fill_default_server_options(ServerOptions *options)
options->client_alive_interval = 0;
if (options->client_alive_count_max == -1)
options->client_alive_count_max = 3;
if (options->authorized_keys_file2 == NULL) {
/* authorized_keys_file2 falls back to authorized_keys_file */
if (options->authorized_keys_file != NULL)
options->authorized_keys_file2 = xstrdup(options->authorized_keys_file);
else
options->authorized_keys_file2 = xstrdup(_PATH_SSH_USER_PERMITTED_KEYS2);
if (options->num_authkeys_files == 0) {
options->authorized_keys_files[options->num_authkeys_files++] =
xstrdup(_PATH_SSH_USER_PERMITTED_KEYS);
options->authorized_keys_files[options->num_authkeys_files++] =
xstrdup(_PATH_SSH_USER_PERMITTED_KEYS2);
}
if (options->authorized_keys_file == NULL)
options->authorized_keys_file = xstrdup(_PATH_SSH_USER_PERMITTED_KEYS);
if (options->permit_tun == -1)
options->permit_tun = SSH_TUNMODE_NO;
if (options->zero_knowledge_password_authentication == -1)
@ -324,7 +320,7 @@ fill_default_server_options(ServerOptions *options)
/* Turn privilege separation on by default */
if (use_privsep == -1)
use_privsep = 1;
use_privsep = PRIVSEP_ON;
#ifndef HAVE_MMAP
if (use_privsep && options->compression == 1) {
@ -361,7 +357,7 @@ typedef enum {
sMaxStartups, sMaxAuthTries, sMaxSessions,
sBanner, sUseDNS, sHostbasedAuthentication,
sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
sClientAliveCountMax, sAuthorizedKeysFile,
sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
sUsePrivilegeSeparation, sAllowAgentForwarding,
@ -483,7 +479,7 @@ static struct {
{ "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
{ "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_ALL },
{ "authorizedkeysfile2", sDeprecated, SSHCFG_ALL },
{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL},
{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
{ "permittunnel", sPermitTunnel, SSHCFG_ALL },
@ -727,6 +723,43 @@ match_cfg_line(char **condition, int line, const char *user, const char *host,
#define WHITESPACE " \t\r\n"
/* Multistate option parsing */
struct multistate {
char *key;
int value;
};
static const struct multistate multistate_addressfamily[] = {
{ "inet", AF_INET },
{ "inet6", AF_INET6 },
{ "any", AF_UNSPEC },
{ NULL, -1 }
};
static const struct multistate multistate_permitrootlogin[] = {
{ "without-password", PERMIT_NO_PASSWD },
{ "forced-commands-only", PERMIT_FORCED_ONLY },
{ "yes", PERMIT_YES },
{ "no", PERMIT_NO },
{ NULL, -1 }
};
static const struct multistate multistate_compression[] = {
{ "delayed", COMP_DELAYED },
{ "yes", COMP_ZLIB },
{ "no", COMP_NONE },
{ NULL, -1 }
};
static const struct multistate multistate_gatewayports[] = {
{ "clientspecified", 2 },
{ "yes", 1 },
{ "no", 0 },
{ NULL, -1 }
};
static const struct multistate multistate_privsep[] = {
{ "sandbox", PRIVSEP_SANDBOX },
{ "yes", PRIVSEP_ON },
{ "no", PRIVSEP_OFF },
{ NULL, -1 }
};
int
process_server_config_line(ServerOptions *options, char *line,
const char *filename, int linenum, int *activep, const char *user,
@ -740,6 +773,7 @@ process_server_config_line(ServerOptions *options, char *line,
int port;
u_int i, flags = 0;
size_t len;
const struct multistate *multistate_ptr;
cp = line;
if ((arg = strdelim(&cp)) == NULL)
@ -855,24 +889,27 @@ process_server_config_line(ServerOptions *options, char *line,
break;
case sAddressFamily:
intptr = &options->address_family;
multistate_ptr = multistate_addressfamily;
if (options->listen_addrs != NULL)
fatal("%s line %d: address family must be specified "
"before ListenAddress.", filename, linenum);
parse_multistate:
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing address family.",
fatal("%s line %d: missing argument.",
filename, linenum);
intptr = &options->address_family;
if (options->listen_addrs != NULL)
fatal("%s line %d: address family must be specified before "
"ListenAddress.", filename, linenum);
if (strcasecmp(arg, "inet") == 0)
value = AF_INET;
else if (strcasecmp(arg, "inet6") == 0)
value = AF_INET6;
else if (strcasecmp(arg, "any") == 0)
value = AF_UNSPEC;
else
fatal("%s line %d: unsupported address family \"%s\".",
value = -1;
for (i = 0; multistate_ptr[i].key != NULL; i++) {
if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
value = multistate_ptr[i].value;
break;
}
}
if (value == -1)
fatal("%s line %d: unsupported option \"%s\".",
filename, linenum, arg);
if (*intptr == -1)
if (*activep && *intptr == -1)
*intptr = value;
break;
@ -911,27 +948,8 @@ process_server_config_line(ServerOptions *options, char *line,
case sPermitRootLogin:
intptr = &options->permit_root_login;
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing yes/"
"without-password/forced-commands-only/no "
"argument.", filename, linenum);
value = 0; /* silence compiler */
if (strcmp(arg, "without-password") == 0)
value = PERMIT_NO_PASSWD;
else if (strcmp(arg, "forced-commands-only") == 0)
value = PERMIT_FORCED_ONLY;
else if (strcmp(arg, "yes") == 0)
value = PERMIT_YES;
else if (strcmp(arg, "no") == 0)
value = PERMIT_NO;
else
fatal("%s line %d: Bad yes/"
"without-password/forced-commands-only/no "
"argument: %s", filename, linenum, arg);
if (*activep && *intptr == -1)
*intptr = value;
break;
multistate_ptr = multistate_permitrootlogin;
goto parse_multistate;
case sIgnoreRhosts:
intptr = &options->ignore_rhosts;
@ -1062,43 +1080,13 @@ process_server_config_line(ServerOptions *options, char *line,
case sCompression:
intptr = &options->compression;
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing yes/no/delayed "
"argument.", filename, linenum);
value = 0; /* silence compiler */
if (strcmp(arg, "delayed") == 0)
value = COMP_DELAYED;
else if (strcmp(arg, "yes") == 0)
value = COMP_ZLIB;
else if (strcmp(arg, "no") == 0)
value = COMP_NONE;
else
fatal("%s line %d: Bad yes/no/delayed "
"argument: %s", filename, linenum, arg);
if (*intptr == -1)
*intptr = value;
break;
multistate_ptr = multistate_compression;
goto parse_multistate;
case sGatewayPorts:
intptr = &options->gateway_ports;
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing yes/no/clientspecified "
"argument.", filename, linenum);
value = 0; /* silence compiler */
if (strcmp(arg, "clientspecified") == 0)
value = 2;
else if (strcmp(arg, "yes") == 0)
value = 1;
else if (strcmp(arg, "no") == 0)
value = 0;
else
fatal("%s line %d: Bad yes/no/clientspecified "
"argument: %s", filename, linenum, arg);
if (*activep && *intptr == -1)
*intptr = value;
break;
multistate_ptr = multistate_gatewayports;
goto parse_multistate;
case sUseDNS:
intptr = &options->use_dns;
@ -1136,7 +1124,8 @@ process_server_config_line(ServerOptions *options, char *line,
case sUsePrivilegeSeparation:
intptr = &use_privsep;
goto parse_flag;
multistate_ptr = multistate_privsep;
goto parse_multistate;
case sAllowUsers:
while ((arg = strdelim(&cp)) && *arg != '\0') {
@ -1302,14 +1291,22 @@ process_server_config_line(ServerOptions *options, char *line,
* AuthorizedKeysFile /etc/ssh_keys/%u
*/
case sAuthorizedKeysFile:
charptr = &options->authorized_keys_file;
goto parse_tilde_filename;
case sAuthorizedKeysFile2:
charptr = &options->authorized_keys_file2;
goto parse_tilde_filename;
if (*activep && options->num_authkeys_files == 0) {
while ((arg = strdelim(&cp)) && *arg != '\0') {
if (options->num_authkeys_files >=
MAX_AUTHKEYS_FILES)
fatal("%s line %d: "
"too many authorized keys files.",
filename, linenum);
options->authorized_keys_files[
options->num_authkeys_files++] =
tilde_expand_filename(arg, getuid());
}
}
return 0;
case sAuthorizedPrincipalsFile:
charptr = &options->authorized_principals_file;
parse_tilde_filename:
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing file name.",
@ -1553,6 +1550,12 @@ parse_server_match_config(ServerOptions *options, const char *user,
dst->n = src->n; \
} \
} while(0)
#define M_CP_STRARRAYOPT(n, num_n) do {\
if (src->num_n != 0) { \
for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \
dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \
} \
} while(0)
/*
* Copy any supported values that are set.
@ -1588,20 +1591,23 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
M_CP_INTOPT(ip_qos_interactive);
M_CP_INTOPT(ip_qos_bulk);
M_CP_STROPT(banner);
/* See comment in servconf.h */
COPY_MATCH_STRING_OPTS();
/*
* The only things that should be below this point are string options
* which are only used after authentication.
*/
if (preauth)
return;
M_CP_STROPT(adm_forced_command);
M_CP_STROPT(chroot_directory);
M_CP_STROPT(trusted_user_ca_keys);
M_CP_STROPT(revoked_keys_file);
M_CP_STROPT(authorized_keys_file);
M_CP_STROPT(authorized_keys_file2);
M_CP_STROPT(authorized_principals_file);
}
#undef M_CP_INTOPT
#undef M_CP_STROPT
#undef M_CP_STRARRAYOPT
void
parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
@ -1626,32 +1632,35 @@ parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
filename, bad_options);
}
static const char *
fmt_multistate_int(int val, const struct multistate *m)
{
u_int i;
for (i = 0; m[i].key != NULL; i++) {
if (m[i].value == val)
return m[i].key;
}
return "UNKNOWN";
}
static const char *
fmt_intarg(ServerOpCodes code, int val)
{
if (code == sAddressFamily) {
switch (val) {
case AF_INET:
return "inet";
case AF_INET6:
return "inet6";
case AF_UNSPEC:
return "any";
default:
return "UNKNOWN";
}
}
if (code == sPermitRootLogin) {
switch (val) {
case PERMIT_NO_PASSWD:
return "without-password";
case PERMIT_FORCED_ONLY:
return "forced-commands-only";
case PERMIT_YES:
return "yes";
}
}
if (code == sProtocol) {
if (val == -1)
return "unset";
switch (code) {
case sAddressFamily:
return fmt_multistate_int(val, multistate_addressfamily);
case sPermitRootLogin:
return fmt_multistate_int(val, multistate_permitrootlogin);
case sGatewayPorts:
return fmt_multistate_int(val, multistate_gatewayports);
case sCompression:
return fmt_multistate_int(val, multistate_compression);
case sUsePrivilegeSeparation:
return fmt_multistate_int(val, multistate_privsep);
case sProtocol:
switch (val) {
case SSH_PROTO_1:
return "1";
@ -1662,20 +1671,16 @@ fmt_intarg(ServerOpCodes code, int val)
default:
return "UNKNOWN";
}
default:
switch (val) {
case 0:
return "no";
case 1:
return "yes";
default:
return "UNKNOWN";
}
}
if (code == sGatewayPorts && val == 2)
return "clientspecified";
if (code == sCompression && val == COMP_DELAYED)
return "delayed";
switch (val) {
case -1:
return "unset";
case 0:
return "no";
case 1:
return "yes";
}
return "UNKNOWN";
}
static const char *
@ -1715,7 +1720,18 @@ dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
u_int i;
for (i = 0; i < count; i++)
printf("%s %s\n", lookup_opcode_name(code), vals[i]);
printf("%s %s\n", lookup_opcode_name(code), vals[i]);
}
static void
dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
{
u_int i;
printf("%s", lookup_opcode_name(code));
for (i = 0; i < count; i++)
printf(" %s", vals[i]);
printf("\n");
}
void
@ -1813,8 +1829,6 @@ dump_config(ServerOptions *o)
dump_cfg_string(sCiphers, o->ciphers);
dump_cfg_string(sMacs, o->macs);
dump_cfg_string(sBanner, o->banner);
dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file);
dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2);
dump_cfg_string(sForceCommand, o->adm_forced_command);
dump_cfg_string(sChrootDirectory, o->chroot_directory);
dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
@ -1827,6 +1841,8 @@ dump_config(ServerOptions *o)
dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
/* string array arguments */
dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files,
o->authorized_keys_files);
dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
o->host_key_files);
dump_cfg_strarray(sHostKeyFile, o->num_host_cert_files,
@ -1852,7 +1868,8 @@ dump_config(ServerOptions *o)
}
dump_cfg_string(sPermitTunnel, s);
printf("ipqos 0x%02x 0x%02x\n", o->ip_qos_interactive, o->ip_qos_bulk);
printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
printf("%s\n", iptos2str(o->ip_qos_bulk));
channel_print_adm_permitted_opens();
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: servconf.h,v 1.95 2010/11/13 23:27:50 djm Exp $ */
/* $OpenBSD: servconf.h,v 1.99 2011/06/22 21:57:01 djm Exp $ */
/* $FreeBSD$ */
/*
@ -28,6 +28,7 @@
#define MAX_HOSTCERTS 256 /* Max # host certificates. */
#define MAX_ACCEPT_ENV 256 /* Max # of env vars. */
#define MAX_MATCH_GROUPS 256 /* Max # of groups for Match. */
#define MAX_AUTHKEYS_FILES 256 /* Max # of authorized_keys files. */
/* permit_root_login */
#define PERMIT_NOT_SET -1
@ -36,6 +37,11 @@
#define PERMIT_NO_PASSWD 2
#define PERMIT_YES 3
/* use_privsep */
#define PRIVSEP_OFF 0
#define PRIVSEP_ON 1
#define PRIVSEP_SANDBOX 2
#define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */
#define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */
@ -146,8 +152,8 @@ typedef struct {
* disconnect the session
*/
char *authorized_keys_file; /* File containing public keys */
char *authorized_keys_file2;
u_int num_authkeys_files; /* Files containing public keys */
char *authorized_keys_files[MAX_AUTHKEYS_FILES];
char *adm_forced_command;
@ -172,6 +178,20 @@ typedef struct {
#endif
} ServerOptions;
/*
* These are string config options that must be copied between the
* Match sub-config and the main config, and must be sent from the
* privsep slave to the privsep master. We use a macro to ensure all
* the options are copied and the copies are done in the correct order.
*/
#define COPY_MATCH_STRING_OPTS() do { \
M_CP_STROPT(banner); \
M_CP_STROPT(trusted_user_ca_keys); \
M_CP_STROPT(revoked_keys_file); \
M_CP_STROPT(authorized_principals_file); \
M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \
} while (0)
void initialize_server_options(ServerOptions *);
void fill_default_server_options(ServerOptions *);
int process_server_config_line(ServerOptions *, char *, const char *, int,

View File

@ -1,4 +1,4 @@
/* $OpenBSD: serverloop.c,v 1.159 2009/05/28 16:50:16 andreas Exp $ */
/* $OpenBSD: serverloop.c,v 1.160 2011/05/15 08:09:01 djm Exp $ */
/* $FreeBSD$ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -132,8 +132,8 @@ notify_setup(void)
{
if (pipe(notify_pipe) < 0) {
error("pipe(notify_pipe) failed %s", strerror(errno));
} else if ((fcntl(notify_pipe[0], F_SETFD, 1) == -1) ||
(fcntl(notify_pipe[1], F_SETFD, 1) == -1)) {
} else if ((fcntl(notify_pipe[0], F_SETFD, FD_CLOEXEC) == -1) ||
(fcntl(notify_pipe[1], F_SETFD, FD_CLOEXEC) == -1)) {
error("fcntl(notify_pipe, F_SETFD) failed %s", strerror(errno));
close(notify_pipe[0]);
close(notify_pipe[1]);

View File

@ -98,6 +98,10 @@ __RCSID("$FreeBSD$");
#include <kafs.h>
#endif
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#endif
#define IS_INTERNAL_SFTP(c) \
(!strncmp(c, INTERNAL_SFTP_NAME, sizeof(INTERNAL_SFTP_NAME) - 1) && \
(c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\0' || \
@ -1547,6 +1551,9 @@ do_pwchange(Session *s)
if (s->ttyfd != -1) {
fprintf(stderr,
"You must change your password now and login again!\n");
#ifdef WITH_SELINUX
setexeccon(NULL);
#endif
#ifdef PASSWD_NEEDS_USERNAME
execl(_PATH_PASSWD_PROG, "passwd", s->pw->pw_name,
(char *)NULL);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sftp-server.c,v 1.93 2010/12/04 00:18:01 djm Exp $ */
/* $OpenBSD: sftp-server.c,v 1.94 2011/06/17 21:46:16 djm Exp $ */
/*
* Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
*
@ -68,7 +68,7 @@ Buffer iqueue;
Buffer oqueue;
/* Version of client */
int version;
u_int version;
/* Disable writes */
int readonly;
@ -522,7 +522,7 @@ process_init(void)
Buffer msg;
version = get_int();
verbose("received client version %d", version);
verbose("received client version %u", version);
buffer_init(&msg);
buffer_put_char(&msg, SSH2_FXP_VERSION);
buffer_put_int(&msg, SSH2_FILEXFER_VERSION);

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: sftp.1,v 1.88 2010/12/04 00:18:01 djm Exp $
.\" $OpenBSD: sftp.1,v 1.90 2011/08/07 12:55:30 dtucker Exp $
.\" $FreeBSD$
.\"
.\" Copyright (c) 2001 Damien Miller. All rights reserved.
@ -23,7 +23,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd December 4, 2010
.Dd August 7, 2011
.Dt SFTP 1
.Os
.Sh NAME
@ -90,6 +90,10 @@ to obviate the need to enter a password at connection time (see
and
.Xr ssh-keygen 1
for details).
.Pp
Since some usage formats use colon characters to delimit host names from path
names, IPv6 addresses must be enclosed in square brackets to avoid ambiguity.
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl 1
@ -481,7 +485,7 @@ is specified, then
.Ar remote-path
must specify a directory.
.Pp
If ether the
If either the
.Fl P
or
.Fl p

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-add.c,v 1.100 2010/08/31 12:33:38 djm Exp $ */
/* $OpenBSD: ssh-add.c,v 1.101 2011/05/04 21:15:29 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -145,8 +145,12 @@ add_file(AuthenticationConnection *ac, const char *filename)
char *comment = NULL;
char msg[1024], *certpath;
int fd, perms_ok, ret = -1;
Buffer keyblob;
if ((fd = open(filename, O_RDONLY)) < 0) {
if (strcmp(filename, "-") == 0) {
fd = STDIN_FILENO;
filename = "(stdin)";
} else if ((fd = open(filename, O_RDONLY)) < 0) {
perror(filename);
return -1;
}
@ -155,18 +159,28 @@ add_file(AuthenticationConnection *ac, const char *filename)
* Since we'll try to load a keyfile multiple times, permission errors
* will occur multiple times, so check perms first and bail if wrong.
*/
perms_ok = key_perm_ok(fd, filename);
close(fd);
if (!perms_ok)
if (fd != STDIN_FILENO) {
perms_ok = key_perm_ok(fd, filename);
if (!perms_ok) {
close(fd);
return -1;
}
}
buffer_init(&keyblob);
if (!key_load_file(fd, filename, &keyblob)) {
buffer_free(&keyblob);
close(fd);
return -1;
}
close(fd);
/* At first, try empty passphrase */
private = key_load_private(filename, "", &comment);
private = key_parse_private(&keyblob, filename, "", &comment);
if (comment == NULL)
comment = xstrdup(filename);
/* try last */
if (private == NULL && pass != NULL)
private = key_load_private(filename, pass, NULL);
private = key_parse_private(&keyblob, filename, pass, NULL);
if (private == NULL) {
/* clear passphrase since it did not work */
clear_pass();
@ -177,9 +191,11 @@ add_file(AuthenticationConnection *ac, const char *filename)
if (strcmp(pass, "") == 0) {
clear_pass();
xfree(comment);
buffer_free(&keyblob);
return -1;
}
private = key_load_private(filename, pass, &comment);
private = key_parse_private(&keyblob, filename, pass,
&comment);
if (private != NULL)
break;
clear_pass();
@ -187,6 +203,7 @@ add_file(AuthenticationConnection *ac, const char *filename)
"Bad passphrase, try again for %.200s: ", comment);
}
}
buffer_free(&keyblob);
if (ssh_add_identity_constrained(ac, private, comment, lifetime,
confirm)) {
@ -372,7 +389,6 @@ main(int argc, char **argv)
sanitise_stdfd();
__progname = ssh_get_progname(argv[0]);
init_rng();
seed_rng();
OpenSSL_add_all_algorithms();

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-agent.c,v 1.171 2010/11/21 01:01:13 djm Exp $ */
/* $OpenBSD: ssh-agent.c,v 1.172 2011/06/03 01:37:40 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -1098,7 +1098,11 @@ cleanup_handler(int sig)
static void
check_parent_exists(void)
{
if (parent_pid != -1 && kill(parent_pid, 0) < 0) {
/*
* If our parent has exited then getppid() will return (pid_t)1,
* so testing for that should be safe.
*/
if (parent_pid != -1 && getppid() != parent_pid) {
/* printf("Parent has died - Authentication agent exiting.\n"); */
cleanup_socket();
_exit(2);
@ -1156,7 +1160,6 @@ main(int ac, char **av)
OpenSSL_add_all_algorithms();
__progname = ssh_get_progname(av[0]);
init_rng();
seed_rng();
while ((ch = getopt(ac, av, "cdksa:t:")) != -1) {

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: ssh-keygen.1,v 1.101 2010/10/28 18:33:28 jmc Exp $
.\" $OpenBSD: ssh-keygen.1,v 1.106 2011/04/13 04:09:37 djm Exp $
.\" $FreeBSD$
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -36,7 +36,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd October 28, 2010
.Dd April 13, 2011
.Dt SSH-KEYGEN 1
.Os
.Sh NAME
@ -118,6 +118,8 @@
.Nm ssh-keygen
.Fl L
.Op Fl f Ar input_keyfile
.Nm ssh-keygen
.Fl A
.Ek
.Sh DESCRIPTION
.Nm
@ -174,9 +176,8 @@ The passphrase can be changed later by using the
option.
.Pp
There is no way to recover a lost passphrase.
If the passphrase is
lost or forgotten, a new key must be generated and copied to the
corresponding public key to other machines.
If the passphrase is lost or forgotten, a new key must be generated
and the corresponding public key copied to other machines.
.Pp
For RSA1 keys,
there is also a comment field in the key file that is only for
@ -193,6 +194,13 @@ should be placed to be activated.
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl A
For each of the key types (rsa1, rsa, dsa and ecdsa) for which host keys
do not exist, generate the host keys with the default key file path,
an empty passphrase, default bits for the key type, and default comment.
This is used by
.Pa /etc/rc
to generate new host keys.
.It Fl a Ar trials
Specifies the number of primality tests to perform when screening DH-GEX
candidates using the
@ -205,6 +213,12 @@ Specifies the number of bits in the key to create.
For RSA keys, the minimum size is 768 bits and the default is 2048 bits.
Generally, 2048 bits is considered sufficient.
DSA keys must be exactly 1024 bits as specified by FIPS 186-2.
For ECDSA keys, the
.Fl b
flag determines they key length by selecting from one of three elliptic
curve sizes: 256, 384 or 521 bits.
Attempting to use bit lengths other than these three values for ECDSA keys
will fail.
.It Fl C Ar comment
Provides a new comment.
.It Fl c
@ -394,9 +408,6 @@ new passphrase.
.It Fl q
Silence
.Nm ssh-keygen .
Used by
.Pa /etc/rc
when creating a new key.
.It Fl R Ar hostname
Removes all keys belonging to
.Ar hostname

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keygen.c,v 1.205 2011/01/11 06:13:10 djm Exp $ */
/* $OpenBSD: ssh-keygen.c,v 1.210 2011/04/18 00:46:05 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -49,10 +49,7 @@
#include "hostfile.h"
#include "dns.h"
#include "ssh2.h"
#ifdef ENABLE_PKCS11
#include "ssh-pkcs11.h"
#endif
/* Number of bits in the RSA/DSA key. This value can be set on the command line. */
#define DEFAULT_BITS 2048
@ -159,6 +156,38 @@ char hostname[MAXHOSTNAMELEN];
int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *);
int prime_test(FILE *, FILE *, u_int32_t, u_int32_t);
static void
type_bits_valid(int type, u_int32_t *bitsp)
{
u_int maxbits;
if (type == KEY_UNSPEC) {
fprintf(stderr, "unknown key type %s\n", key_type_name);
exit(1);
}
if (*bitsp == 0) {
if (type == KEY_DSA)
*bitsp = DEFAULT_BITS_DSA;
else if (type == KEY_ECDSA)
*bitsp = DEFAULT_BITS_ECDSA;
else
*bitsp = DEFAULT_BITS;
}
maxbits = (type == KEY_DSA) ?
OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS;
if (*bitsp > maxbits) {
fprintf(stderr, "key bits exceeds maximum %d\n", maxbits);
exit(1);
}
if (type == KEY_DSA && *bitsp != 1024)
fatal("DSA keys must be 1024 bits");
else if (type != KEY_ECDSA && *bitsp < 768)
fatal("Key must at least be 768 bits");
else if (type == KEY_ECDSA && key_ecdsa_bits_to_nid(*bitsp) == -1)
fatal("Invalid ECDSA key length - valid lengths are "
"256, 384 or 521 bits");
}
static void
ask_filename(struct passwd *pw, const char *prompt)
{
@ -817,6 +846,98 @@ do_fingerprint(struct passwd *pw)
exit(0);
}
static void
do_gen_all_hostkeys(struct passwd *pw)
{
struct {
char *key_type;
char *key_type_display;
char *path;
} key_types[] = {
{ "rsa1", "RSA1", _PATH_HOST_KEY_FILE },
{ "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE },
{ "dsa", "DSA", _PATH_HOST_DSA_KEY_FILE },
{ "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE },
{ NULL, NULL, NULL }
};
int first = 0;
struct stat st;
Key *private, *public;
char comment[1024];
int i, type, fd;
FILE *f;
for (i = 0; key_types[i].key_type; i++) {
if (stat(key_types[i].path, &st) == 0)
continue;
if (errno != ENOENT) {
printf("Could not stat %s: %s", key_types[i].path,
strerror(errno));
first = 0;
continue;
}
if (first == 0) {
first = 1;
printf("%s: generating new host keys: ", __progname);
}
printf("%s ", key_types[i].key_type_display);
fflush(stdout);
arc4random_stir();
type = key_type_from_name(key_types[i].key_type);
strlcpy(identity_file, key_types[i].path, sizeof(identity_file));
bits = 0;
type_bits_valid(type, &bits);
private = key_generate(type, bits);
if (private == NULL) {
fprintf(stderr, "key_generate failed\n");
first = 0;
continue;
}
public = key_from_private(private);
snprintf(comment, sizeof comment, "%s@%s", pw->pw_name,
hostname);
if (!key_save_private(private, identity_file, "", comment)) {
printf("Saving the key failed: %s.\n", identity_file);
key_free(private);
key_free(public);
first = 0;
continue;
}
key_free(private);
arc4random_stir();
strlcat(identity_file, ".pub", sizeof(identity_file));
fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
printf("Could not save your public key in %s\n",
identity_file);
key_free(public);
first = 0;
continue;
}
f = fdopen(fd, "w");
if (f == NULL) {
printf("fdopen %s failed\n", identity_file);
key_free(public);
first = 0;
continue;
}
if (!key_write(public, f)) {
fprintf(stderr, "write key failed\n");
key_free(public);
first = 0;
continue;
}
fprintf(f, " %s\n", comment);
fclose(f);
key_free(public);
}
if (first != 0)
printf("\n");
}
static void
printhost(FILE *f, const char *name, Key *public, int ca, int hash)
{
@ -1329,6 +1450,9 @@ prepare_options_buf(Buffer *c, int which)
if ((which & OPTIONS_CRITICAL) != 0 &&
certflags_command != NULL)
add_string_option(c, "force-command", certflags_command);
if ((which & OPTIONS_EXTENSIONS) != 0 &&
(certflags_flags & CERTOPT_X_FWD) != 0)
add_flag_option(c, "permit-X11-forwarding");
if ((which & OPTIONS_EXTENSIONS) != 0 &&
(certflags_flags & CERTOPT_AGENT_FWD) != 0)
add_flag_option(c, "permit-agent-forwarding");
@ -1341,9 +1465,6 @@ prepare_options_buf(Buffer *c, int which)
if ((which & OPTIONS_EXTENSIONS) != 0 &&
(certflags_flags & CERTOPT_USER_RC) != 0)
add_flag_option(c, "permit-user-rc");
if ((which & OPTIONS_EXTENSIONS) != 0 &&
(certflags_flags & CERTOPT_X_FWD) != 0)
add_flag_option(c, "permit-X11-forwarding");
if ((which & OPTIONS_CRITICAL) != 0 &&
certflags_src_addr != NULL)
add_string_option(c, "source-address", certflags_src_addr);
@ -1593,7 +1714,7 @@ add_cert_option(char *opt)
{
char *val;
if (strcmp(opt, "clear") == 0)
if (strcasecmp(opt, "clear") == 0)
certflags_flags = 0;
else if (strcasecmp(opt, "no-x11-forwarding") == 0)
certflags_flags &= ~CERTOPT_X_FWD;
@ -1745,6 +1866,7 @@ usage(void)
{
fprintf(stderr, "usage: %s [options]\n", __progname);
fprintf(stderr, "Options:\n");
fprintf(stderr, " -A Generate non-existent host keys for all key types.\n");
fprintf(stderr, " -a trials Number of trials for screening DH-GEX moduli.\n");
fprintf(stderr, " -B Show bubblebabble digest of key file.\n");
fprintf(stderr, " -b bits Number of bits in the key to create.\n");
@ -1799,9 +1921,9 @@ main(int argc, char **argv)
struct passwd *pw;
struct stat st;
int opt, type, fd;
u_int maxbits;
u_int32_t memory = 0, generator_wanted = 0, trials = 100;
int do_gen_candidates = 0, do_screen_candidates = 0;
int gen_all_hostkeys = 0;
BIGNUM *start = NULL;
FILE *f;
const char *errstr;
@ -1817,7 +1939,6 @@ main(int argc, char **argv)
OpenSSL_add_all_algorithms();
log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
init_rng();
seed_rng();
/* we need this for the home * directory. */
@ -1831,9 +1952,12 @@ main(int argc, char **argv)
exit(1);
}
while ((opt = getopt(argc, argv, "degiqpclBHLhvxXyF:b:f:t:D:I:P:m:N:n:"
while ((opt = getopt(argc, argv, "AegiqpclBHLhvxXyF:b:f:t:D:I:P:m:N:n:"
"O:C:r:g:R:T:G:M:S:s:a:V:W:z:")) != -1) {
switch (opt) {
case 'A':
gen_all_hostkeys = 1;
break;
case 'b':
bits = (u_int32_t)strtonum(optarg, 256, 32768, &errstr);
if (errstr)
@ -1928,9 +2052,6 @@ main(int argc, char **argv)
case 'y':
print_public = 1;
break;
case 'd':
key_type_name = "dsa";
break;
case 's':
ca_key_path = optarg;
break;
@ -2109,37 +2230,19 @@ main(int argc, char **argv)
return (0);
}
if (gen_all_hostkeys) {
do_gen_all_hostkeys(pw);
return (0);
}
arc4random_stir();
if (key_type_name == NULL)
key_type_name = "rsa";
type = key_type_from_name(key_type_name);
if (type == KEY_UNSPEC) {
fprintf(stderr, "unknown key type %s\n", key_type_name);
exit(1);
}
if (bits == 0) {
if (type == KEY_DSA)
bits = DEFAULT_BITS_DSA;
else if (type == KEY_ECDSA)
bits = DEFAULT_BITS_ECDSA;
else
bits = DEFAULT_BITS;
}
maxbits = (type == KEY_DSA) ?
OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS;
if (bits > maxbits) {
fprintf(stderr, "key bits exceeds maximum %d\n", maxbits);
exit(1);
}
if (type == KEY_DSA && bits != 1024)
fatal("DSA keys must be 1024 bits");
else if (type != KEY_ECDSA && bits < 768)
fatal("Key must at least be 768 bits");
else if (type == KEY_ECDSA && key_ecdsa_bits_to_nid(bits) == -1)
fatal("Invalid ECDSA key length - valid lengths are "
"256, 384 or 521 bits");
type_bits_valid(type, &bits);
if (!quiet)
printf("Generating public/private %s key pair.\n", key_type_name);
private = key_generate(type, bits);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keyscan.c,v 1.84 2011/01/04 20:44:13 otto Exp $ */
/* $OpenBSD: ssh-keyscan.c,v 1.85 2011/03/15 10:36:02 okan Exp $ */
/*
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
*
@ -535,7 +535,7 @@ conloop(void)
seltime.tv_sec--;
}
} else
seltime.tv_sec = seltime.tv_usec = 0;
timerclear(&seltime);
r = xcalloc(read_wait_nfdset, sizeof(fd_mask));
e = xcalloc(read_wait_nfdset, sizeof(fd_mask));
@ -620,7 +620,6 @@ main(int argc, char **argv)
extern char *optarg;
__progname = ssh_get_progname(argv[0]);
init_rng();
seed_rng();
TAILQ_INIT(&tq);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keysign.c,v 1.35 2010/08/31 12:33:38 djm Exp $ */
/* $OpenBSD: ssh-keysign.c,v 1.36 2011/02/16 00:31:14 djm Exp $ */
/*
* Copyright (c) 2002 Markus Friedl. All rights reserved.
*
@ -150,9 +150,10 @@ main(int argc, char **argv)
{
Buffer b;
Options options;
Key *keys[2], *key = NULL;
#define NUM_KEYTYPES 3
Key *keys[NUM_KEYTYPES], *key = NULL;
struct passwd *pw;
int key_fd[2], i, found, version = 2, fd;
int key_fd[NUM_KEYTYPES], i, found, version = 2, fd;
u_char *signature, *data;
char *host;
u_int slen, dlen;
@ -165,8 +166,10 @@ main(int argc, char **argv)
if (fd > 2)
close(fd);
key_fd[0] = open(_PATH_HOST_RSA_KEY_FILE, O_RDONLY);
key_fd[1] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY);
i = 0;
key_fd[i++] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY);
key_fd[i++] = open(_PATH_HOST_ECDSA_KEY_FILE, O_RDONLY);
key_fd[i++] = open(_PATH_HOST_RSA_KEY_FILE, O_RDONLY);
original_real_uid = getuid(); /* XXX readconf.c needs this */
if ((pw = getpwuid(original_real_uid)) == NULL)
@ -175,7 +178,6 @@ main(int argc, char **argv)
permanently_set_uid(pw);
init_rng();
seed_rng();
arc4random_stir();
@ -191,7 +193,11 @@ main(int argc, char **argv)
fatal("ssh-keysign not enabled in %s",
_PATH_HOST_CONFIG_FILE);
if (key_fd[0] == -1 && key_fd[1] == -1)
for (i = found = 0; i < NUM_KEYTYPES; i++) {
if (key_fd[i] != -1)
found = 1;
}
if (found == 0)
fatal("could not open any host key");
OpenSSL_add_all_algorithms();
@ -200,7 +206,7 @@ main(int argc, char **argv)
RAND_seed(rnd, sizeof(rnd));
found = 0;
for (i = 0; i < 2; i++) {
for (i = 0; i < NUM_KEYTYPES; i++) {
keys[i] = NULL;
if (key_fd[i] == -1)
continue;
@ -230,7 +236,7 @@ main(int argc, char **argv)
xfree(host);
found = 0;
for (i = 0; i < 2; i++) {
for (i = 0; i < NUM_KEYTYPES; i++) {
if (keys[i] != NULL &&
key_equal_public(key, keys[i])) {
found = 1;

View File

@ -280,7 +280,6 @@ main(int argc, char **argv)
TAILQ_INIT(&pkcs11_keylist);
pkcs11_init(0);
init_rng();
seed_rng();
__progname = ssh_get_progname(argv[0]);

View File

@ -590,4 +590,18 @@ pkcs11_add_provider(char *provider_id, char *pin, Key ***keyp)
return (-1);
}
#else
int
pkcs11_init(int interactive)
{
return (0);
}
void
pkcs11_terminate(void)
{
return;
}
#endif /* ENABLE_PKCS11 */

View File

@ -1,94 +0,0 @@
.\" $Id: ssh-rand-helper.8,v 1.3 2007/01/22 01:44:53 djm Exp $
.\"
.\" Copyright (c) 2002 Damien Miller. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd April 14, 2002
.Dt SSH-RAND-HELPER 8
.Os
.Sh NAME
.Nm ssh-rand-helper
.Nd random number gatherer for OpenSSH
.Sh SYNOPSIS
.Nm ssh-rand-hlper
.Op Fl vxXh
.Op Fl b Ar bytes
.Sh DESCRIPTION
.Nm
is a small helper program used by
.Xr ssh 1 ,
.Xr ssh-add 1 ,
.Xr ssh-agent 1 ,
.Xr ssh-keygen 1 ,
.Xr ssh-keyscan 1
and
.Xr sshd 8
to gather random numbers of cryptographic quality if the
.Xr openssl 4
library has not been configured to provide them itself.
.Pp
Normally
.Nm
will generate a strong random seed and provide it to the calling
program via standard output. If standard output is a tty,
.Nm
will instead print the seed in hexidecimal format unless told otherwise.
.Pp
.Nm
will by default gather random numbers from the system commands listed
in
.Pa /etc/ssh/ssh_prng_cmds .
The output of each of the commands listed will be hashed and used to
generate a random seed for the calling program.
.Nm
will also store seed files in
.Pa ~/.ssh/prng_seed
between executions.
.Pp
Alternately,
.Nm
may be configured at build time to collect random numbers from a
EGD/PRNGd server via a unix domain or localhost tcp socket.
.Pp
This program is not intended to be run by the end-user, so the few
commandline options are for debugging purposes only.
.Bl -tag -width Ds
.It Fl b Ar bytes
Specify the number of random bytes to include in the output.
.It Fl x
Output a hexidecimal instead of a binary seed.
.It Fl X
Force output of a binary seed, even if standard output is a tty
.It Fl v
Turn on debugging message. Multiple
.Fl v
options will increase the debugging level.
.It Fl h
Display a summary of options.
.El
.Sh AUTHORS
Damien Miller <djm@mindrot.org>
.Sh SEE ALSO
.Xr ssh 1 ,
.Xr ssh-add 1 ,
.Xr ssh-keygen 1 ,
.Xr sshd 8

View File

@ -1,932 +0,0 @@
/*
* Copyright (c) 2001-2002 Damien Miller. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <stdarg.h>
#include <stddef.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef HAVE_SYS_UN_H
# include <sys/un.h>
#endif
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <openssl/crypto.h>
/* SunOS 4.4.4 needs this */
#ifdef HAVE_FLOATINGPOINT_H
# include <floatingpoint.h>
#endif /* HAVE_FLOATINGPOINT_H */
#include "misc.h"
#include "xmalloc.h"
#include "atomicio.h"
#include "pathnames.h"
#include "log.h"
/* Number of bytes we write out */
#define OUTPUT_SEED_SIZE 48
/* Length of on-disk seedfiles */
#define SEED_FILE_SIZE 1024
/* Maximum number of command-line arguments to read from file */
#define NUM_ARGS 10
/* Minimum number of usable commands to be considered sufficient */
#define MIN_ENTROPY_SOURCES 16
/* Path to on-disk seed file (relative to user's home directory */
#ifndef SSH_PRNG_SEED_FILE
# define SSH_PRNG_SEED_FILE _PATH_SSH_USER_DIR"/prng_seed"
#endif
/* Path to PRNG commands list */
#ifndef SSH_PRNG_COMMAND_FILE
# define SSH_PRNG_COMMAND_FILE SSHDIR "/ssh_prng_cmds"
#endif
extern char *__progname;
#define WHITESPACE " \t\n"
#ifndef RUSAGE_SELF
# define RUSAGE_SELF 0
#endif
#ifndef RUSAGE_CHILDREN
# define RUSAGE_CHILDREN 0
#endif
#if !defined(PRNGD_SOCKET) && !defined(PRNGD_PORT)
# define USE_SEED_FILES
#endif
typedef struct {
/* Proportion of data that is entropy */
double rate;
/* Counter goes positive if this command times out */
unsigned int badness;
/* Increases by factor of two each timeout */
unsigned int sticky_badness;
/* Path to executable */
char *path;
/* argv to pass to executable */
char *args[NUM_ARGS]; /* XXX: arbitrary limit */
/* full command string (debug) */
char *cmdstring;
} entropy_cmd_t;
/* slow command timeouts (all in milliseconds) */
/* static int entropy_timeout_default = ENTROPY_TIMEOUT_MSEC; */
static int entropy_timeout_current = ENTROPY_TIMEOUT_MSEC;
/* this is initialised from a file, by prng_read_commands() */
static entropy_cmd_t *entropy_cmds = NULL;
/* Prototypes */
double stir_from_system(void);
double stir_from_programs(void);
double stir_gettimeofday(double entropy_estimate);
double stir_clock(double entropy_estimate);
double stir_rusage(int who, double entropy_estimate);
double hash_command_output(entropy_cmd_t *src, unsigned char *hash);
int get_random_bytes_prngd(unsigned char *buf, int len,
unsigned short tcp_port, char *socket_path);
/*
* Collect 'len' bytes of entropy into 'buf' from PRNGD/EGD daemon
* listening either on 'tcp_port', or via Unix domain socket at *
* 'socket_path'.
* Either a non-zero tcp_port or a non-null socket_path must be
* supplied.
* Returns 0 on success, -1 on error
*/
int
get_random_bytes_prngd(unsigned char *buf, int len,
unsigned short tcp_port, char *socket_path)
{
int fd, addr_len, rval, errors;
u_char msg[2];
struct sockaddr_storage addr;
struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr;
struct sockaddr_un *addr_un = (struct sockaddr_un *)&addr;
mysig_t old_sigpipe;
/* Sanity checks */
if (socket_path == NULL && tcp_port == 0)
fatal("You must specify a port or a socket");
if (socket_path != NULL &&
strlen(socket_path) >= sizeof(addr_un->sun_path))
fatal("Random pool path is too long");
if (len <= 0 || len > 255)
fatal("Too many bytes (%d) to read from PRNGD", len);
memset(&addr, '\0', sizeof(addr));
if (tcp_port != 0) {
addr_in->sin_family = AF_INET;
addr_in->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr_in->sin_port = htons(tcp_port);
addr_len = sizeof(*addr_in);
} else {
addr_un->sun_family = AF_UNIX;
strlcpy(addr_un->sun_path, socket_path,
sizeof(addr_un->sun_path));
addr_len = offsetof(struct sockaddr_un, sun_path) +
strlen(socket_path) + 1;
}
old_sigpipe = mysignal(SIGPIPE, SIG_IGN);
errors = 0;
rval = -1;
reopen:
fd = socket(addr.ss_family, SOCK_STREAM, 0);
if (fd == -1) {
error("Couldn't create socket: %s", strerror(errno));
goto done;
}
if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) {
if (tcp_port != 0) {
error("Couldn't connect to PRNGD port %d: %s",
tcp_port, strerror(errno));
} else {
error("Couldn't connect to PRNGD socket \"%s\": %s",
addr_un->sun_path, strerror(errno));
}
goto done;
}
/* Send blocking read request to PRNGD */
msg[0] = 0x02;
msg[1] = len;
if (atomicio(vwrite, fd, msg, sizeof(msg)) != sizeof(msg)) {
if (errno == EPIPE && errors < 10) {
close(fd);
errors++;
goto reopen;
}
error("Couldn't write to PRNGD socket: %s",
strerror(errno));
goto done;
}
if (atomicio(read, fd, buf, len) != (size_t)len) {
if (errno == EPIPE && errors < 10) {
close(fd);
errors++;
goto reopen;
}
error("Couldn't read from PRNGD socket: %s",
strerror(errno));
goto done;
}
rval = 0;
done:
mysignal(SIGPIPE, old_sigpipe);
if (fd != -1)
close(fd);
return rval;
}
static int
seed_from_prngd(unsigned char *buf, size_t bytes)
{
#ifdef PRNGD_PORT
debug("trying egd/prngd port %d", PRNGD_PORT);
if (get_random_bytes_prngd(buf, bytes, PRNGD_PORT, NULL) == 0)
return 0;
#endif
#ifdef PRNGD_SOCKET
debug("trying egd/prngd socket %s", PRNGD_SOCKET);
if (get_random_bytes_prngd(buf, bytes, 0, PRNGD_SOCKET) == 0)
return 0;
#endif
return -1;
}
double
stir_gettimeofday(double entropy_estimate)
{
struct timeval tv;
if (gettimeofday(&tv, NULL) == -1)
fatal("Couldn't gettimeofday: %s", strerror(errno));
RAND_add(&tv, sizeof(tv), entropy_estimate);
return entropy_estimate;
}
double
stir_clock(double entropy_estimate)
{
#ifdef HAVE_CLOCK
clock_t c;
c = clock();
RAND_add(&c, sizeof(c), entropy_estimate);
return entropy_estimate;
#else /* _HAVE_CLOCK */
return 0;
#endif /* _HAVE_CLOCK */
}
double
stir_rusage(int who, double entropy_estimate)
{
#ifdef HAVE_GETRUSAGE
struct rusage ru;
if (getrusage(who, &ru) == -1)
return 0;
RAND_add(&ru, sizeof(ru), entropy_estimate);
return entropy_estimate;
#else /* _HAVE_GETRUSAGE */
return 0;
#endif /* _HAVE_GETRUSAGE */
}
static int
timeval_diff(struct timeval *t1, struct timeval *t2)
{
int secdiff, usecdiff;
secdiff = t2->tv_sec - t1->tv_sec;
usecdiff = (secdiff*1000000) + (t2->tv_usec - t1->tv_usec);
return (int)(usecdiff / 1000);
}
double
hash_command_output(entropy_cmd_t *src, unsigned char *hash)
{
char buf[8192];
fd_set rdset;
int bytes_read, cmd_eof, error_abort, msec_elapsed, p[2];
int status, total_bytes_read;
static int devnull = -1;
pid_t pid;
SHA_CTX sha;
struct timeval tv_start, tv_current;
debug3("Reading output from \'%s\'", src->cmdstring);
if (devnull == -1) {
devnull = open("/dev/null", O_RDWR);
if (devnull == -1)
fatal("Couldn't open /dev/null: %s",
strerror(errno));
}
if (pipe(p) == -1)
fatal("Couldn't open pipe: %s", strerror(errno));
(void)gettimeofday(&tv_start, NULL); /* record start time */
switch (pid = fork()) {
case -1: /* Error */
close(p[0]);
close(p[1]);
fatal("Couldn't fork: %s", strerror(errno));
/* NOTREACHED */
case 0: /* Child */
dup2(devnull, STDIN_FILENO);
dup2(p[1], STDOUT_FILENO);
dup2(p[1], STDERR_FILENO);
close(p[0]);
close(p[1]);
close(devnull);
execv(src->path, (char**)(src->args));
debug("(child) Couldn't exec '%s': %s",
src->cmdstring, strerror(errno));
_exit(-1);
default: /* Parent */
break;
}
RAND_add(&pid, sizeof(&pid), 0.0);
close(p[1]);
/* Hash output from child */
SHA1_Init(&sha);
cmd_eof = error_abort = msec_elapsed = total_bytes_read = 0;
while (!error_abort && !cmd_eof) {
int ret;
struct timeval tv;
int msec_remaining;
(void) gettimeofday(&tv_current, 0);
msec_elapsed = timeval_diff(&tv_start, &tv_current);
if (msec_elapsed >= entropy_timeout_current) {
error_abort=1;
continue;
}
msec_remaining = entropy_timeout_current - msec_elapsed;
FD_ZERO(&rdset);
FD_SET(p[0], &rdset);
tv.tv_sec = msec_remaining / 1000;
tv.tv_usec = (msec_remaining % 1000) * 1000;
ret = select(p[0] + 1, &rdset, NULL, NULL, &tv);
RAND_add(&tv, sizeof(tv), 0.0);
switch (ret) {
case 0:
/* timer expired */
error_abort = 1;
kill(pid, SIGINT);
break;
case 1:
/* command input */
do {
bytes_read = read(p[0], buf, sizeof(buf));
} while (bytes_read == -1 && errno == EINTR);
RAND_add(&bytes_read, sizeof(&bytes_read), 0.0);
if (bytes_read == -1) {
error_abort = 1;
break;
} else if (bytes_read) {
SHA1_Update(&sha, buf, bytes_read);
total_bytes_read += bytes_read;
} else {
cmd_eof = 1;
}
break;
case -1:
default:
/* error */
debug("Command '%s': select() failed: %s",
src->cmdstring, strerror(errno));
error_abort = 1;
break;
}
}
SHA1_Final(hash, &sha);
close(p[0]);
debug3("Time elapsed: %d msec", msec_elapsed);
if (waitpid(pid, &status, 0) == -1) {
error("Couldn't wait for child '%s' completion: %s",
src->cmdstring, strerror(errno));
return 0.0;
}
RAND_add(&status, sizeof(&status), 0.0);
if (error_abort) {
/*
* Closing p[0] on timeout causes the entropy command to
* SIGPIPE. Take whatever output we got, and mark this
* command as slow
*/
debug2("Command '%s' timed out", src->cmdstring);
src->sticky_badness *= 2;
src->badness = src->sticky_badness;
return total_bytes_read;
}
if (WIFEXITED(status)) {
if (WEXITSTATUS(status) == 0) {
return total_bytes_read;
} else {
debug2("Command '%s' exit status was %d",
src->cmdstring, WEXITSTATUS(status));
src->badness = src->sticky_badness = 128;
return 0.0;
}
} else if (WIFSIGNALED(status)) {
debug2("Command '%s' returned on uncaught signal %d !",
src->cmdstring, status);
src->badness = src->sticky_badness = 128;
return 0.0;
} else
return 0.0;
}
double
stir_from_system(void)
{
double total_entropy_estimate;
long int i;
total_entropy_estimate = 0;
i = getpid();
RAND_add(&i, sizeof(i), 0.5);
total_entropy_estimate += 0.1;
i = getppid();
RAND_add(&i, sizeof(i), 0.5);
total_entropy_estimate += 0.1;
i = getuid();
RAND_add(&i, sizeof(i), 0.0);
i = getgid();
RAND_add(&i, sizeof(i), 0.0);
total_entropy_estimate += stir_gettimeofday(1.0);
total_entropy_estimate += stir_clock(0.5);
total_entropy_estimate += stir_rusage(RUSAGE_SELF, 2.0);
return total_entropy_estimate;
}
double
stir_from_programs(void)
{
int c;
double entropy, total_entropy;
unsigned char hash[SHA_DIGEST_LENGTH];
total_entropy = 0;
for(c = 0; entropy_cmds[c].path != NULL; c++) {
if (!entropy_cmds[c].badness) {
/* Hash output from command */
entropy = hash_command_output(&entropy_cmds[c],
hash);
/* Scale back estimate by command's rate */
entropy *= entropy_cmds[c].rate;
/* Upper bound of entropy is SHA_DIGEST_LENGTH */
if (entropy > SHA_DIGEST_LENGTH)
entropy = SHA_DIGEST_LENGTH;
/* Stir it in */
RAND_add(hash, sizeof(hash), entropy);
debug3("Got %0.2f bytes of entropy from '%s'",
entropy, entropy_cmds[c].cmdstring);
total_entropy += entropy;
/* Execution time should be a bit unpredictable */
total_entropy += stir_gettimeofday(0.05);
total_entropy += stir_clock(0.05);
total_entropy += stir_rusage(RUSAGE_SELF, 0.1);
total_entropy += stir_rusage(RUSAGE_CHILDREN, 0.1);
} else {
debug2("Command '%s' disabled (badness %d)",
entropy_cmds[c].cmdstring,
entropy_cmds[c].badness);
if (entropy_cmds[c].badness > 0)
entropy_cmds[c].badness--;
}
}
return total_entropy;
}
/*
* prng seedfile functions
*/
int
prng_check_seedfile(char *filename)
{
struct stat st;
/*
* XXX raceable: eg replace seed between this stat and subsequent
* open. Not such a problem because we don't really trust the
* seed file anyway.
* XXX: use secure path checking as elsewhere in OpenSSH
*/
if (lstat(filename, &st) == -1) {
/* Give up on hard errors */
if (errno != ENOENT)
debug("WARNING: Couldn't stat random seed file "
"\"%.100s\": %s", filename, strerror(errno));
return 0;
}
/* regular file? */
if (!S_ISREG(st.st_mode))
fatal("PRNG seedfile %.100s is not a regular file",
filename);
/* mode 0600, owned by root or the current user? */
if (((st.st_mode & 0177) != 0) || !(st.st_uid == getuid())) {
debug("WARNING: PRNG seedfile %.100s must be mode 0600, "
"owned by uid %li", filename, (long int)getuid());
return 0;
}
return 1;
}
void
prng_write_seedfile(void)
{
int fd, save_errno;
unsigned char seed[SEED_FILE_SIZE];
char filename[MAXPATHLEN], tmpseed[MAXPATHLEN];
struct passwd *pw;
mode_t old_umask;
pw = getpwuid(getuid());
if (pw == NULL)
fatal("Couldn't get password entry for current user "
"(%li): %s", (long int)getuid(), strerror(errno));
/* Try to ensure that the parent directory is there */
snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
_PATH_SSH_USER_DIR);
if (mkdir(filename, 0700) < 0 && errno != EEXIST)
fatal("mkdir %.200s: %s", filename, strerror(errno));
snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
SSH_PRNG_SEED_FILE);
strlcpy(tmpseed, filename, sizeof(tmpseed));
if (strlcat(tmpseed, ".XXXXXXXXXX", sizeof(tmpseed)) >=
sizeof(tmpseed))
fatal("PRNG seed filename too long");
if (RAND_bytes(seed, sizeof(seed)) <= 0)
fatal("PRNG seed extraction failed");
/* Don't care if the seed doesn't exist */
prng_check_seedfile(filename);
old_umask = umask(0177);
if ((fd = mkstemp(tmpseed)) == -1) {
debug("WARNING: couldn't make temporary PRNG seedfile %.100s "
"(%.100s)", tmpseed, strerror(errno));
} else {
debug("writing PRNG seed to file %.100s", tmpseed);
if (atomicio(vwrite, fd, &seed, sizeof(seed)) < sizeof(seed)) {
save_errno = errno;
close(fd);
unlink(tmpseed);
fatal("problem writing PRNG seedfile %.100s "
"(%.100s)", filename, strerror(save_errno));
}
close(fd);
debug("moving temporary PRNG seed to file %.100s", filename);
if (rename(tmpseed, filename) == -1) {
save_errno = errno;
unlink(tmpseed);
fatal("problem renaming PRNG seedfile from %.100s "
"to %.100s (%.100s)", tmpseed, filename,
strerror(save_errno));
}
}
umask(old_umask);
}
void
prng_read_seedfile(void)
{
int fd;
char seed[SEED_FILE_SIZE], filename[MAXPATHLEN];
struct passwd *pw;
pw = getpwuid(getuid());
if (pw == NULL)
fatal("Couldn't get password entry for current user "
"(%li): %s", (long int)getuid(), strerror(errno));
snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
SSH_PRNG_SEED_FILE);
debug("loading PRNG seed from file %.100s", filename);
if (!prng_check_seedfile(filename)) {
verbose("Random seed file not found or invalid, ignoring.");
return;
}
/* open the file and read in the seed */
fd = open(filename, O_RDONLY);
if (fd == -1)
fatal("could not open PRNG seedfile %.100s (%.100s)",
filename, strerror(errno));
if (atomicio(read, fd, &seed, sizeof(seed)) < sizeof(seed)) {
verbose("invalid or short read from PRNG seedfile "
"%.100s - ignoring", filename);
memset(seed, '\0', sizeof(seed));
}
close(fd);
/* stir in the seed, with estimated entropy zero */
RAND_add(&seed, sizeof(seed), 0.0);
}
/*
* entropy command initialisation functions
*/
int
prng_read_commands(char *cmdfilename)
{
char cmd[SEED_FILE_SIZE], *cp, line[1024], path[SEED_FILE_SIZE];
double est;
entropy_cmd_t *entcmd;
FILE *f;
int cur_cmd, linenum, num_cmds, arg;
if ((f = fopen(cmdfilename, "r")) == NULL) {
fatal("couldn't read entropy commands file %.100s: %.100s",
cmdfilename, strerror(errno));
}
num_cmds = 64;
entcmd = xcalloc(num_cmds, sizeof(entropy_cmd_t));
/* Read in file */
cur_cmd = linenum = 0;
while (fgets(line, sizeof(line), f)) {
linenum++;
/* Skip leading whitespace, blank lines and comments */
cp = line + strspn(line, WHITESPACE);
if ((*cp == 0) || (*cp == '#'))
continue; /* done with this line */
/*
* The first non-whitespace char should be a double quote
* delimiting the commandline
*/
if (*cp != '"') {
error("bad entropy command, %.100s line %d",
cmdfilename, linenum);
continue;
}
/*
* First token, command args (incl. argv[0]) in double
* quotes
*/
cp = strtok(cp, "\"");
if (cp == NULL) {
error("missing or bad command string, %.100s "
"line %d -- ignored", cmdfilename, linenum);
continue;
}
strlcpy(cmd, cp, sizeof(cmd));
/* Second token, full command path */
if ((cp = strtok(NULL, WHITESPACE)) == NULL) {
error("missing command path, %.100s "
"line %d -- ignored", cmdfilename, linenum);
continue;
}
/* Did configure mark this as dead? */
if (strncmp("undef", cp, 5) == 0)
continue;
strlcpy(path, cp, sizeof(path));
/* Third token, entropy rate estimate for this command */
if ((cp = strtok(NULL, WHITESPACE)) == NULL) {
error("missing entropy estimate, %.100s "
"line %d -- ignored", cmdfilename, linenum);
continue;
}
est = strtod(cp, NULL);
/* end of line */
if ((cp = strtok(NULL, WHITESPACE)) != NULL) {
error("garbage at end of line %d in %.100s "
"-- ignored", linenum, cmdfilename);
continue;
}
/* save the command for debug messages */
entcmd[cur_cmd].cmdstring = xstrdup(cmd);
/* split the command args */
cp = strtok(cmd, WHITESPACE);
arg = 0;
do {
entcmd[cur_cmd].args[arg] = xstrdup(cp);
arg++;
} while(arg < NUM_ARGS && (cp = strtok(NULL, WHITESPACE)));
if (strtok(NULL, WHITESPACE))
error("ignored extra commands (max %d), %.100s "
"line %d", NUM_ARGS, cmdfilename, linenum);
/* Copy the command path and rate estimate */
entcmd[cur_cmd].path = xstrdup(path);
entcmd[cur_cmd].rate = est;
/* Initialise other values */
entcmd[cur_cmd].sticky_badness = 1;
cur_cmd++;
/*
* If we've filled the array, reallocate it twice the size
* Do this now because even if this we're on the last
* command we need another slot to mark the last entry
*/
if (cur_cmd == num_cmds) {
num_cmds *= 2;
entcmd = xrealloc(entcmd, num_cmds,
sizeof(entropy_cmd_t));
}
}
/* zero the last entry */
memset(&entcmd[cur_cmd], '\0', sizeof(entropy_cmd_t));
/* trim to size */
entropy_cmds = xrealloc(entcmd, (cur_cmd + 1),
sizeof(entropy_cmd_t));
debug("Loaded %d entropy commands from %.100s", cur_cmd,
cmdfilename);
fclose(f);
return cur_cmd < MIN_ENTROPY_SOURCES ? -1 : 0;
}
void
usage(void)
{
fprintf(stderr, "Usage: %s [options]\n", __progname);
fprintf(stderr, " -v Verbose; display verbose debugging messages.\n");
fprintf(stderr, " Multiple -v increases verbosity.\n");
fprintf(stderr, " -x Force output in hexadecimal (for debugging)\n");
fprintf(stderr, " -X Force output in binary\n");
fprintf(stderr, " -b bytes Number of bytes to output (default %d)\n",
OUTPUT_SEED_SIZE);
}
int
main(int argc, char **argv)
{
unsigned char *buf;
int ret, ch, debug_level, output_hex, bytes;
extern char *optarg;
extern int optind;
LogLevel ll;
__progname = ssh_get_progname(argv[0]);
log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
ll = SYSLOG_LEVEL_INFO;
debug_level = output_hex = 0;
bytes = OUTPUT_SEED_SIZE;
/* Don't write binary data to a tty, unless we are forced to */
if (isatty(STDOUT_FILENO))
output_hex = 1;
while ((ch = getopt(argc, argv, "vxXhb:")) != -1) {
switch (ch) {
case 'v':
if (debug_level < 3)
ll = SYSLOG_LEVEL_DEBUG1 + debug_level++;
break;
case 'x':
output_hex = 1;
break;
case 'X':
output_hex = 0;
break;
case 'b':
if ((bytes = atoi(optarg)) <= 0)
fatal("Invalid number of output bytes");
break;
case 'h':
usage();
exit(0);
default:
error("Invalid commandline option");
usage();
exit(1);
}
}
log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
if (argc != optind) {
error("Unexpected commandline arguments.");
usage();
exit(1);
}
#ifdef USE_SEED_FILES
prng_read_seedfile();
#endif
buf = xmalloc(bytes);
/*
* Seed the RNG from wherever we can
*/
/* Take whatever is on the stack, but don't credit it */
RAND_add(buf, bytes, 0);
debug("Seeded RNG with %i bytes from system calls",
(int)stir_from_system());
/* try prngd, fall back to commands if prngd fails or not configured */
if (seed_from_prngd(buf, bytes) == 0) {
RAND_add(buf, bytes, bytes);
} else {
/* Read in collection commands */
if (prng_read_commands(SSH_PRNG_COMMAND_FILE) == -1)
fatal("PRNG initialisation failed -- exiting.");
debug("Seeded RNG with %i bytes from programs",
(int)stir_from_programs());
}
#ifdef USE_SEED_FILES
prng_write_seedfile();
#endif
/*
* Write the seed to stdout
*/
if (!RAND_status())
fatal("Not enough entropy in RNG");
if (RAND_bytes(buf, bytes) <= 0)
fatal("Couldn't extract entropy from PRNG");
if (output_hex) {
for(ret = 0; ret < bytes; ret++)
printf("%02x", (unsigned char)(buf[ret]));
printf("\n");
} else
ret = atomicio(vwrite, STDOUT_FILENO, buf, bytes);
memset(buf, '\0', bytes);
xfree(buf);
return ret == bytes ? 0 : 1;
}
/*
* We may attempt to re-seed during mkstemp if we are using the one in the
* compat library (via mkstemp -> _gettemp -> arc4random -> seed_rng) so we
* need our own seed_rng(). We must also check that we have enough entropy.
*/
void
seed_rng(void)
{
if (!RAND_status())
fatal("Not enough entropy in RNG");
}

View File

@ -0,0 +1,23 @@
/* $OpenBSD: ssh-sandbox.h,v 1.1 2011/06/23 09:34:13 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
struct ssh_sandbox;
struct ssh_sandbox *ssh_sandbox_init(void);
void ssh_sandbox_child(struct ssh_sandbox *);
void ssh_sandbox_parent_finish(struct ssh_sandbox *);
void ssh_sandbox_parent_preauth(struct ssh_sandbox *, pid_t);

View File

@ -33,9 +33,9 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: ssh.1,v 1.316 2010/11/18 15:01:00 jmc Exp $
.\" $OpenBSD: ssh.1,v 1.320 2011/08/02 01:22:11 djm Exp $
.\" $FreeBSD$
.Dd November 18, 2010
.Dd August 2, 2011
.Dt SSH 1
.Os
.Sh NAME
@ -393,9 +393,11 @@ Valid commands are:
.Dq check
(check that the master process is running),
.Dq forward
(request forwardings without command execution) and
(request forwardings without command execution),
.Dq exit
(request the master to exit).
(request the master to exit), and
.Dq stop
(request the master to stop accepting further multiplexing requests).
.It Fl o Ar option
Can be used to give options in the format used in the configuration file.
This is useful for specifying options for which there is no separate
@ -455,6 +457,7 @@ For full details of the options listed below, and their possible values, see
.It PubkeyAuthentication
.It RekeyLimit
.It RemoteForward
.It RequestTTY
.It RhostsRSAAuthentication
.It RSAAuthentication
.It SendEnv
@ -666,7 +669,9 @@ Both protocols support similar authentication methods,
but protocol 2 is the default since
it provides additional mechanisms for confidentiality
(the traffic is encrypted using AES, 3DES, Blowfish, CAST128, or Arcfour)
and integrity (hmac-md5, hmac-sha1, umac-64, hmac-ripemd160).
and integrity (hmac-md5, hmac-sha1,
hmac-sha2-256, hmac-sha2-512,
umac-64, hmac-ripemd160).
Protocol 1 lacks a strong mechanism for ensuring the
integrity of the connection.
.Pp

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh.c,v 1.356 2011/01/06 22:23:53 djm Exp $ */
/* $OpenBSD: ssh.c,v 1.364 2011/08/02 23:15:03 djm Exp $ */
/* $FreeBSD$ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -113,13 +113,16 @@ __RCSID("$FreeBSD$");
extern char *__progname;
/* Saves a copy of argv for setproctitle emulation */
#ifndef HAVE_SETPROCTITLE
static char **saved_av;
#endif
/* Flag indicating whether debug mode is on. May be set on the command line. */
int debug_flag = 0;
/* Flag indicating whether a tty should be allocated */
/* Flag indicating whether a tty should be requested */
int tty_flag = 0;
int no_tty_flag = 0;
int force_tty_flag = 0;
/* don't exec a shell */
int no_shell_flag = 0;
@ -137,7 +140,7 @@ int stdin_null_flag = 0;
int need_controlpersist_detach = 0;
/* Copies of flags for ControlPersist foreground slave */
int ostdin_null_flag, ono_shell_flag, ono_tty_flag, otty_flag;
int ostdin_null_flag, ono_shell_flag, otty_flag, orequest_tty;
/*
* Flag indicating that ssh should fork after authentication. This is useful
@ -216,6 +219,20 @@ static void main_sigchld_handler(int);
void muxclient(const char *);
void muxserver_listen(void);
/* ~/ expand a list of paths. NB. assumes path[n] is heap-allocated. */
static void
tilde_expand_paths(char **paths, u_int num_paths)
{
u_int i;
char *cp;
for (i = 0; i < num_paths; i++) {
cp = tilde_expand_filename(paths[i], original_real_uid);
xfree(paths[i]);
paths[i] = cp;
}
}
/*
* Main program for the ssh client.
*/
@ -224,11 +241,13 @@ main(int ac, char **av)
{
int i, r, opt, exit_status, use_syslog;
char *p, *cp, *line, *argv0, buf[MAXPATHLEN], *host_arg;
char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
struct stat st;
struct passwd *pw;
int dummy, timeout_ms;
extern int optind, optreset;
extern char *optarg;
struct servent *sp;
Forward fwd;
@ -236,7 +255,17 @@ main(int ac, char **av)
sanitise_stdfd();
__progname = ssh_get_progname(av[0]);
init_rng();
#ifndef HAVE_SETPROCTITLE
/* Prepare for later setproctitle emulation */
/* Save argv so it isn't clobbered by setproctitle() emulation */
saved_av = xcalloc(ac + 1, sizeof(*saved_av));
for (i = 0; i < ac; i++)
saved_av[i] = xstrdup(av[i]);
saved_av[i] = NULL;
compat_init_setproctitle(ac, av);
av = saved_av;
#endif
/*
* Discard other fds that are hanging around. These can cause problem
@ -348,6 +377,8 @@ main(int ac, char **av)
muxclient_command = SSHMUX_COMMAND_FORWARD;
else if (strcmp(optarg, "exit") == 0)
muxclient_command = SSHMUX_COMMAND_TERMINATE;
else if (strcmp(optarg, "stop") == 0)
muxclient_command = SSHMUX_COMMAND_STOP;
else
fatal("Invalid multiplex command.");
break;
@ -389,9 +420,10 @@ main(int ac, char **av)
#endif
break;
case 't':
if (tty_flag)
force_tty_flag = 1;
tty_flag = 1;
if (options.request_tty == REQUEST_TTY_YES)
options.request_tty = REQUEST_TTY_FORCE;
else
options.request_tty = REQUEST_TTY_YES;
break;
case 'v':
if (debug_flag == 0) {
@ -434,7 +466,7 @@ main(int ac, char **av)
optarg);
exit(255);
}
no_tty_flag = 1;
options.request_tty = REQUEST_TTY_NO;
no_shell_flag = 1;
options.clear_forwardings = 1;
options.exit_on_forward_failure = 1;
@ -543,10 +575,10 @@ main(int ac, char **av)
break;
case 'N':
no_shell_flag = 1;
no_tty_flag = 1;
options.request_tty = REQUEST_TTY_NO;
break;
case 'T':
no_tty_flag = 1;
options.request_tty = REQUEST_TTY_NO;
#ifdef NONE_CIPHER_ENABLED
/*
* Ensure that the user does not try to backdoor a
@ -615,6 +647,10 @@ main(int ac, char **av)
/* Initialize the command to execute on remote host. */
buffer_init(&command);
if (options.request_tty == REQUEST_TTY_YES ||
options.request_tty == REQUEST_TTY_FORCE)
tty_flag = 1;
/*
* Save the command to execute on the remote host in a buffer. There
* is no limit on the length of the command, except by the maximum
@ -622,7 +658,7 @@ main(int ac, char **av)
*/
if (!ac) {
/* No command specified - execute shell on a tty. */
tty_flag = 1;
tty_flag = options.request_tty != REQUEST_TTY_NO;
if (subsystem_flag) {
fprintf(stderr,
"You must specify a subsystem to invoke.\n");
@ -645,13 +681,14 @@ main(int ac, char **av)
/* Allocate a tty by default if no command specified. */
if (buffer_len(&command) == 0)
tty_flag = 1;
tty_flag = options.request_tty != REQUEST_TTY_NO;
/* Force no tty */
if (no_tty_flag || muxclient_command != 0)
if (options.request_tty == REQUEST_TTY_NO || muxclient_command != 0)
tty_flag = 0;
/* Do not allocate a tty if stdin is not a tty. */
if ((!isatty(fileno(stdin)) || stdin_null_flag) && !force_tty_flag) {
if ((!isatty(fileno(stdin)) || stdin_null_flag) &&
options.request_tty != REQUEST_TTY_FORCE) {
if (tty_flag)
logit("Pseudo-terminal will not be allocated because "
"stdin is not a terminal.");
@ -680,7 +717,7 @@ main(int ac, char **av)
if (r > 0 && (size_t)r < sizeof(buf))
(void)read_config_file(buf, host, &options, 1);
/* Read systemwide configuration file after use config. */
/* Read systemwide configuration file after user config. */
(void)read_config_file(_PATH_HOST_CONFIG_FILE, host,
&options, 0);
}
@ -711,17 +748,19 @@ main(int ac, char **av)
"h", host, (char *)NULL);
}
if (options.local_command != NULL) {
char thishost[NI_MAXHOST];
if (gethostname(thishost, sizeof(thishost)) == -1)
fatal("gethostname: %s", strerror(errno));
strlcpy(shorthost, thishost, sizeof(shorthost));
shorthost[strcspn(thishost, ".")] = '\0';
snprintf(portstr, sizeof(portstr), "%d", options.port);
if (gethostname(thishost, sizeof(thishost)) == -1)
fatal("gethostname: %s", strerror(errno));
snprintf(buf, sizeof(buf), "%d", options.port);
if (options.local_command != NULL) {
debug3("expanding LocalCommand: %s", options.local_command);
cp = options.local_command;
options.local_command = percent_expand(cp, "d", pw->pw_dir,
"h", host, "l", thishost, "n", host_arg, "r", options.user,
"p", buf, "u", pw->pw_name, (char *)NULL);
"p", portstr, "u", pw->pw_name, "L", shorthost,
(char *)NULL);
debug3("expanded LocalCommand: %s", options.local_command);
xfree(cp);
}
@ -762,16 +801,13 @@ main(int ac, char **av)
}
if (options.control_path != NULL) {
char thishost[NI_MAXHOST];
if (gethostname(thishost, sizeof(thishost)) == -1)
fatal("gethostname: %s", strerror(errno));
snprintf(buf, sizeof(buf), "%d", options.port);
cp = tilde_expand_filename(options.control_path,
original_real_uid);
xfree(options.control_path);
options.control_path = percent_expand(cp, "p", buf, "h", host,
"r", options.user, "l", thishost, (char *)NULL);
options.control_path = percent_expand(cp, "h", host,
"l", thishost, "n", host_arg, "r", options.user,
"p", portstr, "u", pw->pw_name, "L", shorthost,
(char *)NULL);
xfree(cp);
}
if (muxclient_command != 0 && options.control_path == NULL)
@ -892,15 +928,9 @@ main(int ac, char **av)
load_public_identity_files();
/* Expand ~ in known host file names. */
/* XXX mem-leaks: */
options.system_hostfile =
tilde_expand_filename(options.system_hostfile, original_real_uid);
options.user_hostfile =
tilde_expand_filename(options.user_hostfile, original_real_uid);
options.system_hostfile2 =
tilde_expand_filename(options.system_hostfile2, original_real_uid);
options.user_hostfile2 =
tilde_expand_filename(options.user_hostfile2, original_real_uid);
tilde_expand_paths(options.system_hostfiles,
options.num_system_hostfiles);
tilde_expand_paths(options.user_hostfiles, options.num_user_hostfiles);
signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
signal(SIGCHLD, main_sigchld_handler);
@ -973,8 +1003,7 @@ control_persist_detach(void)
/* Parent: set up mux slave to connect to backgrounded master */
debug2("%s: background process is %ld", __func__, (long)pid);
stdin_null_flag = ostdin_null_flag;
no_shell_flag = ono_shell_flag;
no_tty_flag = ono_tty_flag;
options.request_tty = orequest_tty;
tty_flag = otty_flag;
close(muxserver_sock);
muxserver_sock = -1;
@ -993,6 +1022,7 @@ control_persist_detach(void)
if (devnull > STDERR_FILENO)
close(devnull);
}
setproctitle("%s [mux]", options.control_path);
}
/* Do fork() after authentication. Used by "ssh -f" */
@ -1237,8 +1267,8 @@ ssh_session(void)
/* Request forwarding with authentication spoofing. */
debug("Requesting X11 forwarding with authentication "
"spoofing.");
x11_request_forwarding_with_spoofing(0, display, proto, data);
x11_request_forwarding_with_spoofing(0, display, proto,
data, 0);
/* Read response from the server. */
type = packet_read();
if (type == SSH_SMSG_SUCCESS) {
@ -1336,9 +1366,11 @@ ssh_session2_setup(int id, int success, void *arg)
/* Request forwarding with authentication spoofing. */
debug("Requesting X11 forwarding with authentication "
"spoofing.");
x11_request_forwarding_with_spoofing(id, display, proto, data);
x11_request_forwarding_with_spoofing(id, display, proto,
data, 1);
client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN);
/* XXX exit_on_forward_failure */
interactive = 1;
/* XXX wait for reply */
}
check_agent_present();
@ -1461,11 +1493,10 @@ ssh_session2(void)
if (options.control_persist && muxserver_sock != -1) {
ostdin_null_flag = stdin_null_flag;
ono_shell_flag = no_shell_flag;
ono_tty_flag = no_tty_flag;
orequest_tty = options.request_tty;
otty_flag = tty_flag;
stdin_null_flag = 1;
no_shell_flag = 1;
no_tty_flag = 1;
tty_flag = 0;
if (!fork_after_authentication_flag)
need_controlpersist_detach = 1;

View File

@ -46,4 +46,4 @@
# PermitLocalCommand no
# VisualHostKey no
# ProxyCommand ssh -q -W %h:%p gateway.example.com
# VersionAddendum FreeBSD-20110503
# VersionAddendum FreeBSD-20111001

View File

@ -33,9 +33,9 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: ssh_config.5,v 1.146 2010/12/08 04:02:47 djm Exp $
.\" $OpenBSD: ssh_config.5,v 1.153 2011/08/02 01:22:11 djm Exp $
.\" $FreeBSD$
.Dd December 8, 2010
.Dd August 2, 2011
.Dt SSH_CONFIG 5
.Os
.Sh NAME
@ -113,6 +113,15 @@ The host is the
argument given on the command line (i.e. the name is not converted to
a canonicalized host name before matching).
.Pp
A pattern entry may be negated by prefixing it with an exclamation mark
.Pq Sq !\& .
If a negated entry is matched, then the
.Cm Host
entry is ignored, regardless of whether any other patterns on the line
match.
Negated matches are therefore useful to provide exceptions for wildcard
matches.
.Pp
See
.Sx PATTERNS
for more information on patterns.
@ -306,14 +315,22 @@ section above or the string
.Dq none
to disable connection sharing.
In the path,
.Ql %L
will be substituted by the first component of the local host name,
.Ql %l
will be substituted by the local host name,
will be substituted by the local host name (including any domain name),
.Ql %h
will be substituted by the target host name,
.Ql %n
will be substituted by the original target host name
specified on the command line,
.Ql %p
the port, and
the port,
.Ql %r
by the remote login username.
by the remote login username, and
.Ql %u
by the username of the user running
.Xr ssh 1 .
It is recommended that any
.Cm ControlPath
used for opportunistic connection sharing include
@ -501,9 +518,11 @@ or
The default is
.Dq no .
.It Cm GlobalKnownHostsFile
Specifies a file to use for the global
host key database instead of
.Pa /etc/ssh/ssh_known_hosts .
Specifies one or more files to use for the global
host key database, separated by whitespace.
The default is
.Pa /etc/ssh/ssh_known_hosts ,
.Pa /etc/ssh/ssh_known_hosts2 .
.It Cm GSSAPIAuthentication
Specifies whether user authentication based on GSSAPI is allowed.
The default is
@ -570,7 +589,7 @@ Specifies the real host name to log into.
This can be used to specify nicknames or abbreviations for hosts.
If the hostname contains the character sequence
.Ql %h ,
then this will be replaced with the host name specified on the commandline
then this will be replaced with the host name specified on the command line
(this is useful for manipulating unqualified names).
The default is the name given on the command line.
Numeric IP addresses are also permitted (both on the command line and in
@ -630,6 +649,10 @@ escape characters:
It is possible to have
multiple identity files specified in configuration files; all these
identities will be tried in sequence.
Multiple
.Cm IdentityFile
directives will add to the list of identities tried (this behaviour
differs from that of other configuration directives).
.It Cm IPQoS
Specifies the IPv4 type-of-service or DSCP class for connections.
Accepted values are
@ -771,7 +794,9 @@ Multiple algorithms must be comma-separated.
The default is:
.Bd -literal -offset indent
hmac-md5,hmac-sha1,umac-64@openssh.com,
hmac-ripemd160,hmac-sha1-96,hmac-md5-96
hmac-ripemd160,hmac-sha1-96,hmac-md5-96,
hmac-sha2-256,hmac-sha2-256-96,hmac-sha2-512,
hmac-sha2-512-96
.Ed
.It Cm NoHostAuthenticationForLocalhost
This option can be used if the home directory is shared across machines.
@ -944,6 +969,23 @@ will only succeed if the server's
.Cm GatewayPorts
option is enabled (see
.Xr sshd_config 5 ) .
.It Cm RequestTTY
Specifies whether to request a pseudo-tty for the session.
The argument may be one of:
.Dq no
(never request a TTY),
.Dq yes
(always request a TTY when standard input is a TTY),
.Dq force
(always request a TTY) or
.Dq auto
(request a TTY when opening a login session).
This option mirrors the
.Fl t
and
.Fl T
flags for
.Xr ssh 1 .
.It Cm RhostsRSAAuthentication
Specifies whether to try rhosts based authentication with RSA host
authentication.
@ -1138,9 +1180,11 @@ This can be useful when a different user name is used on different machines.
This saves the trouble of
having to remember to give the user name on the command line.
.It Cm UserKnownHostsFile
Specifies a file to use for the user
host key database instead of
.Pa ~/.ssh/known_hosts .
Specifies one or more files to use for the user
host key database, separated by whitespace.
The default is
.Pa ~/.ssh/known_hosts ,
.Pa ~/.ssh/known_hosts2 .
.It Cm VerifyHostKeyDNS
Specifies whether to verify the remote key using DNS and SSHFP resource
records.
@ -1173,7 +1217,7 @@ in
Specifies a string to append to the regular version string to identify
OS- or site-specific modifications.
The default is
.Dq FreeBSD-20110503 .
.Dq FreeBSD-20111001 .
.It Cm VisualHostKey
If this flag is set to
.Dq yes ,

View File

@ -201,6 +201,7 @@
#define dispatch_run ssh_dispatch_run
#define dispatch_set ssh_dispatch_set
#define do_log ssh_do_log
#define do_log2 ssh_do_log2
#define dump_base64 ssh_dump_base64
#define enable_compat13 ssh_enable_compat13
#define enable_compat20 ssh_enable_compat20
@ -238,6 +239,7 @@
#define incoming_stream ssh_incoming_stream
#define init_hostkeys ssh_init_hostkeys
#define init_rng ssh_init_rng
#define iptos2str ssh_iptos2str
#define ipv64_normalise_mapped ssh_ipv64_normalise_mapped
#define kex_derive_keys ssh_kex_derive_keys
#define kex_dh_hash ssh_kex_dh_hash
@ -282,6 +284,7 @@
#define key_in_file ssh_key_in_file
#define key_is_cert ssh_key_is_cert
#define key_load_cert ssh_key_load_cert
#define key_load_file ssh_key_load_file
#define key_load_private ssh_key_load_private
#define key_load_private_cert ssh_key_load_private_cert
#define key_load_private_pem ssh_key_load_private_pem
@ -291,6 +294,7 @@
#define key_names_valid2 ssh_key_names_valid2
#define key_new ssh_key_new
#define key_new_private ssh_key_new_private
#define key_parse_private ssh_key_parse_private
#define key_perm_ok ssh_key_perm_ok
#define key_read ssh_key_read
#define key_save_private ssh_key_save_private
@ -435,6 +439,7 @@
#define sanitise_stdfd ssh_sanitise_stdfd
#define scan_scaled ssh_scan_scaled
#define seed_rng ssh_seed_rng
#define set_log_handler ssh_set_log_handler
#define set_newkeys ssh_set_newkeys
#define set_nodelay ssh_set_nodelay
#define set_nonblock ssh_set_nonblock

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect.c,v 1.232 2011/01/16 11:50:36 djm Exp $ */
/* $OpenBSD: sshconnect.c,v 1.234 2011/05/24 07:15:47 djm Exp $ */
/* $FreeBSD$ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -712,28 +712,30 @@ get_hostfile_hostname_ipaddr(char *hostname, struct sockaddr *hostaddr,
/*
* check whether the supplied host key is valid, return -1 if the key
* is not valid. the user_hostfile will not be updated if 'readonly' is true.
* is not valid. user_hostfile[0] will not be updated if 'readonly' is true.
*/
#define RDRW 0
#define RDONLY 1
#define ROQUIET 2
static int
check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
Key *host_key, int readonly, char *user_hostfile,
char *system_hostfile)
Key *host_key, int readonly,
char **user_hostfiles, u_int num_user_hostfiles,
char **system_hostfiles, u_int num_system_hostfiles)
{
Key *raw_key = NULL;
const char *type;
char *ip = NULL, *host = NULL;
char hostline[1000], *hostp, *fp, *ra;
HostStatus host_status;
HostStatus ip_status;
int r, want_cert = key_is_cert(host_key), host_ip_differ = 0;
int local = sockaddr_is_local(hostaddr);
Key *raw_key = NULL;
char *ip = NULL, *host = NULL;
char hostline[1000], *hostp, *fp, *ra;
char msg[1024];
int len, cancelled_forwarding = 0;
struct hostkeys *host_hostkeys, *ip_hostkeys;
const char *type;
const struct hostkey_entry *host_found, *ip_found;
int len, cancelled_forwarding = 0;
int local = sockaddr_is_local(hostaddr);
int r, want_cert = key_is_cert(host_key), host_ip_differ = 0;
struct hostkeys *host_hostkeys, *ip_hostkeys;
u_int i;
/*
* Force accepting of the host key for loopback/localhost. The
@ -765,14 +767,18 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
options.check_host_ip = 0;
host_hostkeys = init_hostkeys();
load_hostkeys(host_hostkeys, host, user_hostfile);
load_hostkeys(host_hostkeys, host, system_hostfile);
for (i = 0; i < num_user_hostfiles; i++)
load_hostkeys(host_hostkeys, host, user_hostfiles[i]);
for (i = 0; i < num_system_hostfiles; i++)
load_hostkeys(host_hostkeys, host, system_hostfiles[i]);
ip_hostkeys = NULL;
if (!want_cert && options.check_host_ip) {
ip_hostkeys = init_hostkeys();
load_hostkeys(ip_hostkeys, ip, user_hostfile);
load_hostkeys(ip_hostkeys, ip, system_hostfile);
for (i = 0; i < num_user_hostfiles; i++)
load_hostkeys(ip_hostkeys, ip, user_hostfiles[i]);
for (i = 0; i < num_system_hostfiles; i++)
load_hostkeys(ip_hostkeys, ip, system_hostfiles[i]);
}
retry:
@ -817,11 +823,12 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
logit("%s host key for IP address "
"'%.128s' not in list of known hosts.",
type, ip);
else if (!add_host_to_hostfile(user_hostfile, ip,
else if (!add_host_to_hostfile(user_hostfiles[0], ip,
host_key, options.hash_known_hosts))
logit("Failed to add the %s host key for IP "
"address '%.128s' to the list of known "
"hosts (%.30s).", type, ip, user_hostfile);
"hosts (%.30s).", type, ip,
user_hostfiles[0]);
else
logit("Warning: Permanently added the %s host "
"key for IP address '%.128s' to the list "
@ -840,7 +847,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
port != SSH_DEFAULT_PORT) {
debug("checking without port identifier");
if (check_host_key(hostname, hostaddr, 0, host_key,
ROQUIET, user_hostfile, system_hostfile) == 0) {
ROQUIET, user_hostfiles, num_user_hostfiles,
system_hostfiles, num_system_hostfiles) == 0) {
debug("found matching key w/out port");
break;
}
@ -905,25 +913,25 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
hostp = hostline;
if (options.hash_known_hosts) {
/* Add hash of host and IP separately */
r = add_host_to_hostfile(user_hostfile, host,
host_key, options.hash_known_hosts) &&
add_host_to_hostfile(user_hostfile, ip,
r = add_host_to_hostfile(user_hostfiles[0],
host, host_key, options.hash_known_hosts) &&
add_host_to_hostfile(user_hostfiles[0], ip,
host_key, options.hash_known_hosts);
} else {
/* Add unhashed "host,ip" */
r = add_host_to_hostfile(user_hostfile,
r = add_host_to_hostfile(user_hostfiles[0],
hostline, host_key,
options.hash_known_hosts);
}
} else {
r = add_host_to_hostfile(user_hostfile, host, host_key,
options.hash_known_hosts);
r = add_host_to_hostfile(user_hostfiles[0], host,
host_key, options.hash_known_hosts);
hostp = host;
}
if (!r)
logit("Failed to add the host to the list of known "
"hosts (%.500s).", user_hostfile);
"hosts (%.500s).", user_hostfiles[0]);
else
logit("Warning: Permanently added '%.200s' (%s) to the "
"list of known hosts.", hostp, type);
@ -984,7 +992,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
/* The host key has changed. */
warn_changed_key(host_key);
error("Add correct host key in %.100s to get rid of this message.",
user_hostfile);
user_hostfiles[0]);
error("Offending %s key in %s:%lu", key_type(host_found->key),
host_found->file, host_found->line);
@ -1129,7 +1137,6 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
int
verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
{
struct stat st;
int flags = 0;
char *fp;
@ -1140,7 +1147,6 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
/* XXX certs are not yet supported for DNS */
if (!key_is_cert(host_key) && options.verify_host_key_dns &&
verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) {
if (flags & DNS_VERIFY_FOUND) {
if (options.verify_host_key_dns == 1 &&
@ -1158,16 +1164,9 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
}
}
/* return ok if the key can be found in an old keyfile */
if (stat(options.system_hostfile2, &st) == 0 ||
stat(options.user_hostfile2, &st) == 0) {
if (check_host_key(host, hostaddr, options.port, host_key,
RDONLY, options.user_hostfile2,
options.system_hostfile2) == 0)
return 0;
}
return check_host_key(host, hostaddr, options.port, host_key,
RDRW, options.user_hostfile, options.system_hostfile);
return check_host_key(host, hostaddr, options.port, host_key, RDRW,
options.user_hostfiles, options.num_user_hostfiles,
options.system_hostfiles, options.num_system_hostfiles);
}
/*

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect2.c,v 1.186 2010/11/29 23:45:51 djm Exp $ */
/* $OpenBSD: sshconnect2.c,v 1.188 2011/05/24 07:15:47 djm Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -120,14 +120,15 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port)
size_t maxlen;
struct hostkeys *hostkeys;
int ktype;
u_int i;
/* Find all hostkeys for this hostname */
get_hostfile_hostname_ipaddr(host, hostaddr, port, &hostname, NULL);
hostkeys = init_hostkeys();
load_hostkeys(hostkeys, hostname, options.user_hostfile2);
load_hostkeys(hostkeys, hostname, options.system_hostfile2);
load_hostkeys(hostkeys, hostname, options.user_hostfile);
load_hostkeys(hostkeys, hostname, options.system_hostfile);
for (i = 0; i < options.num_user_hostfiles; i++)
load_hostkeys(hostkeys, hostname, options.user_hostfiles[i]);
for (i = 0; i < options.num_system_hostfiles; i++)
load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]);
oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG);
maxlen = strlen(avail) + 1;
@ -1922,9 +1923,12 @@ authmethod_get(char *authlist)
authmethod_is_enabled(current)) {
debug3("authmethod_is_enabled %s", name);
debug("Next authentication method: %s", name);
xfree(name);
return current;
}
}
if (name != NULL)
xfree(name);
}
static char *

View File

@ -33,9 +33,9 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: sshd.8,v 1.260 2010/10/28 18:33:28 jmc Exp $
.\" $OpenBSD: sshd.8,v 1.263 2011/08/02 01:22:11 djm Exp $
.\" $FreeBSD$
.Dd October 28, 2010
.Dd August 2, 2011
.Dt SSHD 8
.Os
.Sh NAME
@ -315,7 +315,8 @@ The client selects the encryption algorithm
to use from those offered by the server.
Additionally, session integrity is provided
through a cryptographic message authentication code
(hmac-md5, hmac-sha1, umac-64 or hmac-ripemd160).
(hmac-md5, hmac-sha1, umac-64, hmac-ripemd160,
hmac-sha2-256 or hmac-sha2-512).
.Pp
Finally, the server and the client enter an authentication dialog.
The client tries to authenticate itself using
@ -465,10 +466,12 @@ is run, and if that
does not exist either, xauth is used to add the cookie.
.Sh AUTHORIZED_KEYS FILE FORMAT
.Cm AuthorizedKeysFile
specifies the file containing public keys for
specifies the files containing public keys for
public key authentication;
if none is specified, the default is
.Pa ~/.ssh/authorized_keys .
.Pa ~/.ssh/authorized_keys
and
.Pa ~/.ssh/authorized_keys2 .
Each line of the file contains one
key (empty lines and lines starting with a
.Ql #

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshd.c,v 1.381 2011/01/11 06:13:10 djm Exp $ */
/* $OpenBSD: sshd.c,v 1.385 2011/06/23 09:34:13 djm Exp $ */
/* $FreeBSD$ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -130,6 +130,7 @@ __RCSID("$FreeBSD$");
#endif
#include "monitor_wrap.h"
#include "roaming.h"
#include "ssh-sandbox.h"
#include "version.h"
#ifdef LIBWRAP
@ -636,42 +637,62 @@ privsep_preauth(Authctxt *authctxt)
{
int status;
pid_t pid;
struct ssh_sandbox *box = NULL;
/* Set up unprivileged child process to deal with network data */
pmonitor = monitor_init();
/* Store a pointer to the kex for later rekeying */
pmonitor->m_pkex = &xxx_kex;
if (use_privsep == PRIVSEP_SANDBOX)
box = ssh_sandbox_init();
pid = fork();
if (pid == -1) {
fatal("fork of unprivileged child failed");
} else if (pid != 0) {
debug2("Network child is on pid %ld", (long)pid);
close(pmonitor->m_recvfd);
if (box != NULL)
ssh_sandbox_parent_preauth(box, pid);
pmonitor->m_pid = pid;
monitor_child_preauth(authctxt, pmonitor);
close(pmonitor->m_sendfd);
/* Sync memory */
monitor_sync(pmonitor);
/* Wait for the child's exit status */
while (waitpid(pid, &status, 0) < 0)
while (waitpid(pid, &status, 0) < 0) {
if (errno != EINTR)
break;
return (1);
fatal("%s: waitpid: %s", __func__,
strerror(errno));
}
if (WIFEXITED(status)) {
if (WEXITSTATUS(status) != 0)
fatal("%s: preauth child exited with status %d",
__func__, WEXITSTATUS(status));
} else if (WIFSIGNALED(status))
fatal("%s: preauth child terminated by signal %d",
__func__, WTERMSIG(status));
if (box != NULL)
ssh_sandbox_parent_finish(box);
return 1;
} else {
/* child */
close(pmonitor->m_sendfd);
close(pmonitor->m_log_recvfd);
/* Arrange for logging to be sent to the monitor */
set_log_handler(mm_log_handler, pmonitor);
/* Demote the child */
if (getuid() == 0 || geteuid() == 0)
privsep_preauth_child();
setproctitle("%s", "[net]");
if (box != NULL)
ssh_sandbox_child(box);
return 0;
}
return (0);
}
static void
@ -697,7 +718,6 @@ privsep_postauth(Authctxt *authctxt)
fatal("fork of unprivileged child failed");
else if (pmonitor->m_pid != 0) {
verbose("User child is on pid %ld", (long)pmonitor->m_pid);
close(pmonitor->m_recvfd);
buffer_clear(&loginmsg);
monitor_child_postauth(pmonitor);
@ -705,7 +725,10 @@ privsep_postauth(Authctxt *authctxt)
exit(0);
}
/* child */
close(pmonitor->m_sendfd);
pmonitor->m_sendfd = -1;
/* Demote the private keys to public keys. */
demote_sensitive_data();
@ -1134,7 +1157,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
(int) received_sigterm);
close_listen_socks();
unlink(options.pid_file);
exit(255);
exit(received_sigterm == SIGTERM ? 0 : 255);
}
if (key_used && key_do_regen) {
generate_ephemeral_server_key();
@ -1325,7 +1348,6 @@ main(int ac, char **av)
(void)set_auth_parameters(ac, av);
#endif
__progname = ssh_get_progname(av[0]);
init_rng();
/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */
saved_argc = ac;

View File

@ -1,4 +1,4 @@
# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $
# $OpenBSD: sshd_config,v 1.84 2011/05/23 03:30:07 djm Exp $
# $FreeBSD$
# This is the sshd server system-wide configuration file. See
@ -8,13 +8,13 @@
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options change a
# possible, but leave them commented. Uncommented options override the
# default value.
# Note that some of FreeBSD's defaults differ from OpenBSD's, and
# FreeBSD has a few additional options.
#VersionAddendum FreeBSD-20110503
#VersionAddendum FreeBSD-20111001
#Port 22
#AddressFamily any
@ -50,7 +50,10 @@
#RSAAuthentication yes
#PubkeyAuthentication yes
#AuthorizedKeysFile .ssh/authorized_keys
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#RhostsRSAAuthentication no

View File

@ -33,9 +33,9 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: sshd_config.5,v 1.131 2010/12/08 04:02:47 djm Exp $
.\" $OpenBSD: sshd_config.5,v 1.135 2011/08/02 01:22:11 djm Exp $
.\" $FreeBSD$
.Dd December 8, 2010
.Dd August 2, 2011
.Dt SSHD_CONFIG 5
.Os
.Sh NAME
@ -169,8 +169,9 @@ After expansion,
.Cm AuthorizedKeysFile
is taken to be an absolute path or one relative to the user's home
directory.
Multiple files may be listed, separated by whitespace.
The default is
.Dq .ssh/authorized_keys .
.Dq .ssh/authorized_keys .ssh/authorized_keys2 .
.It Cm AuthorizedPrincipalsFile
Specifies a file that lists principal names that are accepted for
certificate authentication.
@ -655,7 +656,9 @@ Multiple algorithms must be comma-separated.
The default is:
.Bd -literal -offset indent
hmac-md5,hmac-sha1,umac-64@openssh.com,
hmac-ripemd160,hmac-sha1-96,hmac-md5-96
hmac-ripemd160,hmac-sha1-96,hmac-md5-96,
hmac-sha2-256,hmac-sha256-96,hmac-sha2-512,
hmac-sha2-512-96
.Ed
.It Cm Match
Introduces a conditional block.
@ -1082,11 +1085,17 @@ The goal of privilege separation is to prevent privilege
escalation by containing any corruption within the unprivileged processes.
The default is
.Dq yes .
If
.Cm UsePrivilegeSeparation
is set to
.Dq sandbox
then the pre-authentication unprivileged process is subject to additional
restrictions.
.It Cm VersionAddendum
Specifies a string to append to the regular version string to identify
OS- or site-specific modifications.
The default is
.Dq FreeBSD-20110503 .
.Dq FreeBSD-20111001 .
.It Cm X11DisplayOffset
Specifies the first display number available for
.Xr sshd 8 Ns 's

View File

@ -1,10 +1,9 @@
/* $OpenBSD: version.h,v 1.61 2011/02/04 00:44:43 djm Exp $ */
/* $OpenBSD: version.h,v 1.62 2011/08/02 23:13:01 djm Exp $ */
/* $FreeBSD$ */
#ifndef SSH_VERSION
#define SSH_VERSION_BASE "OpenSSH_5.8p2"
#define SSH_VERSION_ADDENDUM "FreeBSD-20110503"
#define SSH_VERSION_BASE "OpenSSH_5.9p1"
#define SSH_VERSION_ADDENDUM "FreeBSD-20111001"
#define SSH_VERSION_HPN "_hpn13v11"
#define SSH_VERSION SSH_VERSION_BASE SSH_VERSION_HPN " " SSH_VERSION_ADDENDUM
#define SSH_RELEASE (ssh_version_get())

View File

@ -16,7 +16,8 @@ SRCS= sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \
auth2-gss.c gss-serv.c gss-serv-krb5.c \
loginrec.c auth-pam.c auth-shadow.c auth-sia.c md5crypt.c \
sftp-server.c sftp-common.c \
roaming_common.c roaming_serv.c
roaming_common.c roaming_serv.c \
sandbox-null.c sandbox-rlimit.c sandbox-systrace.c sandbox-darwin.c
# gss-genr.c really belongs in libssh; see src/secure/lib/libssh/Makefile
SRCS+= gss-genr.c