Upgrade to OpenSSH 5.9p1.
MFC after: 3 months
This commit is contained in:
commit
e146993e33
@ -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@
|
||||
|
||||
|
@ -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 $
|
||||
|
@ -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 $
|
||||
|
@ -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 $
|
||||
|
@ -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 $
|
30
crypto/openssh/aclocal.m4
vendored
30
crypto/openssh/aclocal.m4
vendored
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "ssh-gss.h"
|
||||
#include "log.h"
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
static void *
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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(©);
|
||||
buffer_append(©, buffer_ptr(blob), buffer_len(blob));
|
||||
buffer_consume(©, 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(©); /* cipher type */
|
||||
(void) buffer_get_int(©); /* reserved */
|
||||
|
||||
/* Read the public key from the buffer. */
|
||||
(void) buffer_get_int(blob);
|
||||
(void) buffer_get_int(©);
|
||||
pub = key_new(KEY_RSA1);
|
||||
buffer_get_bignum(blob, pub->rsa->n);
|
||||
buffer_get_bignum(blob, pub->rsa->e);
|
||||
buffer_get_bignum(©, pub->rsa->n);
|
||||
buffer_get_bignum(©, pub->rsa->e);
|
||||
if (commentp)
|
||||
*commentp = buffer_get_string(blob, NULL);
|
||||
*commentp = buffer_get_string(©, NULL);
|
||||
/* The encrypted private part is not parsed by this function. */
|
||||
buffer_clear(blob);
|
||||
buffer_free(©);
|
||||
|
||||
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(©);
|
||||
buffer_append(©, buffer_ptr(blob), buffer_len(blob));
|
||||
buffer_consume(©, 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(©);
|
||||
(void) buffer_get_int(©); /* Reserved data. */
|
||||
|
||||
/* Read the public key from the buffer. */
|
||||
(void) buffer_get_int(blob);
|
||||
(void) buffer_get_int(©);
|
||||
prv = key_new_private(KEY_RSA1);
|
||||
|
||||
buffer_get_bignum(blob, prv->rsa->n);
|
||||
buffer_get_bignum(blob, prv->rsa->e);
|
||||
buffer_get_bignum(©, prv->rsa->n);
|
||||
buffer_get_bignum(©, prv->rsa->e);
|
||||
if (commentp)
|
||||
*commentp = buffer_get_string(blob, NULL);
|
||||
*commentp = buffer_get_string(©, NULL);
|
||||
else
|
||||
(void)buffer_get_string_ptr(blob, NULL);
|
||||
(void)buffer_get_string_ptr(©, 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(©);
|
||||
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(©));
|
||||
|
||||
/* 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(©), buffer_len(©));
|
||||
cipher_cleanup(&ciphercontext);
|
||||
memset(&ciphercontext, 0, sizeof(ciphercontext));
|
||||
buffer_clear(blob);
|
||||
buffer_free(©);
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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 *);
|
||||
|
||||
|
21
crypto/openssh/config.guess
vendored
21
crypto/openssh/config.guess
vendored
@ -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 ;;
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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 },
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 */
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 ""
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
0
crypto/openssh/openbsd-compat/sha2.c
Executable file → Normal file
0
crypto/openssh/openbsd-compat/sha2.h
Executable file → Normal file
0
crypto/openssh/openbsd-compat/sha2.h
Executable file → Normal 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. */
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
98
crypto/openssh/sandbox-darwin.c
Normal file
98
crypto/openssh/sandbox-darwin.c
Normal 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 */
|
72
crypto/openssh/sandbox-null.c
Normal file
72
crypto/openssh/sandbox-null.c
Normal 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 */
|
93
crypto/openssh/sandbox-rlimit.c
Normal file
93
crypto/openssh/sandbox-rlimit.c
Normal 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 */
|
198
crypto/openssh/sandbox-systrace.c
Normal file
198
crypto/openssh/sandbox-systrace.c
Normal 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 */
|
@ -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();
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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]);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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]);
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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
|
@ -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");
|
||||
}
|
23
crypto/openssh/ssh-sandbox.h
Normal file
23
crypto/openssh/ssh-sandbox.h
Normal 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);
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -46,4 +46,4 @@
|
||||
# PermitLocalCommand no
|
||||
# VisualHostKey no
|
||||
# ProxyCommand ssh -q -W %h:%p gateway.example.com
|
||||
# VersionAddendum FreeBSD-20110503
|
||||
# VersionAddendum FreeBSD-20111001
|
||||
|
@ -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 ,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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 *
|
||||
|
@ -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 #
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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())
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user