aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2010-11-08 10:45:44 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2010-11-08 10:45:44 +0000
commit3a927e69c380468bb32766c99aa7caf86de401a4 (patch)
treea92a6ad754f3ce37585ea89bd5d2693dbc5991ef
parentf276912e6fa1da1174ba900a7e5d6447d71fc8e7 (diff)
downloadsrc-3a927e69c380468bb32766c99aa7caf86de401a4.tar.gz
src-3a927e69c380468bb32766c99aa7caf86de401a4.zip
Vendor import of OpenSSH 5.6p1vendor/openssh/5.6p1
Notes
Notes: svn path=/vendor-crypto/openssh/dist/; revision=214979 svn path=/vendor-crypto/openssh/5.6p1/; revision=214980; tag=vendor/openssh/5.6p1
-rw-r--r--ChangeLog519
-rw-r--r--Makefile.in4
-rw-r--r--PROTOCOL.certkeys106
-rw-r--r--PROTOCOL.mux13
-rw-r--r--README4
-rw-r--r--auth-options.c328
-rw-r--r--auth-options.h5
-rw-r--r--auth-rsa.c9
-rw-r--r--auth.c48
-rw-r--r--auth.h4
-rw-r--r--auth1.c4
-rw-r--r--auth2-hostbased.c31
-rw-r--r--auth2-none.c4
-rw-r--r--auth2-pubkey.c145
-rw-r--r--authfd.c6
-rw-r--r--authfile.c62
-rw-r--r--authfile.h4
-rw-r--r--bufaux.c8
-rw-r--r--channels.c99
-rw-r--r--channels.h8
-rw-r--r--clientloop.c89
-rw-r--r--clientloop.h5
-rw-r--r--config.h.in3
-rwxr-xr-xconfigure10
-rw-r--r--configure.ac11
-rwxr-xr-xcontrib/aix/buildbff.sh4
-rw-r--r--contrib/caldera/openssh.spec5
-rw-r--r--contrib/cygwin/README6
-rw-r--r--contrib/redhat/openssh.spec7
-rw-r--r--contrib/ssh-copy-id10
-rw-r--r--contrib/ssh-copy-id.134
-rw-r--r--contrib/suse/openssh.spec2
-rw-r--r--jpake.c4
-rw-r--r--key.c182
-rw-r--r--key.h11
-rw-r--r--loginrec.h2
-rw-r--r--misc.c19
-rw-r--r--misc.h3
-rw-r--r--moduli.011
-rw-r--r--monitor.c20
-rw-r--r--mux.c181
-rw-r--r--myproposal.h11
-rw-r--r--openbsd-compat/Makefile.in4
-rw-r--r--openbsd-compat/openbsd-compat.h7
-rw-r--r--openbsd-compat/openssl-compat.h13
-rw-r--r--openbsd-compat/port-tun.c8
-rw-r--r--openbsd-compat/port-uw.c2
-rw-r--r--openbsd-compat/strptime.c401
-rw-r--r--packet.c4
-rw-r--r--readconf.c71
-rw-r--r--readconf.h10
-rw-r--r--regress/Makefile9
-rw-r--r--regress/README.regress4
-rwxr-xr-xregress/cert-hostkey.sh174
-rwxr-xr-xregress/cert-userkey.sh221
-rw-r--r--regress/login-timeout.sh2
-rw-r--r--regress/reconfigure.sh2
-rw-r--r--regress/reexec.sh6
-rw-r--r--regress/test-exec.sh2
-rw-r--r--scp.020
-rw-r--r--scp.c20
-rw-r--r--servconf.c31
-rw-r--r--servconf.h3
-rw-r--r--session.c46
-rw-r--r--sftp-client.c7
-rw-r--r--sftp-server.031
-rw-r--r--sftp.0101
-rw-r--r--sftp.c6
-rw-r--r--ssh-add.038
-rw-r--r--ssh-add.c50
-rw-r--r--ssh-agent.056
-rw-r--r--ssh-agent.c5
-rw-r--r--ssh-dss.c12
-rw-r--r--ssh-keygen.0254
-rw-r--r--ssh-keygen.189
-rw-r--r--ssh-keygen.c759
-rw-r--r--ssh-keyscan.033
-rw-r--r--ssh-keyscan.c165
-rw-r--r--ssh-keysign.011
-rw-r--r--ssh-keysign.87
-rw-r--r--ssh-keysign.c4
-rw-r--r--ssh-pkcs11-helper.02
-rw-r--r--ssh-pkcs11.c53
-rw-r--r--ssh-rand-helper.06
-rw-r--r--ssh-rsa.c21
-rw-r--r--ssh.0482
-rw-r--r--ssh.176
-rw-r--r--ssh.c199
-rw-r--r--ssh.h5
-rw-r--r--ssh_config.0548
-rw-r--r--ssh_config.575
-rw-r--r--sshconnect.c14
-rw-r--r--sshconnect2.c12
-rw-r--r--sshd.0391
-rw-r--r--sshd.818
-rw-r--r--sshd.c15
-rw-r--r--sshd_config.0451
-rw-r--r--sshd_config.553
-rw-r--r--version.h4
99 files changed, 4871 insertions, 2283 deletions
diff --git a/ChangeLog b/ChangeLog
index 39e0ba45dd76..e3ac6a9258dc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,522 @@
+20100823
+ - (djm) Release OpenSSH-5.6p1
+
+20100816
+ - (dtucker) [configure.ac openbsd-compat/Makefile.in
+ openbsd-compat/openbsd-compat.h openbsd-compat/strptime.c] Add strptime to
+ the compat library which helps on platforms like old IRIX. Based on work
+ by djm, tested by Tom Christensen.
+ - OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2010/08/12 21:49:44
+ [ssh.c]
+ close any extra file descriptors inherited from parent at start and
+ reopen stdin/stdout to /dev/null when forking for ControlPersist.
+
+ prevents tools that fork and run a captive ssh for communication from
+ failing to exit when the ssh completes while they wait for these fds to
+ close. The inherited fds may persist arbitrarily long if a background
+ mux master has been started by ControlPersist. cvs and scp were effected
+ by this.
+
+ "please commit" markus@
+ - (djm) [regress/README.regress] typo
+
+20100812
+ - (tim) [regress/login-timeout.sh regress/reconfigure.sh regress/reexec.sh
+ regress/test-exec.sh] Under certain conditions when testing with sudo
+ tests would fail because the pidfile could not be read by a regular user.
+ "cat: cannot open ...../regress/pidfile: Permission denied (error 13)"
+ Make sure cat is run by $SUDO. no objection from me. djm@
+ - (tim) [auth.c] add cast to quiet compiler. Change only affects SVR5 systems.
+
+20100809
+ - (djm) bz#1561: don't bother setting IFF_UP on tun(4) device if it is
+ already set. Makes FreeBSD user openable tunnels useful; patch from
+ richard.burakowski+ossh AT mrburak.net, ok dtucker@
+ - (dtucker) bug #1530: strip trailing ":" from hostname in ssh-copy-id.
+ based in part on a patch from Colin Watson, ok djm@
+
+20100809
+ - OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2010/08/08 16:26:42
+ [version.h]
+ crank to 5.6
+ - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec]
+ [contrib/suse/openssh.spec] Crank version numbers
+
+20100805
+ - OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2010/08/04 05:37:01
+ [ssh.1 ssh_config.5 sshd.8]
+ Remove mentions of weird "addr/port" alternate address format for IPv6
+ addresses combinations. It hasn't worked for ages and we have supported
+ the more commen "[addr]:port" format for a long time. ok jmc@ markus@
+ - djm@cvs.openbsd.org 2010/08/04 05:40:39
+ [PROTOCOL.certkeys ssh-keygen.c]
+ tighten the rules for certificate encoding by requiring that options
+ appear in lexical order and make our ssh-keygen comply. ok markus@
+ - djm@cvs.openbsd.org 2010/08/04 05:42:47
+ [auth.c auth2-hostbased.c authfile.c authfile.h ssh-keysign.8]
+ [ssh-keysign.c ssh.c]
+ enable certificates for hostbased authentication, from Iain Morgan;
+ "looks ok" markus@
+ - djm@cvs.openbsd.org 2010/08/04 05:49:22
+ [authfile.c]
+ commited the wrong version of the hostbased certificate diff; this
+ version replaces some strlc{py,at} verbosity with xasprintf() at
+ the request of markus@
+ - djm@cvs.openbsd.org 2010/08/04 06:07:11
+ [ssh-keygen.1 ssh-keygen.c]
+ Support CA keys in PKCS#11 tokens; feedback and ok markus@
+ - djm@cvs.openbsd.org 2010/08/04 06:08:40
+ [ssh-keysign.c]
+ clean for -Wuninitialized (Id sync only; portable had this change)
+ - djm@cvs.openbsd.org 2010/08/05 13:08:42
+ [channels.c]
+ Fix a trio of bugs in the local/remote window calculation for datagram
+ data channels (i.e. TunnelForward):
+
+ Calculate local_consumed correctly in channel_handle_wfd() by measuring
+ the delta to buffer_len(c->output) from when we start to when we finish.
+ The proximal problem here is that the output_filter we use in portable
+ modified the length of the dequeued datagram (to futz with the headers
+ for !OpenBSD).
+
+ In channel_output_poll(), don't enqueue datagrams that won't fit in the
+ peer's advertised packet size (highly unlikely to ever occur) or which
+ won't fit in the peer's remaining window (more likely).
+
+ In channel_input_data(), account for the 4-byte string header in
+ datagram packets that we accept from the peer and enqueue in c->output.
+
+ report, analysis and testing 2/3 cases from wierbows AT us.ibm.com;
+ "looks good" markus@
+
+20100803
+ - (dtucker) [monitor.c] Bug #1795: Initialize the values to be returned from
+ PAM to sane values in case the PAM method doesn't write to them. Spotted by
+ Bitman Zhou, ok djm@.
+ - OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2010/07/16 04:45:30
+ [ssh-keygen.c]
+ avoid bogus compiler warning
+ - djm@cvs.openbsd.org 2010/07/16 14:07:35
+ [ssh-rsa.c]
+ more timing paranoia - compare all parts of the expected decrypted
+ data before returning. AFAIK not exploitable in the SSH protocol.
+ "groovy" deraadt@
+ - djm@cvs.openbsd.org 2010/07/19 03:16:33
+ [sftp-client.c]
+ bz#1797: fix swapped args in upload_dir_internal(), breaking recursive
+ upload depth checks and causing verbose printing of transfers to always
+ be turned on; patch from imorgan AT nas.nasa.gov
+ - djm@cvs.openbsd.org 2010/07/19 09:15:12
+ [clientloop.c readconf.c readconf.h ssh.c ssh_config.5]
+ add a "ControlPersist" option that automatically starts a background
+ ssh(1) multiplex master when connecting. This connection can stay alive
+ indefinitely, or can be set to automatically close after a user-specified
+ duration of inactivity. bz#1330 - patch by dwmw2 AT infradead.org, but
+ further hacked on by wmertens AT cisco.com, apb AT cequrux.com,
+ martin-mindrot-bugzilla AT earth.li and myself; "looks ok" markus@
+ - djm@cvs.openbsd.org 2010/07/21 02:10:58
+ [misc.c]
+ sync timingsafe_bcmp() with the one dempsky@ committed to sys/lib/libkern
+ - dtucker@cvs.openbsd.org 2010/07/23 08:49:25
+ [ssh.1]
+ Ciphers is documented in ssh_config(5) these days
+
+20100819
+ - (dtucker) [contrib/ssh-copy-ud.1] Bug #1786: update ssh-copy-id.1 with more
+ details about its behaviour WRT existing directories. Patch from
+ asguthrie at gmail com, ok djm.
+
+20100716
+ - (djm) OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2010/07/02 04:32:44
+ [misc.c]
+ unbreak strdelim() skipping past quoted strings, e.g.
+ AllowUsers "blah blah" blah
+ was broken; report and fix in bz#1757 from bitman.zhou AT centrify.com
+ ok dtucker;
+ - djm@cvs.openbsd.org 2010/07/12 22:38:52
+ [ssh.c]
+ Make ExitOnForwardFailure work with fork-after-authentication ("ssh -f")
+ for protocol 2. ok markus@
+ - djm@cvs.openbsd.org 2010/07/12 22:41:13
+ [ssh.c ssh_config.5]
+ expand %h to the hostname in ssh_config Hostname options. While this
+ sounds useless, it is actually handy for working with unqualified
+ hostnames:
+
+ Host *.*
+ Hostname %h
+ Host *
+ Hostname %h.example.org
+
+ "I like it" markus@
+ - djm@cvs.openbsd.org 2010/07/13 11:52:06
+ [auth-rsa.c channels.c jpake.c key.c misc.c misc.h monitor.c]
+ [packet.c ssh-rsa.c]
+ implement a timing_safe_cmp() function to compare memory without leaking
+ timing information by short-circuiting like memcmp() and use it for
+ some of the more sensitive comparisons (though nothing high-value was
+ readily attackable anyway); "looks ok" markus@
+ - djm@cvs.openbsd.org 2010/07/13 23:13:16
+ [auth-rsa.c channels.c jpake.c key.c misc.c misc.h monitor.c packet.c]
+ [ssh-rsa.c]
+ s/timing_safe_cmp/timingsafe_bcmp/g
+ - jmc@cvs.openbsd.org 2010/07/14 17:06:58
+ [ssh.1]
+ finally ssh synopsis looks nice again! this commit just removes a ton of
+ hacks we had in place to make it work with old groff;
+ - schwarze@cvs.openbsd.org 2010/07/15 21:20:38
+ [ssh-keygen.1]
+ repair incorrect block nesting, which screwed up indentation;
+ problem reported and fix OK by jmc@
+
+20100714
+ - (tim) [contrib/redhat/openssh.spec] Bug 1796: Test for skip_x11_askpass
+ (line 77) should have been for no_x11_askpass.
+
+20100702
+ - (djm) OpenBSD CVS Sync
+ - jmc@cvs.openbsd.org 2010/06/26 00:57:07
+ [ssh_config.5]
+ tweak previous;
+ - djm@cvs.openbsd.org 2010/06/26 23:04:04
+ [ssh.c]
+ oops, forgot to #include <canohost.h>; spotted and patch from chl@
+ - djm@cvs.openbsd.org 2010/06/29 23:15:30
+ [ssh-keygen.1 ssh-keygen.c]
+ allow import (-i) and export (-e) of PEM and PKCS#8 encoded keys;
+ bz#1749; ok markus@
+ - djm@cvs.openbsd.org 2010/06/29 23:16:46
+ [auth2-pubkey.c sshd_config.5]
+ allow key options (command="..." and friends) in AuthorizedPrincipals;
+ ok markus@
+ - jmc@cvs.openbsd.org 2010/06/30 07:24:25
+ [ssh-keygen.1]
+ tweak previous;
+ - jmc@cvs.openbsd.org 2010/06/30 07:26:03
+ [ssh-keygen.c]
+ sort usage();
+ - jmc@cvs.openbsd.org 2010/06/30 07:28:34
+ [sshd_config.5]
+ tweak previous;
+ - millert@cvs.openbsd.org 2010/07/01 13:06:59
+ [scp.c]
+ Fix a longstanding problem where if you suspend scp at the
+ password/passphrase prompt the terminal mode is not restored.
+ OK djm@
+ - phessler@cvs.openbsd.org 2010/06/27 19:19:56
+ [regress/Makefile]
+ fix how we run the tests so we can successfully use SUDO='sudo -E'
+ in our env
+ - djm@cvs.openbsd.org 2010/06/29 23:59:54
+ [cert-userkey.sh]
+ regress tests for key options in AuthorizedPrincipals
+
+20100627
+ - (tim) [openbsd-compat/port-uw.c] Reorder includes. auth-options.h now needs
+ key.h.
+
+20100626
+ - (djm) OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2010/05/21 05:00:36
+ [misc.c]
+ colon() returns char*, so s/return (0)/return NULL/
+ - markus@cvs.openbsd.org 2010/06/08 21:32:19
+ [ssh-pkcs11.c]
+ check length of value returned C_GetAttributValue for != 0
+ from mdrtbugzilla@codefive.co.uk; bugzilla #1773; ok dtucker@
+ - djm@cvs.openbsd.org 2010/06/17 07:07:30
+ [mux.c]
+ Correct sizing of object to be allocated by calloc(), replacing
+ sizeof(state) with sizeof(*state). This worked by accident since
+ the struct contained a single int at present, but could have broken
+ in the future. patch from hyc AT symas.com
+ - djm@cvs.openbsd.org 2010/06/18 00:58:39
+ [sftp.c]
+ unbreak ls in working directories that contains globbing characters in
+ their pathnames. bz#1655 reported by vgiffin AT apple.com
+ - djm@cvs.openbsd.org 2010/06/18 03:16:03
+ [session.c]
+ Missing check for chroot_director == "none" (we already checked against
+ NULL); bz#1564 from Jan.Pechanec AT Sun.COM
+ - djm@cvs.openbsd.org 2010/06/18 04:43:08
+ [sftp-client.c]
+ fix memory leak in do_realpath() error path; bz#1771, patch from
+ anicka AT suse.cz
+ - djm@cvs.openbsd.org 2010/06/22 04:22:59
+ [servconf.c sshd_config.5]
+ expose some more sshd_config options inside Match blocks:
+ AuthorizedKeysFile AuthorizedPrincipalsFile
+ HostbasedUsesNameFromPacketOnly PermitTunnel
+ bz#1764; feedback from imorgan AT nas.nasa.gov; ok dtucker@
+ - djm@cvs.openbsd.org 2010/06/22 04:32:06
+ [ssh-keygen.c]
+ standardise error messages when attempting to open private key
+ files to include "progname: filename: error reason"
+ bz#1783; ok dtucker@
+ - djm@cvs.openbsd.org 2010/06/22 04:49:47
+ [auth.c]
+ queue auth debug messages for bad ownership or permissions on the user's
+ keyfiles. These messages will be sent after the user has successfully
+ authenticated (where our client will display them with LogLevel=debug).
+ bz#1554; ok dtucker@
+ - djm@cvs.openbsd.org 2010/06/22 04:54:30
+ [ssh-keyscan.c]
+ replace verbose and overflow-prone Linebuf code with read_keyfile_line()
+ based on patch from joachim AT joachimschipper.nl; bz#1565; ok dtucker@
+ - djm@cvs.openbsd.org 2010/06/22 04:59:12
+ [session.c]
+ include the user name on "subsystem request for ..." log messages;
+ bz#1571; ok dtucker@
+ - djm@cvs.openbsd.org 2010/06/23 02:59:02
+ [ssh-keygen.c]
+ fix printing of extensions in v01 certificates that I broke in r1.190
+ - djm@cvs.openbsd.org 2010/06/25 07:14:46
+ [channels.c mux.c readconf.c readconf.h ssh.h]
+ bz#1327: remove hardcoded limit of 100 permitopen clauses and port
+ forwards per direction; ok markus@ stevesk@
+ - djm@cvs.openbsd.org 2010/06/25 07:20:04
+ [channels.c session.c]
+ bz#1750: fix requirement for /dev/null inside ChrootDirectory for
+ internal-sftp accidentally introduced in r1.253 by removing the code
+ that opens and dup /dev/null to stderr and modifying the channels code
+ to read stderr but discard it instead; ok markus@
+ - djm@cvs.openbsd.org 2010/06/25 08:46:17
+ [auth1.c auth2-none.c]
+ skip the initial check for access with an empty password when
+ PermitEmptyPasswords=no; bz#1638; ok markus@
+ - djm@cvs.openbsd.org 2010/06/25 23:10:30
+ [ssh.c]
+ log the hostname and address that we connected to at LogLevel=verbose
+ after authentication is successful to mitigate "phishing" attacks by
+ servers with trusted keys that accept authentication silently and
+ automatically before presenting fake password/passphrase prompts;
+ "nice!" markus@
+ - djm@cvs.openbsd.org 2010/06/25 23:10:30
+ [ssh.c]
+ log the hostname and address that we connected to at LogLevel=verbose
+ after authentication is successful to mitigate "phishing" attacks by
+ servers with trusted keys that accept authentication silently and
+ automatically before presenting fake password/passphrase prompts;
+ "nice!" markus@
+
+20100622
+ - (djm) [loginrec.c] crank LINFO_NAMESIZE (username length) to 512
+ bz#1579; ok dtucker
+
+20100618
+ - (djm) [contrib/ssh-copy-id] Update key file explicitly under ~
+ rather than assuming that $CWD == $HOME. bz#1500, patch from
+ timothy AT gelter.com
+
+20100617
+ - (tim) [contrib/cygwin/README] Remove a reference to the obsolete
+ minires-devel package, and to add the reference to the libedit-devel
+ package since CYgwin now provides libedit. Patch from Corinna Vinschen.
+
+20100521
+ - (djm) OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2010/05/07 11:31:26
+ [regress/Makefile regress/cert-userkey.sh]
+ regress tests for AuthorizedPrincipalsFile and "principals=" key option.
+ feedback and ok markus@
+ - djm@cvs.openbsd.org 2010/05/11 02:58:04
+ [auth-rsa.c]
+ don't accept certificates marked as "cert-authority" here; ok markus@
+ - djm@cvs.openbsd.org 2010/05/14 00:47:22
+ [ssh-add.c]
+ check that the certificate matches the corresponding private key before
+ grafting it on
+ - djm@cvs.openbsd.org 2010/05/14 23:29:23
+ [channels.c channels.h mux.c ssh.c]
+ Pause the mux channel while waiting for reply from aynch callbacks.
+ Prevents misordering of replies if new requests arrive while waiting.
+
+ Extend channel open confirm callback to allow signalling failure
+ conditions as well as success. Use this to 1) fix a memory leak, 2)
+ start using the above pause mechanism and 3) delay sending a success/
+ failure message on mux slave session open until we receive a reply from
+ the server.
+
+ motivated by and with feedback from markus@
+ - markus@cvs.openbsd.org 2010/05/16 12:55:51
+ [PROTOCOL.mux clientloop.h mux.c readconf.c readconf.h ssh.1 ssh.c]
+ mux support for remote forwarding with dynamic port allocation,
+ use with
+ LPORT=`ssh -S muxsocket -R0:localhost:25 -O forward somehost`
+ feedback and ok djm@
+ - djm@cvs.openbsd.org 2010/05/20 11:25:26
+ [auth2-pubkey.c]
+ fix logspam when key options (from="..." especially) deny non-matching
+ keys; reported by henning@ also bz#1765; ok markus@ dtucker@
+ - djm@cvs.openbsd.org 2010/05/20 23:46:02
+ [PROTOCOL.certkeys auth-options.c ssh-keygen.c]
+ Move the permit-* options to the non-critical "extensions" field for v01
+ certificates. The logic is that if another implementation fails to
+ implement them then the connection just loses features rather than fails
+ outright.
+
+ ok markus@
+
+20100511
+ - (dtucker) [Makefile.in] Bug #1770: Link libopenbsd-compat twice to solve
+ circular dependency problem on old or odd platforms. From Tom Lane, ok
+ djm@.
+ - (djm) [openbsd-compat/openssl-compat.h] Fix build breakage on older
+ libcrypto by defining OPENSSL_[DR]SA_MAX_MODULUS_BITS if they aren't
+ already. ok dtucker@
+
+20100510
+ - OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2010/04/23 01:47:41
+ [ssh-keygen.c]
+ bz#1740: display a more helpful error message when $HOME is
+ inaccessible while trying to create .ssh directory. Based on patch
+ from jchadima AT redhat.com; ok dtucker@
+ - djm@cvs.openbsd.org 2010/04/23 22:27:38
+ [mux.c]
+ set "detach_close" flag when registering channel cleanup callbacks.
+ This causes the channel to close normally when its fds close and
+ hangs when terminating a mux slave using ~. bz#1758; ok markus@
+ - djm@cvs.openbsd.org 2010/04/23 22:42:05
+ [session.c]
+ set stderr to /dev/null for subsystems rather than just closing it.
+ avoids hangs if a subsystem or shell initialisation writes to stderr.
+ bz#1750; ok markus@
+ - djm@cvs.openbsd.org 2010/04/23 22:48:31
+ [ssh-keygen.c]
+ refuse to generate keys longer than OPENSSL_[RD]SA_MAX_MODULUS_BITS,
+ since we would refuse to use them anyway. bz#1516; ok dtucker@
+ - djm@cvs.openbsd.org 2010/04/26 22:28:24
+ [sshconnect2.c]
+ bz#1502: authctxt.success is declared as an int, but passed by
+ reference to function that accepts sig_atomic_t*. Convert it to
+ the latter; ok markus@ dtucker@
+ - djm@cvs.openbsd.org 2010/05/01 02:50:50
+ [PROTOCOL.certkeys]
+ typo; jmeltzer@
+ - dtucker@cvs.openbsd.org 2010/05/05 04:22:09
+ [sftp.c]
+ restore mput and mget which got lost in the tab-completion changes.
+ found by Kenneth Whitaker, ok djm@
+ - djm@cvs.openbsd.org 2010/05/07 11:30:30
+ [auth-options.c auth-options.h auth.c auth.h auth2-pubkey.c]
+ [key.c servconf.c servconf.h sshd.8 sshd_config.5]
+ add some optional indirection to matching of principal names listed
+ in certificates. Currently, a certificate must include the a user's name
+ to be accepted for authentication. This change adds the ability to
+ specify a list of certificate principal names that are acceptable.
+
+ When authenticating using a CA trusted through ~/.ssh/authorized_keys,
+ this adds a new principals="name1[,name2,...]" key option.
+
+ For CAs listed through sshd_config's TrustedCAKeys option, a new config
+ option "AuthorizedPrincipalsFile" specifies a per-user file containing
+ the list of acceptable names.
+
+ If either option is absent, the current behaviour of requiring the
+ username to appear in principals continues to apply.
+
+ These options are useful for role accounts, disjoint account namespaces
+ and "user@realm"-style naming policies in certificates.
+
+ feedback and ok markus@
+ - jmc@cvs.openbsd.org 2010/05/07 12:49:17
+ [sshd_config.5]
+ tweak previous;
+
+20100423
+ - (dtucker) [configure.ac] Bug #1756: Check for the existence of a lib64 dir
+ in the openssl install directory (some newer openssl versions do this on at
+ least some amd64 platforms).
+
+20100418
+ - OpenBSD CVS Sync
+ - jmc@cvs.openbsd.org 2010/04/16 06:45:01
+ [ssh_config.5]
+ tweak previous; ok djm
+ - jmc@cvs.openbsd.org 2010/04/16 06:47:04
+ [ssh-keygen.1 ssh-keygen.c]
+ tweak previous; ok djm
+ - djm@cvs.openbsd.org 2010/04/16 21:14:27
+ [sshconnect.c]
+ oops, %r => remote username, not %u
+ - djm@cvs.openbsd.org 2010/04/16 01:58:45
+ [regress/cert-hostkey.sh regress/cert-userkey.sh]
+ regression tests for v01 certificate format
+ includes interop tests for v00 certs
+ - (dtucker) [contrib/aix/buildbff.sh] Fix creation of ssh_prng_cmds.default
+ file.
+
+20100416
+ - (djm) Release openssh-5.5p1
+ - OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2010/03/26 03:13:17
+ [bufaux.c]
+ allow buffer_get_int_ret/buffer_get_int64_ret to take a NULL pointer
+ argument to allow skipping past values in a buffer
+ - jmc@cvs.openbsd.org 2010/03/26 06:54:36
+ [ssh.1]
+ tweak previous;
+ - jmc@cvs.openbsd.org 2010/03/27 14:26:55
+ [ssh_config.5]
+ tweak previous; ok dtucker
+ - djm@cvs.openbsd.org 2010/04/10 00:00:16
+ [ssh.c]
+ bz#1746 - suppress spurious tty warning when using -O and stdin
+ is not a tty; ok dtucker@ markus@
+ - djm@cvs.openbsd.org 2010/04/10 00:04:30
+ [sshconnect.c]
+ fix terminology: we didn't find a certificate in known_hosts, we found
+ a CA key
+ - djm@cvs.openbsd.org 2010/04/10 02:08:44
+ [clientloop.c]
+ bz#1698: kill channel when pty allocation requests fail. Fixed
+ stuck client if the server refuses pty allocation.
+ ok dtucker@ "think so" markus@
+ - djm@cvs.openbsd.org 2010/04/10 02:10:56
+ [sshconnect2.c]
+ show the key type that we are offering in debug(), helps distinguish
+ between certs and plain keys as the path to the private key is usually
+ the same.
+ - djm@cvs.openbsd.org 2010/04/10 05:48:16
+ [mux.c]
+ fix NULL dereference; from matthew.haub AT alumni.adelaide.edu.au
+ - djm@cvs.openbsd.org 2010/04/14 22:27:42
+ [ssh_config.5 sshconnect.c]
+ expand %r => remote username in ssh_config:ProxyCommand;
+ ok deraadt markus
+ - markus@cvs.openbsd.org 2010/04/15 20:32:55
+ [ssh-pkcs11.c]
+ retry lookup for private key if there's no matching key with CKA_SIGN
+ attribute enabled; this fixes fixes MuscleCard support (bugzilla #1736)
+ ok djm@
+ - djm@cvs.openbsd.org 2010/04/16 01:47:26
+ [PROTOCOL.certkeys auth-options.c auth-options.h auth-rsa.c]
+ [auth2-pubkey.c authfd.c key.c key.h myproposal.h ssh-add.c]
+ [ssh-agent.c ssh-dss.c ssh-keygen.1 ssh-keygen.c ssh-rsa.c]
+ [sshconnect.c sshconnect2.c sshd.c]
+ revised certificate format ssh-{dss,rsa}-cert-v01@openssh.com with the
+ following changes:
+
+ move the nonce field to the beginning of the certificate where it can
+ better protect against chosen-prefix attacks on the signature hash
+
+ Rename "constraints" field to "critical options"
+
+ Add a new non-critical "extensions" field
+
+ Add a serial number
+
+ The older format is still support for authentication and cert generation
+ (use "ssh-keygen -t v00 -s ca_key ..." to generate a v00 certificate)
+
+ ok markus@
+
20100410
- (dtucker) [configure.ac] Put the check for the existence of getaddrinfo
back so we disable the IPv6 tests if we don't have it.
diff --git a/Makefile.in b/Makefile.in
index 476674b0e49f..5654d4341467 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
-# $Id: Makefile.in,v 1.309 2010/03/13 21:41:34 djm Exp $
+# $Id: Makefile.in,v 1.310 2010/05/12 06:51:39 dtucker Exp $
# uncomment if you run a non bourne compatable shell. Ie. csh
#SHELL = @SH@
@@ -160,7 +160,7 @@ ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o readco
$(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o
- $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
+ $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o
$(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
diff --git a/PROTOCOL.certkeys b/PROTOCOL.certkeys
index 1ed9e2064101..1d1be13da773 100644
--- a/PROTOCOL.certkeys
+++ b/PROTOCOL.certkeys
@@ -16,7 +16,7 @@ These protocol extensions build on the simple public key authentication
system already in SSH to allow certificate-based authentication.
The certificates used are not traditional X.509 certificates, with
numerous options and complex encoding rules, but something rather
-more minimal: a key, some identity information and usage constraints
+more minimal: a key, some identity information and usage options
that have been signed with some other trusted key.
A sshd server may be configured to allow authentication via certified
@@ -27,7 +27,7 @@ of acceptance of certified host keys, by adding a similar ability
to specify CA keys in ~/.ssh/known_hosts.
Certified keys are represented using two new key types:
-ssh-rsa-cert-v00@openssh.com and ssh-dss-cert-v00@openssh.com that
+ssh-rsa-cert-v01@openssh.com and ssh-dss-cert-v01@openssh.com that
include certification information along with the public key that is used
to sign challenges. ssh-keygen performs the CA signing operation.
@@ -47,7 +47,7 @@ in RFC4252 section 7.
New public key formats
----------------------
-The ssh-rsa-cert-v00@openssh.com and ssh-dss-cert-v00@openssh.com key
+The ssh-rsa-cert-v01@openssh.com and ssh-dss-cert-v01@openssh.com key
types take a similar high-level format (note: data types and
encoding are as per RFC4251 section 5). The serialised wire encoding of
these certificates is also used for storing them on disk.
@@ -57,42 +57,55 @@ these certificates is also used for storing them on disk.
RSA certificate
- string "ssh-rsa-cert-v00@openssh.com"
+ string "ssh-rsa-cert-v01@openssh.com"
+ string nonce
mpint e
mpint n
+ uint64 serial
uint32 type
string key id
string valid principals
uint64 valid after
uint64 valid before
- string constraints
- string nonce
+ string critical options
+ string extensions
string reserved
string signature key
string signature
DSA certificate
- string "ssh-dss-cert-v00@openssh.com"
+ string "ssh-dss-cert-v01@openssh.com"
+ string nonce
mpint p
mpint q
mpint g
mpint y
+ uint64 serial
uint32 type
string key id
string valid principals
uint64 valid after
uint64 valid before
- string constraints
- string nonce
+ string critical options
+ string extensions
string reserved
string signature key
string signature
+The nonce field is a CA-provided random bitstring of arbitrary length
+(but typically 16 or 32 bytes) included to make attacks that depend on
+inducing collisions in the signature hash infeasible.
+
e and n are the RSA exponent and public modulus respectively.
p, q, g, y are the DSA parameters as described in FIPS-186-2.
+serial is an optional certificate serial number set by the CA to
+provide an abbreviated way to refer to certificates from that CA.
+If a CA does not wish to number its certificates it must set this
+field to zero.
+
type specifies whether this certificate is for identification of a user
or a host using a SSH_CERT_TYPE_... value.
@@ -112,13 +125,15 @@ certificate. Each represents a time in seconds since 1970-01-01
00:00:00. A certificate is considered valid if:
valid after <= current time < valid before
-constraints is a set of zero or more key constraints encoded as below.
+criticial options is a set of zero or more key options encoded as
+below. All such options are "critical" in the sense that an implementation
+must refuse to authorise a key that has an unrecognised option.
-The nonce field is a CA-provided random bitstring of arbitrary length
-(but typically 16 or 32 bytes) included to make attacks that depend on
-inducing collisions in the signature hash infeasible.
+extensions is a set of zero or more optional extensions. These extensions
+are not critical, and an implementation that encounters one that it does
+not recognise may safely ignore it.
-The reserved field is current unused and is ignored in this version of
+The reserved field is currently unused and is ignored in this version of
the protocol.
signature key contains the CA key used to sign the certificate.
@@ -132,22 +147,25 @@ up to, and including the signature key. Signatures are computed and
encoded according to the rules defined for the CA's public key algorithm
(RFC4253 section 6.6 for ssh-rsa and ssh-dss).
-Constraints
------------
+Critical options
+----------------
-The constraints section of the certificate specifies zero or more
-constraints on the certificates validity. The format of this field
+The critical options section of the certificate specifies zero or more
+options on the certificates validity. The format of this field
is a sequence of zero or more tuples:
string name
string data
-The name field identifies the constraint and the data field encodes
-constraint-specific information (see below). All constraints are
-"critical", if an implementation does not recognise a constraint
+Options must be lexically ordered by "name" if they appear in the
+sequence.
+
+The name field identifies the option and the data field encodes
+option-specific information (see below). All options are
+"critical", if an implementation does not recognise a option
then the validating party should refuse to accept the certificate.
-The supported constraints and the contents and structure of their
+The supported options and the contents and structure of their
data fields are:
Name Format Description
@@ -157,37 +175,51 @@ force-command string Specifies a command that is executed
ssh command-line) whenever this key is
used for authentication.
+source-address string Comma-separated list of source addresses
+ from which this certificate is accepted
+ for authentication. Addresses are
+ specified in CIDR format (nn.nn.nn.nn/nn
+ or hhhh::hhhh/nn).
+ If this option is not present then
+ certificates may be presented from any
+ source address.
+
+Extensions
+----------
+
+The extensions section of the certificate specifies zero or more
+non-critical certificate extensions. The encoding and ordering of
+extensions in this field is identical to that of the critical options.
+If an implementation does not recognise an extension, then it should
+ignore it.
+
+The supported extensions and the contents and structure of their data
+fields are:
+
+Name Format Description
+-----------------------------------------------------------------------------
permit-X11-forwarding empty Flag indicating that X11 forwarding
should be permitted. X11 forwarding will
- be refused if this constraint is absent.
+ be refused if this option is absent.
permit-agent-forwarding empty Flag indicating that agent forwarding
should be allowed. Agent forwarding
must not be permitted unless this
- constraint is present.
+ option is present.
permit-port-forwarding empty Flag indicating that port-forwarding
- should be allowed. If this constraint is
+ should be allowed. If this option is
not present then no port forwarding will
be allowed.
permit-pty empty Flag indicating that PTY allocation
should be permitted. In the absence of
- this constraint PTY allocation will be
+ this option PTY allocation will be
disabled.
permit-user-rc empty Flag indicating that execution of
~/.ssh/rc should be permitted. Execution
of this script will not be permitted if
- this constraint is not present.
-
-source-address string Comma-separated list of source addresses
- from which this certificate is accepted
- for authentication. Addresses are
- specified in CIDR format (nn.nn.nn.nn/nn
- or hhhh::hhhh/nn).
- If this constraint is not present then
- certificates may be presented from any
- source address.
+ this option is not present.
-$OpenBSD: PROTOCOL.certkeys,v 1.3 2010/03/03 22:50:40 djm Exp $
+$OpenBSD: PROTOCOL.certkeys,v 1.7 2010/08/04 05:40:39 djm Exp $
diff --git a/PROTOCOL.mux b/PROTOCOL.mux
index d22f7379c85c..1d8c463a7477 100644
--- a/PROTOCOL.mux
+++ b/PROTOCOL.mux
@@ -109,8 +109,14 @@ A client may request the master to establish a port forward:
forwarding type may be MUX_FWD_LOCAL, MUX_FWD_REMOTE, MUX_FWD_DYNAMIC.
-A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a
-MUX_S_FAILURE.
+A server may reply with a MUX_S_OK, a MUX_S_REMOTE_PORT, a
+MUX_S_PERMISSION_DENIED or a MUX_S_FAILURE.
+
+For dynamically allocated listen port the server replies with
+
+ uint32 MUX_S_REMOTE_PORT
+ uint32 client request id
+ uint32 allocated remote listen port
5. Requesting closure of port forwards
@@ -178,6 +184,7 @@ The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason:
#define MUX_S_EXIT_MESSAGE 0x80000004
#define MUX_S_ALIVE 0x80000005
#define MUX_S_SESSION_OPENED 0x80000006
+#define MUX_S_REMOTE_PORT 0x80000007
#define MUX_FWD_LOCAL 1
#define MUX_FWD_REMOTE 2
@@ -193,4 +200,4 @@ XXX server->client error/warning notifications
XXX port0 rfwd (need custom response message)
XXX send signals via mux
-$OpenBSD: PROTOCOL.mux,v 1.1 2010/01/26 01:28:35 djm Exp $
+$OpenBSD: PROTOCOL.mux,v 1.2 2010/05/16 12:55:51 markus Exp $
diff --git a/README b/README
index a29f2007dcac..4eaa5458814f 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-See http://www.openssh.com/txt/release-5.5 for the release notes.
+See http://www.openssh.com/txt/release-5.6 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.73 2010/03/21 19:11:55 djm Exp $
+$Id: README,v 1.74 2010/08/08 16:32:06 djm Exp $
diff --git a/auth-options.c b/auth-options.c
index 69b314fbd11a..a7040247fe67 100644
--- a/auth-options.c
+++ b/auth-options.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-options.c,v 1.49 2010/03/16 15:46:52 stevesk Exp $ */
+/* $OpenBSD: auth-options.c,v 1.52 2010/05/20 23:46:02 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -27,10 +27,10 @@
#include "canohost.h"
#include "buffer.h"
#include "channels.h"
-#include "auth-options.h"
#include "servconf.h"
#include "misc.h"
#include "key.h"
+#include "auth-options.h"
#include "hostfile.h"
#include "auth.h"
#ifdef GSSAPI
@@ -55,6 +55,9 @@ struct envstring *custom_environment = NULL;
/* "tunnel=" option. */
int forced_tun_device = -1;
+/* "principals=" option. */
+char *authorized_principals = NULL;
+
extern ServerOptions options;
void
@@ -76,6 +79,10 @@ auth_clear_options(void)
xfree(forced_command);
forced_command = NULL;
}
+ if (authorized_principals) {
+ xfree(authorized_principals);
+ authorized_principals = NULL;
+ }
forced_tun_device = -1;
channel_clear_permitted_opens();
}
@@ -141,6 +148,8 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
cp = "command=\"";
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
opts += strlen(cp);
+ if (forced_command != NULL)
+ xfree(forced_command);
forced_command = xmalloc(strlen(opts) + 1);
i = 0;
while (*opts) {
@@ -167,6 +176,38 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
opts++;
goto next_option;
}
+ cp = "principals=\"";
+ if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+ opts += strlen(cp);
+ if (authorized_principals != NULL)
+ xfree(authorized_principals);
+ authorized_principals = xmalloc(strlen(opts) + 1);
+ i = 0;
+ while (*opts) {
+ if (*opts == '"')
+ break;
+ if (*opts == '\\' && opts[1] == '"') {
+ opts += 2;
+ authorized_principals[i++] = '"';
+ continue;
+ }
+ authorized_principals[i++] = *opts++;
+ }
+ if (!*opts) {
+ debug("%.100s, line %lu: missing end quote",
+ file, linenum);
+ auth_debug_add("%.100s, line %lu: missing end quote",
+ file, linenum);
+ xfree(authorized_principals);
+ authorized_principals = NULL;
+ goto bad_option;
+ }
+ authorized_principals[i] = '\0';
+ auth_debug_add("principals: %.900s",
+ authorized_principals);
+ opts++;
+ goto next_option;
+ }
cp = "environment=\"";
if (options.permit_user_env &&
strncasecmp(opts, cp, strlen(cp)) == 0) {
@@ -376,123 +417,147 @@ bad_option:
return 0;
}
-/*
- * Set options from certificate constraints. These supersede user key options
- * so this must be called after auth_parse_options().
- */
-int
-auth_cert_constraints(Buffer *c_orig, struct passwd *pw)
+#define OPTIONS_CRITICAL 1
+#define OPTIONS_EXTENSIONS 2
+static int
+parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw,
+ u_int which, int crit,
+ int *cert_no_port_forwarding_flag,
+ int *cert_no_agent_forwarding_flag,
+ int *cert_no_x11_forwarding_flag,
+ int *cert_no_pty_flag,
+ int *cert_no_user_rc,
+ char **cert_forced_command,
+ int *cert_source_address_done)
{
+ char *command, *allowed;
+ const char *remote_ip;
u_char *name = NULL, *data_blob = NULL;
u_int nlen, dlen, clen;
Buffer c, data;
- int ret = -1;
-
- int cert_no_port_forwarding_flag = 1;
- int cert_no_agent_forwarding_flag = 1;
- int cert_no_x11_forwarding_flag = 1;
- int cert_no_pty_flag = 1;
- int cert_no_user_rc = 1;
- char *cert_forced_command = NULL;
- int cert_source_address_done = 0;
+ int ret = -1, found;
buffer_init(&data);
/* Make copy to avoid altering original */
buffer_init(&c);
- buffer_append(&c, buffer_ptr(c_orig), buffer_len(c_orig));
+ buffer_append(&c, optblob, optblob_len);
while (buffer_len(&c) > 0) {
if ((name = buffer_get_string_ret(&c, &nlen)) == NULL ||
(data_blob = buffer_get_string_ret(&c, &dlen)) == NULL) {
- error("Certificate constraints corrupt");
+ error("Certificate options corrupt");
goto out;
}
buffer_append(&data, data_blob, dlen);
- debug3("found certificate constraint \"%.100s\" len %u",
+ debug3("found certificate option \"%.100s\" len %u",
name, dlen);
if (strlen(name) != nlen) {
error("Certificate constraint name contains \\0");
goto out;
}
- if (strcmp(name, "permit-X11-forwarding") == 0)
- cert_no_x11_forwarding_flag = 0;
- else if (strcmp(name, "permit-agent-forwarding") == 0)
- cert_no_agent_forwarding_flag = 0;
- else if (strcmp(name, "permit-port-forwarding") == 0)
- cert_no_port_forwarding_flag = 0;
- else if (strcmp(name, "permit-pty") == 0)
- cert_no_pty_flag = 0;
- else if (strcmp(name, "permit-user-rc") == 0)
- cert_no_user_rc = 0;
- else if (strcmp(name, "force-command") == 0) {
- char *command = buffer_get_string_ret(&data, &clen);
-
- if (command == NULL) {
- error("Certificate constraint \"%s\" corrupt",
- name);
- goto out;
+ found = 0;
+ if ((which & OPTIONS_EXTENSIONS) != 0) {
+ if (strcmp(name, "permit-X11-forwarding") == 0) {
+ *cert_no_x11_forwarding_flag = 0;
+ found = 1;
+ } else if (strcmp(name,
+ "permit-agent-forwarding") == 0) {
+ *cert_no_agent_forwarding_flag = 0;
+ found = 1;
+ } else if (strcmp(name,
+ "permit-port-forwarding") == 0) {
+ *cert_no_port_forwarding_flag = 0;
+ found = 1;
+ } else if (strcmp(name, "permit-pty") == 0) {
+ *cert_no_pty_flag = 0;
+ found = 1;
+ } else if (strcmp(name, "permit-user-rc") == 0) {
+ *cert_no_user_rc = 0;
+ found = 1;
}
- if (strlen(command) != clen) {
- error("force-command constraint contains \\0");
- goto out;
- }
- if (cert_forced_command != NULL) {
- error("Certificate has multiple "
- "force-command constraints");
- xfree(command);
- goto out;
- }
- cert_forced_command = command;
- } else if (strcmp(name, "source-address") == 0) {
- char *allowed = buffer_get_string_ret(&data, &clen);
- const char *remote_ip = get_remote_ipaddr();
-
- if (allowed == NULL) {
- error("Certificate constraint \"%s\" corrupt",
- name);
- goto out;
- }
- if (strlen(allowed) != clen) {
- error("source-address constraint contains \\0");
- goto out;
- }
- if (cert_source_address_done++) {
- error("Certificate has multiple "
- "source-address constraints");
- xfree(allowed);
- goto out;
+ }
+ if (!found && (which & OPTIONS_CRITICAL) != 0) {
+ if (strcmp(name, "force-command") == 0) {
+ if ((command = buffer_get_string_ret(&data,
+ &clen)) == NULL) {
+ error("Certificate constraint \"%s\" "
+ "corrupt", name);
+ goto out;
+ }
+ if (strlen(command) != clen) {
+ error("force-command constraint "
+ "contains \\0");
+ goto out;
+ }
+ if (*cert_forced_command != NULL) {
+ error("Certificate has multiple "
+ "force-command options");
+ xfree(command);
+ goto out;
+ }
+ *cert_forced_command = command;
+ found = 1;
}
- switch (addr_match_cidr_list(remote_ip, allowed)) {
- case 1:
- /* accepted */
- xfree(allowed);
- break;
- case 0:
- /* no match */
- logit("Authentication tried for %.100s with "
- "valid certificate but not from a "
- "permitted host (ip=%.200s).",
- pw->pw_name, remote_ip);
- auth_debug_add("Your address '%.200s' is not "
- "permitted to use this certificate for "
- "login.", remote_ip);
- xfree(allowed);
- goto out;
- case -1:
- error("Certificate source-address contents "
- "invalid");
- xfree(allowed);
- goto out;
+ if (strcmp(name, "source-address") == 0) {
+ if ((allowed = buffer_get_string_ret(&data,
+ &clen)) == NULL) {
+ error("Certificate constraint "
+ "\"%s\" corrupt", name);
+ goto out;
+ }
+ if (strlen(allowed) != clen) {
+ error("source-address constraint "
+ "contains \\0");
+ goto out;
+ }
+ if ((*cert_source_address_done)++) {
+ error("Certificate has multiple "
+ "source-address options");
+ xfree(allowed);
+ goto out;
+ }
+ remote_ip = get_remote_ipaddr();
+ switch (addr_match_cidr_list(remote_ip,
+ allowed)) {
+ case 1:
+ /* accepted */
+ xfree(allowed);
+ break;
+ case 0:
+ /* no match */
+ logit("Authentication tried for %.100s "
+ "with valid certificate but not "
+ "from a permitted host "
+ "(ip=%.200s).", pw->pw_name,
+ remote_ip);
+ auth_debug_add("Your address '%.200s' "
+ "is not permitted to use this "
+ "certificate for login.",
+ remote_ip);
+ xfree(allowed);
+ goto out;
+ case -1:
+ error("Certificate source-address "
+ "contents invalid");
+ xfree(allowed);
+ goto out;
+ }
+ found = 1;
}
- } else {
- error("Certificate constraint \"%s\" is not supported",
- name);
- goto out;
}
- if (buffer_len(&data) != 0) {
- error("Certificate constraint \"%s\" corrupt "
+ if (!found) {
+ if (crit) {
+ error("Certificate critical option \"%s\" "
+ "is not supported", name);
+ goto out;
+ } else {
+ logit("Certificate extension \"%s\" "
+ "is not supported", name);
+ }
+ } else if (buffer_len(&data) != 0) {
+ error("Certificate option \"%s\" corrupt "
"(extra data)", name);
goto out;
}
@@ -501,10 +566,73 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw)
xfree(data_blob);
name = data_blob = NULL;
}
-
- /* successfully parsed all constraints */
+ /* successfully parsed all options */
ret = 0;
+ out:
+ if (ret != 0 &&
+ cert_forced_command != NULL &&
+ *cert_forced_command != NULL) {
+ xfree(*cert_forced_command);
+ *cert_forced_command = NULL;
+ }
+ if (name != NULL)
+ xfree(name);
+ if (data_blob != NULL)
+ xfree(data_blob);
+ buffer_free(&data);
+ buffer_free(&c);
+ return ret;
+}
+
+/*
+ * Set options from critical certificate options. These supersede user key
+ * options so this must be called after auth_parse_options().
+ */
+int
+auth_cert_options(Key *k, struct passwd *pw)
+{
+ int cert_no_port_forwarding_flag = 1;
+ int cert_no_agent_forwarding_flag = 1;
+ int cert_no_x11_forwarding_flag = 1;
+ int cert_no_pty_flag = 1;
+ int cert_no_user_rc = 1;
+ char *cert_forced_command = NULL;
+ int cert_source_address_done = 0;
+
+ if (key_cert_is_legacy(k)) {
+ /* All options are in the one field for v00 certs */
+ if (parse_option_list(buffer_ptr(&k->cert->critical),
+ buffer_len(&k->cert->critical), pw,
+ OPTIONS_CRITICAL|OPTIONS_EXTENSIONS, 1,
+ &cert_no_port_forwarding_flag,
+ &cert_no_agent_forwarding_flag,
+ &cert_no_x11_forwarding_flag,
+ &cert_no_pty_flag,
+ &cert_no_user_rc,
+ &cert_forced_command,
+ &cert_source_address_done) == -1)
+ return -1;
+ } else {
+ /* Separate options and extensions for v01 certs */
+ if (parse_option_list(buffer_ptr(&k->cert->critical),
+ buffer_len(&k->cert->critical), pw,
+ OPTIONS_CRITICAL, 1, NULL, NULL, NULL, NULL, NULL,
+ &cert_forced_command,
+ &cert_source_address_done) == -1)
+ return -1;
+ if (parse_option_list(buffer_ptr(&k->cert->extensions),
+ buffer_len(&k->cert->extensions), pw,
+ OPTIONS_EXTENSIONS, 1,
+ &cert_no_port_forwarding_flag,
+ &cert_no_agent_forwarding_flag,
+ &cert_no_x11_forwarding_flag,
+ &cert_no_pty_flag,
+ &cert_no_user_rc,
+ NULL, NULL) == -1)
+ return -1;
+ }
+
no_port_forwarding_flag |= cert_no_port_forwarding_flag;
no_agent_forwarding_flag |= cert_no_agent_forwarding_flag;
no_x11_forwarding_flag |= cert_no_x11_forwarding_flag;
@@ -516,14 +644,6 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw)
xfree(forced_command);
forced_command = cert_forced_command;
}
-
- out:
- if (name != NULL)
- xfree(name);
- if (data_blob != NULL)
- xfree(data_blob);
- buffer_free(&data);
- buffer_free(&c);
- return ret;
+ return 0;
}
diff --git a/auth-options.h b/auth-options.h
index 694edc842b34..7455c945465a 100644
--- a/auth-options.h
+++ b/auth-options.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-options.h,v 1.18 2010/02/26 20:29:54 djm Exp $ */
+/* $OpenBSD: auth-options.h,v 1.20 2010/05/07 11:30:29 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -31,9 +31,10 @@ extern char *forced_command;
extern struct envstring *custom_environment;
extern int forced_tun_device;
extern int key_is_cert_authority;
+extern char *authorized_principals;
int auth_parse_options(struct passwd *, char *, char *, u_long);
void auth_clear_options(void);
-int auth_cert_constraints(Buffer *, struct passwd *);
+int auth_cert_options(Key *, struct passwd *);
#endif
diff --git a/auth-rsa.c b/auth-rsa.c
index 65571a890b46..56702d130f9c 100644
--- a/auth-rsa.c
+++ b/auth-rsa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-rsa.c,v 1.74 2010/03/04 10:36:03 djm Exp $ */
+/* $OpenBSD: auth-rsa.c,v 1.78 2010/07/13 23:13:16 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -34,11 +34,11 @@
#include "uidswap.h"
#include "match.h"
#include "buffer.h"
-#include "auth-options.h"
#include "pathnames.h"
#include "log.h"
#include "servconf.h"
#include "key.h"
+#include "auth-options.h"
#include "hostfile.h"
#include "auth.h"
#ifdef GSSAPI
@@ -116,7 +116,7 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16])
MD5_Final(mdbuf, &md);
/* Verify that the response is the original challenge. */
- if (memcmp(response, mdbuf, 16) != 0) {
+ if (timingsafe_bcmp(response, mdbuf, 16) != 0) {
/* Wrong answer. */
return (0);
}
@@ -256,7 +256,8 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
*/
if (!auth_parse_options(pw, key_options, file, linenum))
continue;
-
+ if (key_is_cert_authority)
+ continue;
/* break out, this key is allowed */
allowed = 1;
break;
diff --git a/auth.c b/auth.c
index 89a9360684b4..dba1e6555ebd 100644
--- a/auth.c
+++ b/auth.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.c,v 1.86 2010/03/05 02:58:11 djm Exp $ */
+/* $OpenBSD: auth.c,v 1.89 2010/08/04 05:42:47 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -143,7 +143,7 @@ allowed_user(struct passwd * pw)
locked = 1;
#endif
#ifdef USE_LIBIAF
- free(passwd);
+ free((void *) passwd);
#endif /* USE_LIBIAF */
if (locked) {
logit("User %.100s not allowed because account is locked",
@@ -366,6 +366,14 @@ authorized_keys_file2(struct passwd *pw)
return expand_authorized_keys(options.authorized_keys_file2, pw);
}
+char *
+authorized_principals_file(struct passwd *pw)
+{
+ if (options.authorized_principals_file == NULL)
+ return NULL;
+ return expand_authorized_keys(options.authorized_principals_file, pw);
+}
+
/* return ok if key exists in sysfile or userfile */
HostStatus
check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
@@ -377,7 +385,7 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
HostStatus host_status;
/* Check if we know the host and its host key. */
- found = key_new(key->type);
+ found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
host_status = check_host_in_hostfile(sysfile, host, key, found, NULL);
if (host_status != HOST_OK && userfile != NULL) {
@@ -389,6 +397,8 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
logit("Authentication refused for %.100s: "
"bad owner or modes for %.200s",
pw->pw_name, user_hostfile);
+ auth_debug_add("Ignored %.200s: bad ownership or modes",
+ user_hostfile);
} else {
temporarily_use_uid(pw);
host_status = check_host_in_hostfile(user_hostfile,
@@ -477,21 +487,18 @@ secure_filename(FILE *f, const char *file, struct passwd *pw,
return 0;
}
-FILE *
-auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes)
+static FILE *
+auth_openfile(const char *file, struct passwd *pw, int strict_modes,
+ int log_missing, char *file_type)
{
char line[1024];
struct stat st;
int fd;
FILE *f;
- /*
- * Open the file containing the authorized keys
- * Fail quietly if file does not exist
- */
if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) {
- if (errno != ENOENT)
- debug("Could not open keyfile '%s': %s", file,
+ if (log_missing || errno != ENOENT)
+ debug("Could not open %s '%s': %s", file_type, file,
strerror(errno));
return NULL;
}
@@ -501,8 +508,8 @@ auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes)
return NULL;
}
if (!S_ISREG(st.st_mode)) {
- logit("User %s authorized keys %s is not a regular file",
- pw->pw_name, file);
+ logit("User %s %s %s is not a regular file",
+ pw->pw_name, file_type, file);
close(fd);
return NULL;
}
@@ -515,12 +522,27 @@ auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes)
secure_filename(f, file, pw, line, sizeof(line)) != 0) {
fclose(f);
logit("Authentication refused: %s", line);
+ auth_debug_add("Ignored %s: %s", file_type, line);
return NULL;
}
return f;
}
+
+FILE *
+auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes)
+{
+ return auth_openfile(file, pw, strict_modes, 1, "authorized keys");
+}
+
+FILE *
+auth_openprincipals(const char *file, struct passwd *pw, int strict_modes)
+{
+ return auth_openfile(file, pw, strict_modes, 0,
+ "authorized principals");
+}
+
struct passwd *
getpwnamallow(const char *user)
{
diff --git a/auth.h b/auth.h
index a65b87dd126e..77317aee6dbf 100644
--- a/auth.h
+++ b/auth.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.h,v 1.65 2010/03/04 10:36:03 djm Exp $ */
+/* $OpenBSD: auth.h,v 1.66 2010/05/07 11:30:29 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -169,8 +169,10 @@ void abandon_challenge_response(Authctxt *);
char *authorized_keys_file(struct passwd *);
char *authorized_keys_file2(struct passwd *);
+char *authorized_principals_file(struct passwd *);
FILE *auth_openkeyfile(const char *, struct passwd *, int);
+FILE *auth_openprincipals(const char *, struct passwd *, int);
int auth_key_is_revoked(Key *);
HostStatus
diff --git a/auth1.c b/auth1.c
index 1801661fdda8..bf442dbf6e7b 100644
--- a/auth1.c
+++ b/auth1.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth1.c,v 1.73 2008/07/04 23:30:16 djm Exp $ */
+/* $OpenBSD: auth1.c,v 1.74 2010/06/25 08:46:17 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -244,7 +244,7 @@ do_authloop(Authctxt *authctxt)
authctxt->valid ? "" : "invalid user ", authctxt->user);
/* If the user has no password, accept authentication immediately. */
- if (options.password_authentication &&
+ if (options.permit_empty_passwd && options.password_authentication &&
#ifdef KRB5
(!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
#endif
diff --git a/auth2-hostbased.c b/auth2-hostbased.c
index 721646520fec..cdf442f97c2c 100644
--- a/auth2-hostbased.c
+++ b/auth2-hostbased.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-hostbased.c,v 1.13 2010/03/04 10:36:03 djm Exp $ */
+/* $OpenBSD: auth2-hostbased.c,v 1.14 2010/08/04 05:42:47 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -141,9 +141,10 @@ int
hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
Key *key)
{
- const char *resolvedname, *ipaddr, *lookup;
+ const char *resolvedname, *ipaddr, *lookup, *reason;
HostStatus host_status;
int len;
+ char *fp;
if (auth_key_is_revoked(key))
return 0;
@@ -174,16 +175,40 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
}
debug2("userauth_hostbased: access allowed by auth_rhosts2");
+ if (key_is_cert(key) &&
+ key_cert_check_authority(key, 1, 0, lookup, &reason)) {
+ error("%s", reason);
+ auth_debug_add("%s", reason);
+ return 0;
+ }
+
host_status = check_key_in_hostfiles(pw, key, lookup,
_PATH_SSH_SYSTEM_HOSTFILE,
options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE);
/* backward compat if no key has been found. */
- if (host_status == HOST_NEW)
+ if (host_status == HOST_NEW) {
host_status = check_key_in_hostfiles(pw, key, lookup,
_PATH_SSH_SYSTEM_HOSTFILE2,
options.ignore_user_known_hosts ? NULL :
_PATH_SSH_USER_HOSTFILE2);
+ }
+
+ if (host_status == HOST_OK) {
+ if (key_is_cert(key)) {
+ fp = key_fingerprint(key->cert->signature_key,
+ SSH_FP_MD5, SSH_FP_HEX);
+ verbose("Accepted certificate ID \"%s\" signed by "
+ "%s CA %s from %s@%s", key->cert->key_id,
+ key_type(key->cert->signature_key), fp,
+ cuser, lookup);
+ } else {
+ fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
+ verbose("Accepted %s public key %s from %s@%s",
+ key_type(key), fp, cuser, lookup);
+ }
+ xfree(fp);
+ }
return (host_status == HOST_OK);
}
diff --git a/auth2-none.c b/auth2-none.c
index 08f2f935fe98..c8c6c74a9347 100644
--- a/auth2-none.c
+++ b/auth2-none.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-none.c,v 1.15 2008/07/02 12:36:39 djm Exp $ */
+/* $OpenBSD: auth2-none.c,v 1.16 2010/06/25 08:46:17 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -61,7 +61,7 @@ userauth_none(Authctxt *authctxt)
{
none_enabled = 0;
packet_check_eom();
- if (options.password_authentication)
+ if (options.permit_empty_passwd && options.password_authentication)
return (PRIVSEP(auth_password(authctxt, "")));
return (0);
}
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index c4cadf4e78c2..35cf79c9f783 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-pubkey.c,v 1.22 2010/03/10 23:27:17 djm Exp $ */
+/* $OpenBSD: auth2-pubkey.c,v 1.26 2010/06/29 23:16:46 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -57,6 +57,7 @@
#include "monitor_wrap.h"
#include "misc.h"
#include "authfile.h"
+#include "match.h"
/* import */
extern ServerOptions options;
@@ -176,6 +177,83 @@ done:
return authenticated;
}
+static int
+match_principals_option(const char *principal_list, struct KeyCert *cert)
+{
+ char *result;
+ u_int i;
+
+ /* XXX percent_expand() sequences for authorized_principals? */
+
+ for (i = 0; i < cert->nprincipals; i++) {
+ if ((result = match_list(cert->principals[i],
+ principal_list, NULL)) != NULL) {
+ debug3("matched principal from key options \"%.100s\"",
+ result);
+ xfree(result);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int
+match_principals_file(char *file, struct passwd *pw, struct KeyCert *cert)
+{
+ FILE *f;
+ char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts;
+ u_long linenum = 0;
+ u_int i;
+
+ temporarily_use_uid(pw);
+ debug("trying authorized principals file %s", file);
+ if ((f = auth_openprincipals(file, pw, options.strict_modes)) == NULL) {
+ restore_uid();
+ return 0;
+ }
+ while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
+ /* Skip leading whitespace. */
+ for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
+ ;
+ /* Skip blank and comment lines. */
+ if ((ep = strchr(cp, '#')) != NULL)
+ *ep = '\0';
+ if (!*cp || *cp == '\n')
+ continue;
+ /* Trim trailing whitespace. */
+ ep = cp + strlen(cp) - 1;
+ while (ep > cp && (*ep == '\n' || *ep == ' ' || *ep == '\t'))
+ *ep-- = '\0';
+ /*
+ * If the line has internal whitespace then assume it has
+ * key options.
+ */
+ line_opts = NULL;
+ if ((ep = strrchr(cp, ' ')) != NULL ||
+ (ep = strrchr(cp, '\t')) != NULL) {
+ for (; *ep == ' ' || *ep == '\t'; ep++)
+ ;;
+ line_opts = cp;
+ cp = ep;
+ }
+ for (i = 0; i < cert->nprincipals; i++) {
+ if (strcmp(cp, cert->principals[i]) == 0) {
+ debug3("matched principal from file \"%.100s\"",
+ cert->principals[i]);
+ if (auth_parse_options(pw, line_opts,
+ file, linenum) != 1)
+ continue;
+ fclose(f);
+ restore_uid();
+ return 1;
+ }
+ }
+ }
+ fclose(f);
+ restore_uid();
+ return 0;
+}
+
/* return 1 if user allows given key */
static int
user_key_allowed2(struct passwd *pw, Key *key, char *file)
@@ -233,26 +311,39 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
continue;
}
}
- if (auth_parse_options(pw, key_options, file, linenum) != 1)
- continue;
- if (key->type == KEY_RSA_CERT || key->type == KEY_DSA_CERT) {
- if (!key_is_cert_authority)
- continue;
+ if (key_is_cert(key)) {
if (!key_equal(found, key->cert->signature_key))
continue;
+ if (auth_parse_options(pw, key_options, file,
+ linenum) != 1)
+ continue;
+ if (!key_is_cert_authority)
+ continue;
fp = key_fingerprint(found, SSH_FP_MD5,
SSH_FP_HEX);
debug("matching CA found: file %s, line %lu, %s %s",
file, linenum, key_type(found), fp);
- if (key_cert_check_authority(key, 0, 0, pw->pw_name,
- &reason) != 0) {
+ /*
+ * If the user has specified a list of principals as
+ * a key option, then prefer that list to matching
+ * their username in the certificate principals list.
+ */
+ if (authorized_principals != NULL &&
+ !match_principals_option(authorized_principals,
+ key->cert)) {
+ reason = "Certificate does not contain an "
+ "authorized principal";
+ fail_reason:
xfree(fp);
error("%s", reason);
auth_debug_add("%s", reason);
continue;
}
- if (auth_cert_constraints(&key->cert->constraints,
- pw) != 0) {
+ if (key_cert_check_authority(key, 0, 0,
+ authorized_principals == NULL ? pw->pw_name : NULL,
+ &reason) != 0)
+ goto fail_reason;
+ if (auth_cert_options(key, pw) != 0) {
xfree(fp);
continue;
}
@@ -262,7 +353,12 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
xfree(fp);
found_key = 1;
break;
- } else if (!key_is_cert_authority && key_equal(found, key)) {
+ } else if (key_equal(found, key)) {
+ if (auth_parse_options(pw, key_options, file,
+ linenum) != 1)
+ continue;
+ if (key_is_cert_authority)
+ continue;
found_key = 1;
debug("matching key found: file %s, line %lu",
file, linenum);
@@ -285,7 +381,7 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
static int
user_cert_trusted_ca(struct passwd *pw, Key *key)
{
- char *ca_fp;
+ char *ca_fp, *principals_file = NULL;
const char *reason;
int ret = 0;
@@ -302,12 +398,25 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
options.trusted_user_ca_keys);
goto out;
}
- if (key_cert_check_authority(key, 0, 1, pw->pw_name, &reason) != 0) {
- error("%s", reason);
- auth_debug_add("%s", reason);
- goto out;
+ /*
+ * If AuthorizedPrincipals is in use, then compare the certificate
+ * principals against the names in that file rather than matching
+ * against the username.
+ */
+ if ((principals_file = authorized_principals_file(pw)) != NULL) {
+ if (!match_principals_file(principals_file, pw, key->cert)) {
+ reason = "Certificate does not contain an "
+ "authorized principal";
+ fail_reason:
+ error("%s", reason);
+ auth_debug_add("%s", reason);
+ goto out;
+ }
}
- if (auth_cert_constraints(&key->cert->constraints, pw) != 0)
+ if (key_cert_check_authority(key, 0, 1,
+ principals_file == NULL ? pw->pw_name : NULL, &reason) != 0)
+ goto fail_reason;
+ if (auth_cert_options(key, pw) != 0)
goto out;
verbose("Accepted certificate ID \"%s\" signed by %s CA %s via %s",
@@ -316,6 +425,8 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
ret = 1;
out:
+ if (principals_file != NULL)
+ xfree(principals_file);
if (ca_fp != NULL)
xfree(ca_fp);
return ret;
diff --git a/authfd.c b/authfd.c
index 28a8cf2d7d80..739722fbfba8 100644
--- a/authfd.c
+++ b/authfd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfd.c,v 1.82 2010/02/26 20:29:54 djm Exp $ */
+/* $OpenBSD: authfd.c,v 1.83 2010/04/16 01:47:26 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -483,6 +483,7 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
buffer_put_bignum2(b, key->rsa->p);
buffer_put_bignum2(b, key->rsa->q);
break;
+ case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
fatal("%s: no cert/certblob", __func__);
@@ -500,6 +501,7 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
buffer_put_bignum2(b, key->dsa->pub_key);
buffer_put_bignum2(b, key->dsa->priv_key);
break;
+ case KEY_DSA_CERT_V00:
case KEY_DSA_CERT:
if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
fatal("%s: no cert/certblob", __func__);
@@ -535,8 +537,10 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key,
break;
case KEY_RSA:
case KEY_RSA_CERT:
+ case KEY_RSA_CERT_V00:
case KEY_DSA:
case KEY_DSA_CERT:
+ case KEY_DSA_CERT_V00:
type = constrained ?
SSH2_AGENTC_ADD_ID_CONSTRAINED :
SSH2_AGENTC_ADD_IDENTITY;
diff --git a/authfile.c b/authfile.c
index 224c6aa806fa..2bd887845cc0 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfile.c,v 1.80 2010/03/04 10:36:03 djm Exp $ */
+/* $OpenBSD: authfile.c,v 1.82 2010/08/04 05:49:22 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -693,6 +693,66 @@ key_load_public(const char *filename, char **commentp)
return NULL;
}
+/* Load the certificate associated with the named private key */
+Key *
+key_load_cert(const char *filename)
+{
+ Key *pub;
+ char *file;
+
+ pub = key_new(KEY_UNSPEC);
+ xasprintf(&file, "%s-cert.pub", filename);
+ if (key_try_load_public(pub, file, NULL) == 1) {
+ xfree(file);
+ return pub;
+ }
+ xfree(file);
+ key_free(pub);
+ return NULL;
+}
+
+/* Load private key and certificate */
+Key *
+key_load_private_cert(int type, const char *filename, const char *passphrase,
+ int *perm_ok)
+{
+ Key *key, *pub;
+
+ switch (type) {
+ case KEY_RSA:
+ case KEY_DSA:
+ break;
+ default:
+ error("%s: unsupported key type", __func__);
+ return NULL;
+ }
+
+ if ((key = key_load_private_type(type, filename,
+ passphrase, NULL, perm_ok)) == NULL)
+ return NULL;
+
+ if ((pub = key_load_cert(filename)) == NULL) {
+ key_free(key);
+ return NULL;
+ }
+
+ /* Make sure the private key matches the certificate */
+ if (key_equal_public(key, pub) == 0) {
+ error("%s: certificate does not match private key %s",
+ __func__, filename);
+ } else if (key_to_certified(key, key_cert_is_legacy(pub)) != 0) {
+ error("%s: key_to_certified failed", __func__);
+ } else {
+ key_cert_copy(pub, key);
+ key_free(pub);
+ return key;
+ }
+
+ key_free(key);
+ key_free(pub);
+ return NULL;
+}
+
/*
* Returns 1 if the specified "key" is listed in the file "filename",
* 0 if the key is not listed or -1 on error.
diff --git a/authfile.h b/authfile.h
index 6dfa478e76eb..6745dc062be1 100644
--- a/authfile.h
+++ b/authfile.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfile.h,v 1.14 2010/03/04 10:36:03 djm Exp $ */
+/* $OpenBSD: authfile.h,v 1.15 2010/08/04 05:42:47 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 *);
+Key *key_load_cert(const char *);
Key *key_load_public(const char *, char **);
Key *key_load_public_type(int, 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 *);
Key *key_load_private_pem(int, int, const char *, char **);
int key_perm_ok(int, const char *);
diff --git a/bufaux.c b/bufaux.c
index 4ef19c454b16..854fd510a967 100644
--- a/bufaux.c
+++ b/bufaux.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bufaux.c,v 1.48 2010/02/02 22:49:34 djm Exp $ */
+/* $OpenBSD: bufaux.c,v 1.49 2010/03/26 03:13:17 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -84,7 +84,8 @@ buffer_get_int_ret(u_int *ret, Buffer *buffer)
if (buffer_get_ret(buffer, (char *) buf, 4) == -1)
return (-1);
- *ret = get_u32(buf);
+ if (ret != NULL)
+ *ret = get_u32(buf);
return (0);
}
@@ -106,7 +107,8 @@ buffer_get_int64_ret(u_int64_t *ret, Buffer *buffer)
if (buffer_get_ret(buffer, (char *) buf, 8) == -1)
return (-1);
- *ret = get_u64(buf);
+ if (ret != NULL)
+ *ret = get_u64(buf);
return (0);
}
diff --git a/channels.c b/channels.c
index a55d27817573..1cd5004c47bb 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.c,v 1.303 2010/01/30 21:12:08 djm Exp $ */
+/* $OpenBSD: channels.c,v 1.309 2010/08/05 13:08:42 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -114,10 +114,10 @@ typedef struct {
} ForwardPermission;
/* List of all permitted host/port pairs to connect by the user. */
-static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
+static ForwardPermission *permitted_opens = NULL;
/* List of all permitted host/port pairs to connect by the admin. */
-static ForwardPermission permitted_adm_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
+static ForwardPermission *permitted_adm_opens = NULL;
/* Number of permitted host/port pairs in the array permitted by the user. */
static int num_permitted_opens = 0;
@@ -330,6 +330,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
c->ctl_chan = -1;
c->mux_rcb = NULL;
c->mux_ctx = NULL;
+ c->mux_pause = 0;
c->delayed = 1; /* prevent call to channel_post handler */
TAILQ_INIT(&c->status_confirms);
debug("channel %d: new [%s]", found, remote_name);
@@ -703,7 +704,7 @@ channel_register_status_confirm(int id, channel_confirm_cb *cb,
}
void
-channel_register_open_confirm(int id, channel_callback_fn *fn, void *ctx)
+channel_register_open_confirm(int id, channel_open_fn *fn, void *ctx)
{
Channel *c = channel_lookup(id);
@@ -838,8 +839,9 @@ channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
if (c->extended_usage == CHAN_EXTENDED_WRITE &&
buffer_len(&c->extended) > 0)
FD_SET(c->efd, writeset);
- else if (!(c->flags & CHAN_EOF_SENT) &&
- c->extended_usage == CHAN_EXTENDED_READ &&
+ else if (c->efd != -1 && !(c->flags & CHAN_EOF_SENT) &&
+ (c->extended_usage == CHAN_EXTENDED_READ ||
+ c->extended_usage == CHAN_EXTENDED_IGNORE) &&
buffer_len(&c->extended) < c->remote_window)
FD_SET(c->efd, readset);
}
@@ -915,7 +917,7 @@ x11_open_helper(Buffer *b)
}
/* Check if authentication data matches our fake data. */
if (data_len != x11_fake_data_len ||
- memcmp(ucp + 12 + ((proto_len + 3) & ~3),
+ timingsafe_bcmp(ucp + 12 + ((proto_len + 3) & ~3),
x11_fake_data, x11_fake_data_len) != 0) {
debug2("X11 auth data does not match fake data.");
return -1;
@@ -991,7 +993,7 @@ channel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset)
static void
channel_pre_mux_client(Channel *c, fd_set *readset, fd_set *writeset)
{
- if (c->istate == CHAN_INPUT_OPEN &&
+ if (c->istate == CHAN_INPUT_OPEN && !c->mux_pause &&
buffer_check_alloc(&c->input, CHAN_RBUF))
FD_SET(c->rfd, readset);
if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
@@ -1642,13 +1644,14 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
{
struct termios tio;
u_char *data = NULL, *buf;
- u_int dlen;
+ u_int dlen, olen = 0;
int len;
/* Send buffered output data to the socket. */
if (c->wfd != -1 &&
FD_ISSET(c->wfd, writeset) &&
buffer_len(&c->output) > 0) {
+ olen = buffer_len(&c->output);
if (c->output_filter != NULL) {
if ((buf = c->output_filter(c, &data, &dlen)) == NULL) {
debug2("channel %d: filter stops", c->self);
@@ -1667,7 +1670,6 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
if (c->datagram) {
/* ignore truncated writes, datagrams might get lost */
- c->local_consumed += dlen + 4;
len = write(c->wfd, buf, dlen);
xfree(data);
if (len < 0 && (errno == EINTR || errno == EAGAIN ||
@@ -1680,7 +1682,7 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
chan_write_failed(c);
return -1;
}
- return 1;
+ goto out;
}
#ifdef _AIX
/* XXX: Later AIX versions can't push as much data to tty */
@@ -1722,10 +1724,10 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
}
#endif
buffer_consume(&c->output, len);
- if (compat20 && len > 0) {
- c->local_consumed += len;
- }
}
+ out:
+ if (compat20 && olen > 0)
+ c->local_consumed += olen - buffer_len(&c->output);
return 1;
}
@@ -1755,7 +1757,9 @@ channel_handle_efd(Channel *c, fd_set *readset, fd_set *writeset)
buffer_consume(&c->extended, len);
c->local_consumed += len;
}
- } else if (c->extended_usage == CHAN_EXTENDED_READ &&
+ } else if (c->efd != -1 &&
+ (c->extended_usage == CHAN_EXTENDED_READ ||
+ c->extended_usage == CHAN_EXTENDED_IGNORE) &&
(c->detach_close || FD_ISSET(c->efd, readset))) {
len = read(c->efd, buf, sizeof(buf));
debug2("channel %d: read %d from efd %d",
@@ -1768,7 +1772,11 @@ channel_handle_efd(Channel *c, fd_set *readset, fd_set *writeset)
c->self, c->efd);
channel_close_fd(&c->efd);
} else {
- buffer_append(&c->extended, buf, len);
+ if (c->extended_usage == CHAN_EXTENDED_IGNORE) {
+ debug3("channel %d: discard efd",
+ c->self);
+ } else
+ buffer_append(&c->extended, buf, len);
}
}
}
@@ -1840,7 +1848,7 @@ channel_post_mux_client(Channel *c, fd_set *readset, fd_set *writeset)
if (!compat20)
fatal("%s: entered with !compat20", __func__);
- if (c->rfd != -1 && FD_ISSET(c->rfd, readset) &&
+ if (c->rfd != -1 && !c->mux_pause && FD_ISSET(c->rfd, readset) &&
(c->istate == CHAN_INPUT_OPEN ||
c->istate == CHAN_INPUT_WAIT_DRAIN)) {
/*
@@ -2164,6 +2172,14 @@ channel_output_poll(void)
data = buffer_get_string(&c->input,
&dlen);
+ if (dlen > c->remote_window ||
+ dlen > c->remote_maxpacket) {
+ debug("channel %d: datagram "
+ "too big for channel",
+ c->self);
+ xfree(data);
+ continue;
+ }
packet_start(SSH2_MSG_CHANNEL_DATA);
packet_put_int(c->remote_id);
packet_put_string(data, dlen);
@@ -2249,7 +2265,7 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
{
int id;
char *data;
- u_int data_len;
+ u_int data_len, win_len;
Channel *c;
/* Get the channel number and verify it. */
@@ -2265,6 +2281,9 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
/* Get the data. */
data = packet_get_string_ptr(&data_len);
+ win_len = data_len;
+ if (c->datagram)
+ win_len += 4; /* string length header */
/*
* Ignore data for protocol > 1.3 if output end is no longer open.
@@ -2275,23 +2294,23 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
*/
if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN) {
if (compat20) {
- c->local_window -= data_len;
- c->local_consumed += data_len;
+ c->local_window -= win_len;
+ c->local_consumed += win_len;
}
return;
}
if (compat20) {
- if (data_len > c->local_maxpacket) {
+ if (win_len > c->local_maxpacket) {
logit("channel %d: rcvd big packet %d, maxpack %d",
- c->self, data_len, c->local_maxpacket);
+ c->self, win_len, c->local_maxpacket);
}
- if (data_len > c->local_window) {
+ if (win_len > c->local_window) {
logit("channel %d: rcvd too much data %d, win %d",
- c->self, data_len, c->local_window);
+ c->self, win_len, c->local_window);
return;
}
- c->local_window -= data_len;
+ c->local_window -= win_len;
}
if (c->datagram)
buffer_put_string(&c->output, data, data_len);
@@ -2463,7 +2482,7 @@ channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt)
c->remote_maxpacket = packet_get_int();
if (c->open_confirm) {
debug2("callback start");
- c->open_confirm(c->self, c->open_confirm_ctx);
+ c->open_confirm(c->self, 1, c->open_confirm_ctx);
debug2("callback done");
}
debug2("channel %d: open confirm rwindow %u rmax %u", c->self,
@@ -2514,6 +2533,11 @@ channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
xfree(msg);
if (lang != NULL)
xfree(lang);
+ if (c->open_confirm) {
+ debug2("callback start");
+ c->open_confirm(c->self, 0, c->open_confirm_ctx);
+ debug2("callback done");
+ }
}
packet_check_eom();
/* Schedule the channel for cleanup/deletion. */
@@ -2832,10 +2856,6 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
{
int type, success = 0;
- /* Record locally that connection to this host/port is permitted. */
- if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
- fatal("channel_request_remote_forwarding: too many forwards");
-
/* Send the forward request to the remote side. */
if (compat20) {
const char *address_to_bind;
@@ -2885,6 +2905,9 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
}
}
if (success) {
+ /* Record that connection to this host/port is permitted. */
+ permitted_opens = xrealloc(permitted_opens,
+ num_permitted_opens + 1, sizeof(*permitted_opens));
permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host_to_connect);
permitted_opens[num_permitted_opens].port_to_connect = port_to_connect;
permitted_opens[num_permitted_opens].listen_port = listen_port;
@@ -2982,10 +3005,10 @@ channel_permit_all_opens(void)
void
channel_add_permitted_opens(char *host, int port)
{
- if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
- fatal("channel_add_permitted_opens: too many forwards");
debug("allow port forwarding to host %s port %d", host, port);
+ permitted_opens = xrealloc(permitted_opens,
+ num_permitted_opens + 1, sizeof(*permitted_opens));
permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host);
permitted_opens[num_permitted_opens].port_to_connect = port;
num_permitted_opens++;
@@ -2996,10 +3019,10 @@ channel_add_permitted_opens(char *host, int port)
int
channel_add_adm_permitted_opens(char *host, int port)
{
- if (num_adm_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
- fatal("channel_add_adm_permitted_opens: too many forwards");
debug("config allows port forwarding to host %s port %d", host, port);
+ permitted_adm_opens = xrealloc(permitted_adm_opens,
+ num_adm_permitted_opens + 1, sizeof(*permitted_adm_opens));
permitted_adm_opens[num_adm_permitted_opens].host_to_connect
= xstrdup(host);
permitted_adm_opens[num_adm_permitted_opens].port_to_connect = port;
@@ -3014,6 +3037,10 @@ channel_clear_permitted_opens(void)
for (i = 0; i < num_permitted_opens; i++)
if (permitted_opens[i].host_to_connect != NULL)
xfree(permitted_opens[i].host_to_connect);
+ if (num_permitted_opens > 0) {
+ xfree(permitted_opens);
+ permitted_opens = NULL;
+ }
num_permitted_opens = 0;
}
@@ -3025,6 +3052,10 @@ channel_clear_adm_permitted_opens(void)
for (i = 0; i < num_adm_permitted_opens; i++)
if (permitted_adm_opens[i].host_to_connect != NULL)
xfree(permitted_adm_opens[i].host_to_connect);
+ if (num_adm_permitted_opens > 0) {
+ xfree(permitted_adm_opens);
+ permitted_adm_opens = NULL;
+ }
num_adm_permitted_opens = 0;
}
diff --git a/channels.h b/channels.h
index cc71885f4945..0680ed00e465 100644
--- a/channels.h
+++ b/channels.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.h,v 1.103 2010/01/26 01:28:35 djm Exp $ */
+/* $OpenBSD: channels.h,v 1.104 2010/05/14 23:29:23 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -60,6 +60,7 @@
struct Channel;
typedef struct Channel Channel;
+typedef void channel_open_fn(int, int, void *);
typedef void channel_callback_fn(int, void *);
typedef int channel_infilter_fn(struct Channel *, char *, int);
typedef void channel_filter_cleanup_fn(int, void *);
@@ -130,7 +131,7 @@ struct Channel {
char *ctype; /* type */
/* callback */
- channel_callback_fn *open_confirm;
+ channel_open_fn *open_confirm;
void *open_confirm_ctx;
channel_callback_fn *detach_user;
int detach_close;
@@ -151,6 +152,7 @@ struct Channel {
/* multiplexing protocol hook, called for each packet received */
mux_callback_fn *mux_rcb;
void *mux_ctx;
+ int mux_pause;
};
#define CHAN_EXTENDED_IGNORE 0
@@ -208,7 +210,7 @@ void channel_stop_listening(void);
void channel_send_open(int);
void channel_request_start(int, char *, int);
void channel_register_cleanup(int, channel_callback_fn *, int);
-void channel_register_open_confirm(int, channel_callback_fn *, void *);
+void channel_register_open_confirm(int, channel_open_fn *, void *);
void channel_register_filter(int, channel_infilter_fn *,
channel_outfilter_fn *, channel_filter_cleanup_fn *, void *);
void channel_register_status_confirm(int, channel_confirm_cb *,
diff --git a/clientloop.c b/clientloop.c
index 9ab56b44c477..de79793666af 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.c,v 1.219 2010/03/13 21:10:38 djm Exp $ */
+/* $OpenBSD: clientloop.c,v 1.222 2010/07/19 09:15:12 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -145,6 +145,9 @@ static volatile sig_atomic_t received_signal = 0;
/* Flag indicating whether the user's terminal is in non-blocking mode. */
static int in_non_blocking_mode = 0;
+/* Time when backgrounded control master using ControlPersist should exit */
+static time_t control_persist_exit_time = 0;
+
/* Common data for the client loop code. */
volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */
static int escape_char1; /* Escape character. (proto1 only) */
@@ -155,11 +158,12 @@ static int stdin_eof; /* EOF has been encountered on stderr. */
static Buffer stdin_buffer; /* Buffer for stdin data. */
static Buffer stdout_buffer; /* Buffer for stdout data. */
static Buffer stderr_buffer; /* Buffer for stderr data. */
-static u_int buffer_high;/* Soft max buffer size. */
+static u_int buffer_high; /* Soft max buffer size. */
static int connection_in; /* Connection to server (input). */
static int connection_out; /* Connection to server (output). */
static int need_rekeying; /* Set to non-zero if rekeying is requested. */
-static int session_closed = 0; /* In SSH2: login session closed. */
+static int session_closed; /* In SSH2: login session closed. */
+static int x11_refuse_time; /* If >0, refuse x11 opens after this time. */
static void client_init_dispatch(void);
int session_ident = -1;
@@ -251,10 +255,38 @@ get_current_time(void)
return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;
}
+/*
+ * Sets control_persist_exit_time to the absolute time when the
+ * backgrounded control master should exit due to expiry of the
+ * ControlPersist timeout. Sets it to 0 if we are not a backgrounded
+ * control master process, or if there is no ControlPersist timeout.
+ */
+static void
+set_control_persist_exit_time(void)
+{
+ if (muxserver_sock == -1 || !options.control_persist
+ || options.control_persist_timeout == 0)
+ /* not using a ControlPersist timeout */
+ control_persist_exit_time = 0;
+ else if (channel_still_open()) {
+ /* some client connections are still open */
+ if (control_persist_exit_time > 0)
+ debug2("%s: cancel scheduled exit", __func__);
+ control_persist_exit_time = 0;
+ } else if (control_persist_exit_time <= 0) {
+ /* a client connection has recently closed */
+ control_persist_exit_time = time(NULL) +
+ (time_t)options.control_persist_timeout;
+ debug2("%s: schedule exit in %d seconds", __func__,
+ options.control_persist_timeout);
+ }
+ /* else we are already counting down to the timeout */
+}
+
#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1"
void
client_x11_get_proto(const char *display, const char *xauth_path,
- u_int trusted, char **_proto, char **_data)
+ u_int trusted, u_int timeout, char **_proto, char **_data)
{
char cmd[1024];
char line[512];
@@ -264,6 +296,7 @@ client_x11_get_proto(const char *display, const char *xauth_path,
int got_data = 0, generated = 0, do_unlink = 0, i;
char *xauthdir, *xauthfile;
struct stat st;
+ u_int now;
xauthdir = xauthfile = NULL;
*_proto = proto;
@@ -299,11 +332,18 @@ client_x11_get_proto(const char *display, const char *xauth_path,
xauthdir);
snprintf(cmd, sizeof(cmd),
"%s -f %s generate %s " SSH_X11_PROTO
- " untrusted timeout 1200 2>" _PATH_DEVNULL,
- xauth_path, xauthfile, display);
+ " untrusted timeout %u 2>" _PATH_DEVNULL,
+ xauth_path, xauthfile, display, timeout);
debug2("x11_get_proto: %s", cmd);
if (system(cmd) == 0)
generated = 1;
+ if (x11_refuse_time == 0) {
+ now = time(NULL) + 1;
+ if (UINT_MAX - timeout < now)
+ x11_refuse_time = UINT_MAX;
+ else
+ x11_refuse_time = now + timeout;
+ }
}
}
@@ -524,6 +564,7 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
int *maxfdp, u_int *nallocp, int rekeying)
{
struct timeval tv, *tvp;
+ int timeout_secs;
int ret;
/* Add any selections by the channel mechanism. */
@@ -567,16 +608,27 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
/*
* Wait for something to happen. This will suspend the process until
* some selected descriptor can be read, written, or has some other
- * event pending.
+ * event pending, or a timeout expires.
*/
- if (options.server_alive_interval == 0 || !compat20)
+ timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */
+ if (options.server_alive_interval > 0 && compat20)
+ timeout_secs = options.server_alive_interval;
+ set_control_persist_exit_time();
+ if (control_persist_exit_time > 0) {
+ timeout_secs = MIN(timeout_secs,
+ control_persist_exit_time - time(NULL));
+ if (timeout_secs < 0)
+ timeout_secs = 0;
+ }
+ if (timeout_secs == INT_MAX)
tvp = NULL;
else {
- tv.tv_sec = options.server_alive_interval;
+ tv.tv_sec = timeout_secs;
tv.tv_usec = 0;
tvp = &tv;
}
+
ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp);
if (ret < 0) {
char buf[100];
@@ -1469,6 +1521,18 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
*/
if (FD_ISSET(connection_out, writeset))
packet_write_poll();
+
+ /*
+ * If we are a backgrounded control master, and the
+ * timeout has expired without any active client
+ * connections, then quit.
+ */
+ if (control_persist_exit_time > 0) {
+ if (time(NULL) >= control_persist_exit_time) {
+ debug("ControlPersist timeout expired");
+ break;
+ }
+ }
}
if (readset)
xfree(readset);
@@ -1686,6 +1750,11 @@ client_request_x11(const char *request_type, int rchan)
"malicious server.");
return NULL;
}
+ if (x11_refuse_time != 0 && time(NULL) >= x11_refuse_time) {
+ verbose("Rejected X11 connection after ForwardX11Timeout "
+ "expired");
+ return NULL;
+ }
originator = packet_get_string(NULL);
if (datafellows & SSH_BUG_X11FWD) {
debug2("buggy server: x11 request w/o originator_port");
@@ -1912,7 +1981,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", 0);
+ client_expect_confirm(id, "PTY allocation", 1);
packet_put_cstring(term != NULL ? term : "");
packet_put_int((u_int)ws.ws_col);
packet_put_int((u_int)ws.ws_row);
diff --git a/clientloop.h b/clientloop.h
index 0b8257b996c7..52115db6ec8d 100644
--- a/clientloop.h
+++ b/clientloop.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.h,v 1.23 2010/01/26 01:28:35 djm Exp $ */
+/* $OpenBSD: clientloop.h,v 1.25 2010/06/25 23:15:36 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -39,7 +39,7 @@
/* Client side main loop for the interactive session. */
int client_loop(int, int, int);
-void client_x11_get_proto(const char *, const char *, u_int,
+void client_x11_get_proto(const char *, const char *, u_int, u_int,
char **, char **);
void client_global_request_reply_fwd(int, u_int32_t, void *);
void client_session2_setup(int, int, int, const char *, struct termios *,
@@ -63,6 +63,7 @@ void client_register_global_confirm(global_confirm_cb *, void *);
#define SSHMUX_COMMAND_ALIVE_CHECK 2 /* Check master is alive */
#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 */
void muxserver_listen(void);
void muxclient(const char *);
diff --git a/config.h.in b/config.h.in
index a43ad57115d6..4ff407fcc020 100644
--- a/config.h.in
+++ b/config.h.in
@@ -900,6 +900,9 @@
/* Define to 1 if you have the `strnvis' function. */
#undef HAVE_STRNVIS
+/* Define to 1 if you have the `strptime' function. */
+#undef HAVE_STRPTIME
+
/* Define to 1 if you have the `strsep' function. */
#undef HAVE_STRSEP
diff --git a/configure b/configure
index 5ebdb15c610b..ef3bb0f0fa2d 100755
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.ac Revision: 1.449 .
+# From configure.ac Revision: 1.451 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.61 for OpenSSH Portable.
#
@@ -13078,6 +13078,7 @@ fi
+
for ac_func in \
arc4random \
arc4random_buf \
@@ -13158,6 +13159,7 @@ for ac_func in \
strlcpy \
strmode \
strnvis \
+ strptime \
strtonum \
strtoll \
strtoul \
@@ -16492,6 +16494,12 @@ if test "${with_ssl_dir+set}" = set; then
else
LDFLAGS="-L${withval}/lib ${LDFLAGS}"
fi
+ elif test -d "$withval/lib64"; then
+ if test -n "${need_dash_r}"; then
+ LDFLAGS="-L${withval}/lib64 -R${withval}/lib64 ${LDFLAGS}"
+ else
+ LDFLAGS="-L${withval}/lib64 ${LDFLAGS}"
+ fi
else
if test -n "${need_dash_r}"; then
LDFLAGS="-L${withval} -R${withval} ${LDFLAGS}"
diff --git a/configure.ac b/configure.ac
index 0a0e2ea15d0c..637e7b536fd4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-# $Id: configure.ac,v 1.449 2010/04/10 12:58:01 dtucker Exp $
+# $Id: configure.ac,v 1.451 2010/08/16 03:15:23 dtucker Exp $
#
# Copyright (c) 1999-2004 Damien Miller
#
@@ -15,7 +15,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org)
-AC_REVISION($Revision: 1.449 $)
+AC_REVISION($Revision: 1.451 $)
AC_CONFIG_SRCDIR([ssh.c])
AC_CONFIG_HEADER(config.h)
@@ -1427,6 +1427,7 @@ AC_CHECK_FUNCS( \
strlcpy \
strmode \
strnvis \
+ strptime \
strtonum \
strtoll \
strtoul \
@@ -1906,6 +1907,12 @@ AC_ARG_WITH(ssl-dir,
else
LDFLAGS="-L${withval}/lib ${LDFLAGS}"
fi
+ elif test -d "$withval/lib64"; then
+ if test -n "${need_dash_r}"; then
+ LDFLAGS="-L${withval}/lib64 -R${withval}/lib64 ${LDFLAGS}"
+ else
+ LDFLAGS="-L${withval}/lib64 ${LDFLAGS}"
+ fi
else
if test -n "${need_dash_r}"; then
LDFLAGS="-L${withval} -R${withval} ${LDFLAGS}"
diff --git a/contrib/aix/buildbff.sh b/contrib/aix/buildbff.sh
index 6648e8e6562a..ca4bf0210dc7 100755
--- a/contrib/aix/buildbff.sh
+++ b/contrib/aix/buildbff.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
# buildbff.sh: Create AIX SMIT-installable OpenSSH packages
-# $Id: buildbff.sh,v 1.11 2009/03/06 23:22:10 dtucker Exp $
+# $Id: buildbff.sh,v 1.12 2010/04/18 03:35:00 dtucker Exp $
#
# Author: Darren Tucker (dtucker at zip dot com dot au)
# This file is placed in the public domain and comes with absolutely
@@ -159,7 +159,7 @@ done
# AIX 5.3 and newer have /dev/random and don't create ssh_prng_cmds
if [ -f $FAKE_ROOT/$sysconfdir/ssh_prng_cmds ]
then
- mv FAKE_ROOT/$sysconfdir/ssh_prng_cmds \
+ mv $FAKE_ROOT/$sysconfdir/ssh_prng_cmds \
$FAKE_ROOT/$sysconfdir/ssh_prng_cmds.default
fi
diff --git a/contrib/caldera/openssh.spec b/contrib/caldera/openssh.spec
index 6bea9a40fdfb..515fe334d2c3 100644
--- a/contrib/caldera/openssh.spec
+++ b/contrib/caldera/openssh.spec
@@ -16,12 +16,11 @@
#old cvs stuff. please update before use. may be deprecated.
%define use_stable 1
+%define version 5.6p1
%if %{use_stable}
- %define version 5.5p1
%define cvs %{nil}
%define release 1
%else
- %define version 5.5p1
%define cvs cvs20050315
%define release 0r1
%endif
@@ -360,4 +359,4 @@ fi
* Mon Jan 01 1998 ...
Template Version: 1.31
-$Id: openssh.spec,v 1.70 2010/03/21 19:11:58 djm Exp $
+$Id: openssh.spec,v 1.71 2010/08/08 16:32:09 djm Exp $
diff --git a/contrib/cygwin/README b/contrib/cygwin/README
index 3dd45014a06a..5f911e924427 100644
--- a/contrib/cygwin/README
+++ b/contrib/cygwin/README
@@ -201,6 +201,7 @@ configure are used for the Cygwin binary distribution:
--mandir='${datadir}/man' \
--infodir='${datadir}/info'
--with-tcp-wrappers
+ --with-libedit
If you want to create a Cygwin package, equivalent to the one
in the Cygwin binary distribution, install like this:
@@ -217,12 +218,15 @@ You must have installed the following packages to be able to build OpenSSH:
- zlib
- openssl-devel
-- minires-devel
If you want to build with --with-tcp-wrappers, you also need the package
- tcp_wrappers
+If you want to build with --with-libedit, you also need the package
+
+- libedit-devel
+
Please send requests, error reports etc. to cygwin@cygwin.com.
diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec
index c13cfe60d324..77e66252ec5d 100644
--- a/contrib/redhat/openssh.spec
+++ b/contrib/redhat/openssh.spec
@@ -1,4 +1,4 @@
-%define ver 5.5p1
+%define ver 5.6p1
%define rel 1
# OpenSSH privilege separation requires a user & group ID
@@ -74,7 +74,7 @@ Release: %{rel}
%endif
URL: http://www.openssh.com/portable.html
Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz
-%if ! %{skip_x11_askpass}
+%if ! %{no_x11_askpass}
Source1: http://www.jmknoble.net/software/x11-ssh-askpass/x11-ssh-askpass-%{aversion}.tar.gz
%endif
License: BSD
@@ -407,6 +407,9 @@ fi
%endif
%changelog
+* Wed Jul 14 2010 Tim Rice <tim@multitalents.net>
+- test for skip_x11_askpass (line 77) should have been for no_x11_askpass
+
* Mon Jun 2 2003 Damien Miller <djm@mindrot.org>
- Remove noip6 option. This may be controlled at run-time in client config
file using new AddressFamily directive
diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id
index 65c0a8cd8635..368645cb4fc7 100644
--- a/contrib/ssh-copy-id
+++ b/contrib/ssh-copy-id
@@ -38,13 +38,17 @@ if [ "$#" -lt 1 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
exit 1
fi
-{ eval "$GET_ID" ; } | ssh $1 "umask 077; test -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys" || exit 1
+# strip any trailing colon
+host=`echo $1 | sed 's/:$//'`
+
+{ eval "$GET_ID" ; } | ssh $host "umask 077; test -d ~/.ssh || mkdir ~/.ssh ; cat >> ~/.ssh/authorized_keys" || exit 1
cat <<EOF
-Now try logging into the machine, with "ssh '$1'", and check in:
+Now try logging into the machine, with "ssh '$host'", and check in:
- .ssh/authorized_keys
+ ~/.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.
EOF
+
diff --git a/contrib/ssh-copy-id.1 b/contrib/ssh-copy-id.1
index f25ed01f2a6e..cb15ab24dbc4 100644
--- a/contrib/ssh-copy-id.1
+++ b/contrib/ssh-copy-id.1
@@ -25,19 +25,10 @@ ssh-copy-id \- install your public key in a remote machine's authorized_keys
.br
.SH DESCRIPTION
.BR ssh-copy-id
-is a script that uses ssh to log into a remote machine (presumably
-using a login password, so password authentication should be enabled,
-unless you've done some clever use of multiple identities)
-.PP
-It also changes the permissions of the remote user's home,
-.BR ~/.ssh ,
-and
+is a script that uses ssh to log into a remote machine and
+append the indicated identity file to that machine's
.B ~/.ssh/authorized_keys
-to remove group writability (which would otherwise prevent you from logging in, if the remote
-.B sshd
-has
-.B StrictModes
-set in its configuration).
+file.
.PP
If the
.B -i
@@ -59,7 +50,24 @@ produced no output, then it uses the contents of the identity
file. Once it has one or more fingerprints (by whatever means) it
uses ssh to append them to
.B ~/.ssh/authorized_keys
-on the remote machine (creating the file, and directory, if necessary)
+on the remote machine (creating the file, and directory, if necessary.)
+
+.SH NOTES
+This program does not modify the permissions of any
+pre-existing files or directories. Therefore, if the remote
+.B sshd
+has
+.B StrictModes
+set in its
+configuration, then the user's home,
+.B ~/.ssh
+folder, and
+.B ~/.ssh/authorized_keys
+file may need to have group writability disabled manually, e.g. via
+
+.B " chmod go-w ~ ~/.ssh ~/.ssh/authorized_keys"
+
+on the remote machine.
.SH "SEE ALSO"
.BR ssh (1),
diff --git a/contrib/suse/openssh.spec b/contrib/suse/openssh.spec
index 52ed915dc822..f099746f2a03 100644
--- a/contrib/suse/openssh.spec
+++ b/contrib/suse/openssh.spec
@@ -13,7 +13,7 @@
Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
Name: openssh
-Version: 5.5p1
+Version: 5.6p1
URL: http://www.openssh.com/
Release: 1
Source0: openssh-%{version}.tar.gz
diff --git a/jpake.c b/jpake.c
index 130661069fbd..cdf65f509228 100644
--- a/jpake.c
+++ b/jpake.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: jpake.c,v 1.2 2009/03/05 07:18:19 djm Exp $ */
+/* $OpenBSD: jpake.c,v 1.4 2010/07/13 23:13:16 djm Exp $ */
/*
* Copyright (c) 2008 Damien Miller. All rights reserved.
*
@@ -434,7 +434,7 @@ jpake_check_confirm(const BIGNUM *k,
if (peer_confirm_hash_len != expected_confirm_hash_len)
error("%s: confirmation length mismatch (my %u them %u)",
__func__, expected_confirm_hash_len, peer_confirm_hash_len);
- else if (memcmp(peer_confirm_hash, expected_confirm_hash,
+ else if (timingsafe_bcmp(peer_confirm_hash, expected_confirm_hash,
expected_confirm_hash_len) == 0)
success = 1;
bzero(expected_confirm_hash, expected_confirm_hash_len);
diff --git a/key.c b/key.c
index 66592c7ed19e..e4aa25c035f9 100644
--- a/key.c
+++ b/key.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: key.c,v 1.86 2010/03/15 19:40:02 stevesk Exp $ */
+/* $OpenBSD: key.c,v 1.90 2010/07/13 23:13:16 djm Exp $ */
/*
* read_bignum():
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -52,6 +52,7 @@
#include "uuencode.h"
#include "buffer.h"
#include "log.h"
+#include "misc.h"
#include "ssh2.h"
static struct KeyCert *
@@ -61,7 +62,8 @@ cert_new(void)
cert = xcalloc(1, sizeof(*cert));
buffer_init(&cert->certblob);
- buffer_init(&cert->constraints);
+ buffer_init(&cert->critical);
+ buffer_init(&cert->extensions);
cert->key_id = NULL;
cert->principals = NULL;
cert->signature_key = NULL;
@@ -82,6 +84,7 @@ key_new(int type)
switch (k->type) {
case KEY_RSA1:
case KEY_RSA:
+ case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
if ((rsa = RSA_new()) == NULL)
fatal("key_new: RSA_new failed");
@@ -92,6 +95,7 @@ key_new(int type)
k->rsa = rsa;
break;
case KEY_DSA:
+ case KEY_DSA_CERT_V00:
case KEY_DSA_CERT:
if ((dsa = DSA_new()) == NULL)
fatal("key_new: DSA_new failed");
@@ -124,6 +128,7 @@ key_add_private(Key *k)
switch (k->type) {
case KEY_RSA1:
case KEY_RSA:
+ case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
if ((k->rsa->d = BN_new()) == NULL)
fatal("key_new_private: BN_new failed");
@@ -139,6 +144,7 @@ key_add_private(Key *k)
fatal("key_new_private: BN_new failed");
break;
case KEY_DSA:
+ case KEY_DSA_CERT_V00:
case KEY_DSA_CERT:
if ((k->dsa->priv_key = BN_new()) == NULL)
fatal("key_new_private: BN_new failed");
@@ -165,7 +171,8 @@ cert_free(struct KeyCert *cert)
u_int i;
buffer_free(&cert->certblob);
- buffer_free(&cert->constraints);
+ buffer_free(&cert->critical);
+ buffer_free(&cert->extensions);
if (cert->key_id != NULL)
xfree(cert->key_id);
for (i = 0; i < cert->nprincipals; i++)
@@ -184,12 +191,14 @@ key_free(Key *k)
switch (k->type) {
case KEY_RSA1:
case KEY_RSA:
+ case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
if (k->rsa != NULL)
RSA_free(k->rsa);
k->rsa = NULL;
break;
case KEY_DSA:
+ case KEY_DSA_CERT_V00:
case KEY_DSA_CERT:
if (k->dsa != NULL)
DSA_free(k->dsa);
@@ -219,7 +228,7 @@ cert_compare(struct KeyCert *a, struct KeyCert *b)
return 0;
if (buffer_len(&a->certblob) != buffer_len(&b->certblob))
return 0;
- if (memcmp(buffer_ptr(&a->certblob), buffer_ptr(&b->certblob),
+ if (timingsafe_bcmp(buffer_ptr(&a->certblob), buffer_ptr(&b->certblob),
buffer_len(&a->certblob)) != 0)
return 0;
return 1;
@@ -238,11 +247,13 @@ key_equal_public(const Key *a, const Key *b)
switch (a->type) {
case KEY_RSA1:
+ case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
case KEY_RSA:
return a->rsa != NULL && b->rsa != NULL &&
BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
BN_cmp(a->rsa->n, b->rsa->n) == 0;
+ case KEY_DSA_CERT_V00:
case KEY_DSA_CERT:
case KEY_DSA:
return a->dsa != NULL && b->dsa != NULL &&
@@ -304,6 +315,8 @@ key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length)
case KEY_RSA:
key_to_blob(k, &blob, &len);
break;
+ case KEY_DSA_CERT_V00:
+ case KEY_RSA_CERT_V00:
case KEY_DSA_CERT:
case KEY_RSA_CERT:
/* We want a fingerprint of the _key_ not of the cert */
@@ -631,6 +644,8 @@ key_read(Key *ret, char **cpp)
case KEY_UNSPEC:
case KEY_RSA:
case KEY_DSA:
+ case KEY_DSA_CERT_V00:
+ case KEY_RSA_CERT_V00:
case KEY_DSA_CERT:
case KEY_RSA_CERT:
space = strchr(cp, ' ');
@@ -757,11 +772,13 @@ key_write(const Key *key, FILE *f)
error("key_write: failed for RSA key");
return 0;
case KEY_DSA:
+ case KEY_DSA_CERT_V00:
case KEY_DSA_CERT:
if (key->dsa == NULL)
return 0;
break;
case KEY_RSA:
+ case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
if (key->rsa == NULL)
return 0;
@@ -793,6 +810,10 @@ key_type(const Key *k)
return "RSA";
case KEY_DSA:
return "DSA";
+ case KEY_RSA_CERT_V00:
+ return "RSA-CERT-V00";
+ case KEY_DSA_CERT_V00:
+ return "DSA-CERT-V00";
case KEY_RSA_CERT:
return "RSA-CERT";
case KEY_DSA_CERT:
@@ -822,10 +843,14 @@ key_ssh_name(const Key *k)
return "ssh-rsa";
case KEY_DSA:
return "ssh-dss";
- case KEY_RSA_CERT:
+ case KEY_RSA_CERT_V00:
return "ssh-rsa-cert-v00@openssh.com";
- case KEY_DSA_CERT:
+ case KEY_DSA_CERT_V00:
return "ssh-dss-cert-v00@openssh.com";
+ case KEY_RSA_CERT:
+ return "ssh-rsa-cert-v01@openssh.com";
+ case KEY_DSA_CERT:
+ return "ssh-dss-cert-v01@openssh.com";
}
return "ssh-unknown";
}
@@ -836,9 +861,11 @@ key_size(const Key *k)
switch (k->type) {
case KEY_RSA1:
case KEY_RSA:
+ case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
return BN_num_bits(k->rsa->n);
case KEY_DSA:
+ case KEY_DSA_CERT_V00:
case KEY_DSA_CERT:
return BN_num_bits(k->dsa->p);
}
@@ -882,6 +909,8 @@ key_generate(int type, u_int bits)
case KEY_RSA1:
k->rsa = rsa_generate_private_key(bits);
break;
+ case KEY_RSA_CERT_V00:
+ case KEY_DSA_CERT_V00:
case KEY_RSA_CERT:
case KEY_DSA_CERT:
fatal("key_generate: cert keys cannot be generated directly");
@@ -912,9 +941,12 @@ key_cert_copy(const Key *from_key, struct Key *to_key)
buffer_append(&to->certblob, buffer_ptr(&from->certblob),
buffer_len(&from->certblob));
- buffer_append(&to->constraints, buffer_ptr(&from->constraints),
- buffer_len(&from->constraints));
+ buffer_append(&to->critical,
+ buffer_ptr(&from->critical), buffer_len(&from->critical));
+ buffer_append(&to->extensions,
+ buffer_ptr(&from->extensions), buffer_len(&from->extensions));
+ to->serial = from->serial;
to->type = from->type;
to->key_id = from->key_id == NULL ? NULL : xstrdup(from->key_id);
to->valid_after = from->valid_after;
@@ -940,6 +972,7 @@ key_from_private(const Key *k)
Key *n = NULL;
switch (k->type) {
case KEY_DSA:
+ case KEY_DSA_CERT_V00:
case KEY_DSA_CERT:
n = key_new(k->type);
if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) ||
@@ -950,6 +983,7 @@ key_from_private(const Key *k)
break;
case KEY_RSA:
case KEY_RSA1:
+ case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
n = key_new(k->type);
if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
@@ -979,8 +1013,12 @@ key_type_from_name(char *name)
} else if (strcmp(name, "ssh-dss") == 0) {
return KEY_DSA;
} else if (strcmp(name, "ssh-rsa-cert-v00@openssh.com") == 0) {
- return KEY_RSA_CERT;
+ return KEY_RSA_CERT_V00;
} else if (strcmp(name, "ssh-dss-cert-v00@openssh.com") == 0) {
+ return KEY_DSA_CERT_V00;
+ } else if (strcmp(name, "ssh-rsa-cert-v01@openssh.com") == 0) {
+ return KEY_RSA_CERT;
+ } else if (strcmp(name, "ssh-dss-cert-v01@openssh.com") == 0) {
return KEY_DSA_CERT;
}
debug2("key_type_from_name: unknown key type '%s'", name);
@@ -1012,26 +1050,31 @@ key_names_valid2(const char *names)
static int
cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen)
{
- u_char *principals, *constraints, *sig_key, *sig;
- u_int signed_len, plen, clen, sklen, slen, kidlen;
+ u_char *principals, *critical, *exts, *sig_key, *sig;
+ u_int signed_len, plen, clen, sklen, slen, kidlen, elen;
Buffer tmp;
char *principal;
int ret = -1;
+ int v00 = key->type == KEY_DSA_CERT_V00 ||
+ key->type == KEY_RSA_CERT_V00;
buffer_init(&tmp);
/* Copy the entire key blob for verification and later serialisation */
buffer_append(&key->cert->certblob, blob, blen);
- principals = constraints = sig_key = sig = NULL;
- if (buffer_get_int_ret(&key->cert->type, b) != 0 ||
+ elen = 0; /* Not touched for v00 certs */
+ principals = exts = critical = sig_key = sig = NULL;
+ if ((!v00 && buffer_get_int64_ret(&key->cert->serial, b) != 0) ||
+ buffer_get_int_ret(&key->cert->type, b) != 0 ||
(key->cert->key_id = buffer_get_string_ret(b, &kidlen)) == NULL ||
(principals = buffer_get_string_ret(b, &plen)) == NULL ||
buffer_get_int64_ret(&key->cert->valid_after, b) != 0 ||
buffer_get_int64_ret(&key->cert->valid_before, b) != 0 ||
- (constraints = buffer_get_string_ret(b, &clen)) == NULL ||
- /* skip nonce */ buffer_get_string_ptr_ret(b, NULL) == NULL ||
- /* skip reserved */ buffer_get_string_ptr_ret(b, NULL) == NULL ||
+ (critical = buffer_get_string_ret(b, &clen)) == NULL ||
+ (!v00 && (exts = buffer_get_string_ret(b, &elen)) == NULL) ||
+ (v00 && buffer_get_string_ptr_ret(b, NULL) == NULL) || /* nonce */
+ buffer_get_string_ptr_ret(b, NULL) == NULL || /* reserved */
(sig_key = buffer_get_string_ret(b, &sklen)) == NULL) {
error("%s: parse error", __func__);
goto out;
@@ -1078,13 +1121,25 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen)
buffer_clear(&tmp);
- buffer_append(&key->cert->constraints, constraints, clen);
- buffer_append(&tmp, constraints, clen);
+ buffer_append(&key->cert->critical, critical, clen);
+ buffer_append(&tmp, critical, clen);
/* validate structure */
while (buffer_len(&tmp) != 0) {
if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL ||
buffer_get_string_ptr_ret(&tmp, NULL) == NULL) {
- error("%s: Constraints data invalid", __func__);
+ error("%s: critical option data invalid", __func__);
+ goto out;
+ }
+ }
+ buffer_clear(&tmp);
+
+ buffer_append(&key->cert->extensions, exts, elen);
+ buffer_append(&tmp, exts, elen);
+ /* validate structure */
+ while (buffer_len(&tmp) != 0) {
+ if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL ||
+ buffer_get_string_ptr_ret(&tmp, NULL) == NULL) {
+ error("%s: extension data invalid", __func__);
goto out;
}
}
@@ -1121,8 +1176,10 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen)
buffer_free(&tmp);
if (principals != NULL)
xfree(principals);
- if (constraints != NULL)
- xfree(constraints);
+ if (critical != NULL)
+ xfree(critical);
+ if (exts != NULL)
+ xfree(exts);
if (sig_key != NULL)
xfree(sig_key);
if (sig != NULL)
@@ -1151,8 +1208,11 @@ key_from_blob(const u_char *blob, u_int blen)
type = key_type_from_name(ktype);
switch (type) {
- case KEY_RSA:
case KEY_RSA_CERT:
+ (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */
+ /* FALLTHROUGH */
+ case KEY_RSA:
+ case KEY_RSA_CERT_V00:
key = key_new(type);
if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 ||
buffer_get_bignum2_ret(&b, key->rsa->n) == -1) {
@@ -1166,8 +1226,11 @@ key_from_blob(const u_char *blob, u_int blen)
RSA_print_fp(stderr, key->rsa, 8);
#endif
break;
- case KEY_DSA:
case KEY_DSA_CERT:
+ (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */
+ /* FALLTHROUGH */
+ case KEY_DSA:
+ case KEY_DSA_CERT_V00:
key = key_new(type);
if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 ||
buffer_get_bignum2_ret(&b, key->dsa->q) == -1 ||
@@ -1213,6 +1276,8 @@ key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
}
buffer_init(&b);
switch (key->type) {
+ case KEY_DSA_CERT_V00:
+ case KEY_RSA_CERT_V00:
case KEY_DSA_CERT:
case KEY_RSA_CERT:
/* Use the existing blob */
@@ -1255,9 +1320,11 @@ key_sign(
const u_char *data, u_int datalen)
{
switch (key->type) {
+ case KEY_DSA_CERT_V00:
case KEY_DSA_CERT:
case KEY_DSA:
return ssh_dss_sign(key, sigp, lenp, data, datalen);
+ case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
case KEY_RSA:
return ssh_rsa_sign(key, sigp, lenp, data, datalen);
@@ -1281,9 +1348,11 @@ key_verify(
return -1;
switch (key->type) {
+ case KEY_DSA_CERT_V00:
case KEY_DSA_CERT:
case KEY_DSA:
return ssh_dss_verify(key, signature, signaturelen, data, datalen);
+ case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
case KEY_RSA:
return ssh_rsa_verify(key, signature, signaturelen, data, datalen);
@@ -1306,6 +1375,7 @@ key_demote(const Key *k)
pk->rsa = NULL;
switch (k->type) {
+ case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
key_cert_copy(k, pk);
/* FALLTHROUGH */
@@ -1318,6 +1388,7 @@ key_demote(const Key *k)
if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL)
fatal("key_demote: BN_dup failed");
break;
+ case KEY_DSA_CERT_V00:
case KEY_DSA_CERT:
key_cert_copy(k, pk);
/* FALLTHROUGH */
@@ -1344,8 +1415,17 @@ key_demote(const Key *k)
int
key_is_cert(const Key *k)
{
- return k != NULL &&
- (k->type == KEY_RSA_CERT || k->type == KEY_DSA_CERT);
+ if (k == NULL)
+ return 0;
+ switch (k->type) {
+ case KEY_RSA_CERT_V00:
+ case KEY_DSA_CERT_V00:
+ case KEY_RSA_CERT:
+ case KEY_DSA_CERT:
+ return 1;
+ default:
+ return 0;
+ }
}
/* Return the cert-less equivalent to a certified key type */
@@ -1353,8 +1433,10 @@ int
key_type_plain(int type)
{
switch (type) {
+ case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
return KEY_RSA;
+ case KEY_DSA_CERT_V00:
case KEY_DSA_CERT:
return KEY_DSA;
default:
@@ -1364,16 +1446,16 @@ key_type_plain(int type)
/* Convert a KEY_RSA or KEY_DSA to their _CERT equivalent */
int
-key_to_certified(Key *k)
+key_to_certified(Key *k, int legacy)
{
switch (k->type) {
case KEY_RSA:
k->cert = cert_new();
- k->type = KEY_RSA_CERT;
+ k->type = legacy ? KEY_RSA_CERT_V00 : KEY_RSA_CERT;
return 0;
case KEY_DSA:
k->cert = cert_new();
- k->type = KEY_DSA_CERT;
+ k->type = legacy ? KEY_DSA_CERT_V00 : KEY_DSA_CERT;
return 0;
default:
error("%s: key has incorrect type %s", __func__, key_type(k));
@@ -1386,10 +1468,12 @@ int
key_drop_cert(Key *k)
{
switch (k->type) {
+ case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
cert_free(k->cert);
k->type = KEY_RSA;
return 0;
+ case KEY_DSA_CERT_V00:
case KEY_DSA_CERT:
cert_free(k->cert);
k->type = KEY_DSA;
@@ -1430,13 +1514,21 @@ key_certify(Key *k, Key *ca)
buffer_clear(&k->cert->certblob);
buffer_put_cstring(&k->cert->certblob, key_ssh_name(k));
+ /* -v01 certs put nonce first */
+ if (k->type == KEY_DSA_CERT || k->type == KEY_RSA_CERT) {
+ arc4random_buf(&nonce, sizeof(nonce));
+ buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce));
+ }
+
switch (k->type) {
+ case KEY_DSA_CERT_V00:
case KEY_DSA_CERT:
buffer_put_bignum2(&k->cert->certblob, k->dsa->p);
buffer_put_bignum2(&k->cert->certblob, k->dsa->q);
buffer_put_bignum2(&k->cert->certblob, k->dsa->g);
buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key);
break;
+ case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
buffer_put_bignum2(&k->cert->certblob, k->rsa->e);
buffer_put_bignum2(&k->cert->certblob, k->rsa->n);
@@ -1448,6 +1540,10 @@ key_certify(Key *k, Key *ca)
return -1;
}
+ /* -v01 certs have a serial number next */
+ if (k->type == KEY_DSA_CERT || k->type == KEY_RSA_CERT)
+ buffer_put_int64(&k->cert->certblob, k->cert->serial);
+
buffer_put_int(&k->cert->certblob, k->cert->type);
buffer_put_cstring(&k->cert->certblob, k->cert->key_id);
@@ -1461,11 +1557,19 @@ key_certify(Key *k, Key *ca)
buffer_put_int64(&k->cert->certblob, k->cert->valid_after);
buffer_put_int64(&k->cert->certblob, k->cert->valid_before);
buffer_put_string(&k->cert->certblob,
- buffer_ptr(&k->cert->constraints),
- buffer_len(&k->cert->constraints));
+ buffer_ptr(&k->cert->critical), buffer_len(&k->cert->critical));
+
+ /* -v01 certs have non-critical options here */
+ if (k->type == KEY_DSA_CERT || k->type == KEY_RSA_CERT) {
+ buffer_put_string(&k->cert->certblob,
+ buffer_ptr(&k->cert->extensions),
+ buffer_len(&k->cert->extensions));
+ }
+
+ /* -v00 certs put the nonce at the end */
+ if (k->type == KEY_DSA_CERT_V00 || k->type == KEY_RSA_CERT_V00)
+ buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce));
- arc4random_buf(&nonce, sizeof(nonce));
- buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce));
buffer_put_string(&k->cert->certblob, NULL, 0); /* reserved */
buffer_put_string(&k->cert->certblob, ca_blob, ca_len);
xfree(ca_blob);
@@ -1520,7 +1624,7 @@ key_cert_check_authority(const Key *k, int want_host, int require_principal,
*reason = "Certificate lacks principal list";
return -1;
}
- } else {
+ } else if (name != NULL) {
principal_matches = 0;
for (i = 0; i < k->cert->nprincipals; i++) {
if (strcmp(name, k->cert->principals[i]) == 0) {
@@ -1536,3 +1640,15 @@ key_cert_check_authority(const Key *k, int want_host, int require_principal,
}
return 0;
}
+
+int
+key_cert_is_legacy(Key *k)
+{
+ switch (k->type) {
+ case KEY_DSA_CERT_V00:
+ case KEY_RSA_CERT_V00:
+ return 1;
+ default:
+ return 0;
+ }
+}
diff --git a/key.h b/key.h
index 4f17777c0881..11d30eae685b 100644
--- a/key.h
+++ b/key.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: key.h,v 1.29 2010/03/15 19:40:02 stevesk Exp $ */
+/* $OpenBSD: key.h,v 1.30 2010/04/16 01:47:26 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -37,6 +37,8 @@ enum types {
KEY_DSA,
KEY_RSA_CERT,
KEY_DSA_CERT,
+ KEY_RSA_CERT_V00,
+ KEY_DSA_CERT_V00,
KEY_UNSPEC
};
enum fp_type {
@@ -56,11 +58,13 @@ enum fp_rep {
struct KeyCert {
Buffer certblob; /* Kept around for use on wire */
u_int type; /* SSH2_CERT_TYPE_USER or SSH2_CERT_TYPE_HOST */
+ u_int64_t serial;
char *key_id;
u_int nprincipals;
char **principals;
u_int64_t valid_after, valid_before;
- Buffer constraints;
+ Buffer critical;
+ Buffer extensions;
Key *signature_key;
};
@@ -92,12 +96,13 @@ Key *key_from_private(const Key *);
int key_type_from_name(char *);
int key_is_cert(const Key *);
int key_type_plain(int);
-int key_to_certified(Key *);
+int key_to_certified(Key *, int);
int key_drop_cert(Key *);
int key_certify(Key *, Key *);
void key_cert_copy(const Key *, struct Key *);
int key_cert_check_authority(const Key *, int, int, const char *,
const char **);
+int key_cert_is_legacy(Key *);
Key *key_from_blob(const u_char *, u_int);
int key_to_blob(const Key *, u_char **, u_int *);
diff --git a/loginrec.h b/loginrec.h
index 859e1a63049b..84b48659003c 100644
--- a/loginrec.h
+++ b/loginrec.h
@@ -56,7 +56,7 @@ union login_netinfo {
/* string lengths - set very long */
#define LINFO_PROGSIZE 64
#define LINFO_LINESIZE 64
-#define LINFO_NAMESIZE 128
+#define LINFO_NAMESIZE 512
#define LINFO_HOSTSIZE 256
struct logininfo {
diff --git a/misc.c b/misc.c
index e1f723123eb4..a82e7936ed6e 100644
--- a/misc.c
+++ b/misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.75 2010/01/09 23:04:13 dtucker Exp $ */
+/* $OpenBSD: misc.c,v 1.80 2010/07/21 02:10:58 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@@ -178,6 +178,7 @@ strdelim(char **s)
return (NULL); /* no matching quote */
} else {
*s[0] = '\0';
+ *s += strspn(*s + 1, WHITESPACE) + 1;
return (old);
}
}
@@ -425,7 +426,7 @@ colon(char *cp)
int flag = 0;
if (*cp == ':') /* Leading colon is part of file name. */
- return (0);
+ return NULL;
if (*cp == '[')
flag = 1;
@@ -437,9 +438,9 @@ colon(char *cp)
if (*cp == ':' && !flag)
return (cp);
if (*cp == '/')
- return (0);
+ return NULL;
}
- return (0);
+ return NULL;
}
/* function to assist building execv() arguments */
@@ -849,6 +850,16 @@ ms_to_timeval(struct timeval *tv, int ms)
tv->tv_usec = (ms % 1000) * 1000;
}
+int
+timingsafe_bcmp(const void *b1, const void *b2, size_t n)
+{
+ const unsigned char *p1 = b1, *p2 = b2;
+ int ret = 0;
+
+ for (; n > 0; n--)
+ ret |= *p1++ ^ *p2++;
+ return (ret != 0);
+}
void
sock_set_v6only(int s)
{
diff --git a/misc.h b/misc.h
index 32073acd4175..bb799f616379 100644
--- a/misc.h
+++ b/misc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.h,v 1.41 2010/01/09 23:04:13 dtucker Exp $ */
+/* $OpenBSD: misc.h,v 1.43 2010/07/13 23:13:16 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -36,6 +36,7 @@ void sanitise_stdfd(void);
void ms_subtract_diff(struct timeval *, int *);
void ms_to_timeval(struct timeval *, int);
void sock_set_v6only(int);
+int timingsafe_bcmp(const void *, const void *, size_t);
struct passwd *pwcopy(struct passwd *);
const char *ssh_gai_strerror(int);
diff --git a/moduli.0 b/moduli.0
index e3fea22a9a79..6d707ff8257a 100644
--- a/moduli.0
+++ b/moduli.0
@@ -14,11 +14,12 @@ DESCRIPTION
are prime and are safe for use in Diffie Hellman operations by sshd(8).
This moduli format is used as the output from each pass.
- The file consists of newline-separated records, one per modulus, contain-
- ing seven space separated fields. These fields are as follows:
+ The file consists of newline-separated records, one per modulus,
+ containing seven space separated fields. These fields are as follows:
- timestamp The time that the modulus was last processed as YYYYM-
- MDDHHMMSS.
+
+ timestamp The time that the modulus was last processed as
+ YYYYMMDDHHMMSS.
type Decimal number specifying the internal structure of
the prime modulus. Supported types are:
@@ -69,4 +70,4 @@ SEE ALSO
Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer
Protocol, RFC 4419, 2006.
-OpenBSD 4.7 June 26, 2008 2
+OpenBSD 4.8 June 26, 2008 OpenBSD 4.8
diff --git a/monitor.c b/monitor.c
index 334aedde5916..9eb4e35c97e1 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.c,v 1.106 2010/03/07 11:57:13 dtucker Exp $ */
+/* $OpenBSD: monitor.c,v 1.108 2010/07/13 23:13:16 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -518,7 +518,7 @@ monitor_allowed_key(u_char *blob, u_int bloblen)
{
/* make sure key is allowed */
if (key_blob == NULL || key_bloblen != bloblen ||
- memcmp(key_blob, blob, key_bloblen))
+ timingsafe_bcmp(key_blob, blob, key_bloblen))
return (0);
return (1);
}
@@ -922,8 +922,8 @@ mm_answer_pam_init_ctx(int sock, Buffer *m)
int
mm_answer_pam_query(int sock, Buffer *m)
{
- char *name, *info, **prompts;
- u_int i, num, *echo_on;
+ char *name = NULL, *info = NULL, **prompts = NULL;
+ u_int i, num = 0, *echo_on = 0;
int ret;
debug3("%s", __func__);
@@ -1103,14 +1103,14 @@ monitor_valid_userblob(u_char *data, u_int datalen)
len = buffer_len(&b);
if ((session_id2 == NULL) ||
(len < session_id2_len) ||
- (memcmp(p, session_id2, session_id2_len) != 0))
+ (timingsafe_bcmp(p, session_id2, session_id2_len) != 0))
fail++;
buffer_consume(&b, session_id2_len);
} else {
p = buffer_get_string(&b, &len);
if ((session_id2 == NULL) ||
(len != session_id2_len) ||
- (memcmp(p, session_id2, session_id2_len) != 0))
+ (timingsafe_bcmp(p, session_id2, session_id2_len) != 0))
fail++;
xfree(p);
}
@@ -1158,7 +1158,7 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser,
p = buffer_get_string(&b, &len);
if ((session_id2 == NULL) ||
(len != session_id2_len) ||
- (memcmp(p, session_id2, session_id2_len) != 0))
+ (timingsafe_bcmp(p, session_id2, session_id2_len) != 0))
fail++;
xfree(p);
@@ -1682,9 +1682,9 @@ mm_get_kex(Buffer *m)
kex = xcalloc(1, sizeof(*kex));
kex->session_id = buffer_get_string(m, &kex->session_id_len);
- if ((session_id2 == NULL) ||
- (kex->session_id_len != session_id2_len) ||
- (memcmp(kex->session_id, session_id2, session_id2_len) != 0))
+ if (session_id2 == NULL ||
+ kex->session_id_len != session_id2_len ||
+ timingsafe_bcmp(kex->session_id, session_id2, session_id2_len) != 0)
fatal("mm_get_get: internal error: bad session id");
kex->we_need = buffer_get_int(m);
kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
diff --git a/mux.c b/mux.c
index 825fb7a9a70d..5c3857ee816b 100644
--- a/mux.c
+++ b/mux.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mux.c,v 1.14 2010/01/30 02:54:53 djm Exp $ */
+/* $OpenBSD: mux.c,v 1.21 2010/06/25 23:15:36 djm Exp $ */
/*
* Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
*
@@ -71,6 +71,7 @@
#include "xmalloc.h"
#include "log.h"
#include "ssh.h"
+#include "ssh2.h"
#include "pathnames.h"
#include "misc.h"
#include "match.h"
@@ -106,6 +107,14 @@ struct mux_session_confirm_ctx {
char *term;
struct termios tio;
char **env;
+ u_int rid;
+};
+
+/* Context for global channel callback */
+struct mux_channel_confirm_ctx {
+ u_int cid; /* channel id */
+ u_int rid; /* request id */
+ int fid; /* forward id */
};
/* fd to control socket */
@@ -143,13 +152,14 @@ struct mux_master_state {
#define MUX_S_EXIT_MESSAGE 0x80000004
#define MUX_S_ALIVE 0x80000005
#define MUX_S_SESSION_OPENED 0x80000006
+#define MUX_S_REMOTE_PORT 0x80000007
/* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */
#define MUX_FWD_LOCAL 1
#define MUX_FWD_REMOTE 2
#define MUX_FWD_DYNAMIC 3
-static void mux_session_confirm(int, void *);
+static void mux_session_confirm(int, int, void *);
static int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *);
static int process_mux_new_session(u_int, Channel *, Buffer *, Buffer *);
@@ -206,7 +216,7 @@ mux_master_control_cleanup_cb(int cid, void *unused)
fatal("%s: channel_by_id(%i) == NULL", __func__, cid);
if (c->remote_id != -1) {
if ((sc = channel_by_id(c->remote_id)) == NULL)
- debug2("%s: channel %d n session channel %d",
+ fatal("%s: channel %d missing session channel %d",
__func__, c->self, c->remote_id);
c->remote_id = -1;
sc->ctl_chan = -1;
@@ -301,6 +311,7 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
/* Reply for SSHMUX_COMMAND_OPEN */
cctx = xcalloc(1, sizeof(*cctx));
cctx->term = NULL;
+ cctx->rid = rid;
cmd = reserved = NULL;
if ((reserved = buffer_get_string_ret(m, NULL)) == NULL ||
buffer_get_int_ret(&cctx->want_tty, m) != 0 ||
@@ -454,14 +465,10 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
channel_send_open(nc->self);
channel_register_open_confirm(nc->self, mux_session_confirm, cctx);
- channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 0);
-
- /* prepare reply */
- /* XXX defer until mux_session_confirm() fires */
- buffer_put_int(r, MUX_S_SESSION_OPENED);
- buffer_put_int(r, rid);
- buffer_put_int(r, nc->self);
+ c->mux_pause = 1; /* stop handling messages until open_confirm done */
+ channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1);
+ /* reply is deferred, sent by mux_session_confirm */
return 0;
}
@@ -559,6 +566,61 @@ compare_forward(Forward *a, Forward *b)
return 1;
}
+static void
+mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
+{
+ struct mux_channel_confirm_ctx *fctx = ctxt;
+ char *failmsg = NULL;
+ Forward *rfwd;
+ Channel *c;
+ Buffer out;
+
+ if ((c = channel_by_id(fctx->cid)) == NULL) {
+ /* no channel for reply */
+ error("%s: unknown channel", __func__);
+ return;
+ }
+ buffer_init(&out);
+ if (fctx->fid >= options.num_remote_forwards) {
+ xasprintf(&failmsg, "unknown forwarding id %d", fctx->fid);
+ goto fail;
+ }
+ rfwd = &options.remote_forwards[fctx->fid];
+ debug("%s: %s for: listen %d, connect %s:%d", __func__,
+ type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
+ rfwd->listen_port, rfwd->connect_host, rfwd->connect_port);
+ if (type == SSH2_MSG_REQUEST_SUCCESS) {
+ if (rfwd->listen_port == 0) {
+ rfwd->allocated_port = packet_get_int();
+ logit("Allocated port %u for mux remote forward"
+ " to %s:%d", rfwd->allocated_port,
+ rfwd->connect_host, rfwd->connect_port);
+ buffer_put_int(&out, MUX_S_REMOTE_PORT);
+ buffer_put_int(&out, fctx->rid);
+ buffer_put_int(&out, rfwd->allocated_port);
+ } else {
+ buffer_put_int(&out, MUX_S_OK);
+ buffer_put_int(&out, fctx->rid);
+ }
+ goto out;
+ } else {
+ xasprintf(&failmsg, "remote port forwarding failed for "
+ "listen port %d", rfwd->listen_port);
+ }
+ fail:
+ error("%s: %s", __func__, failmsg);
+ buffer_put_int(&out, MUX_S_FAILURE);
+ buffer_put_int(&out, fctx->rid);
+ buffer_put_cstring(&out, failmsg);
+ xfree(failmsg);
+ out:
+ buffer_put_string(&c->output, buffer_ptr(&out), buffer_len(&out));
+ buffer_free(&out);
+ if (c->mux_pause <= 0)
+ fatal("%s: mux_pause %d", __func__, c->mux_pause);
+ c->mux_pause = 0; /* start processing messages again */
+}
+
static int
process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
{
@@ -594,15 +656,16 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
ftype != MUX_FWD_DYNAMIC) {
logit("%s: invalid forwarding type %u", __func__, ftype);
invalid:
- xfree(fwd.listen_host);
- xfree(fwd.connect_host);
+ if (fwd.listen_host)
+ xfree(fwd.listen_host);
+ if (fwd.connect_host)
+ xfree(fwd.connect_host);
buffer_put_int(r, MUX_S_FAILURE);
buffer_put_int(r, rid);
buffer_put_cstring(r, "Invalid forwarding request");
return 0;
}
- /* XXX support rport0 forwarding with reply of port assigned */
- if (fwd.listen_port == 0 || fwd.listen_port >= 65536) {
+ if (fwd.listen_port >= 65536) {
logit("%s: invalid listen port %u", __func__,
fwd.listen_port);
goto invalid;
@@ -637,8 +700,17 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
case MUX_FWD_REMOTE:
for (i = 0; i < options.num_remote_forwards; i++) {
if (compare_forward(&fwd,
- options.remote_forwards + i))
- goto exists;
+ options.remote_forwards + i)) {
+ if (fwd.listen_port != 0)
+ goto exists;
+ debug2("%s: found allocated port",
+ __func__);
+ buffer_put_int(r, MUX_S_REMOTE_PORT);
+ buffer_put_int(r, rid);
+ buffer_put_int(r,
+ options.remote_forwards[i].allocated_port);
+ goto out;
+ }
}
break;
}
@@ -655,9 +727,7 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
}
if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) {
- if (options.num_local_forwards + 1 >=
- SSH_MAX_FORWARDS_PER_DIRECTION ||
- channel_setup_local_fwd_listener(fwd.listen_host,
+ if (channel_setup_local_fwd_listener(fwd.listen_host,
fwd.listen_port, fwd.connect_host, fwd.connect_port,
options.gateway_ports) < 0) {
fail:
@@ -670,14 +740,22 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
add_local_forward(&options, &fwd);
freefwd = 0;
} else {
- /* XXX wait for remote to confirm */
- if (options.num_remote_forwards + 1 >=
- SSH_MAX_FORWARDS_PER_DIRECTION ||
- channel_request_remote_forwarding(fwd.listen_host,
+ struct mux_channel_confirm_ctx *fctx;
+
+ if (channel_request_remote_forwarding(fwd.listen_host,
fwd.listen_port, fwd.connect_host, fwd.connect_port) < 0)
goto fail;
add_remote_forward(&options, &fwd);
+ fctx = xcalloc(1, sizeof(*fctx));
+ fctx->cid = c->self;
+ fctx->rid = rid;
+ fctx->fid = options.num_remote_forwards - 1;
+ client_register_global_confirm(mux_confirm_remote_forward,
+ fctx);
freefwd = 0;
+ c->mux_pause = 1; /* wait for mux_confirm_remote_forward */
+ /* delayed reply in mux_confirm_remote_forward */
+ goto out;
}
buffer_put_int(r, MUX_S_OK);
buffer_put_int(r, rid);
@@ -826,7 +904,7 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
debug2("%s: channel_new: %d linked to control channel %d",
__func__, nc->self, nc->ctl_chan);
- channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 0);
+ channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1);
/* prepare reply */
/* XXX defer until channel confirmed */
@@ -849,7 +927,7 @@ mux_master_read_cb(Channel *c)
/* Setup ctx and */
if (c->mux_ctx == NULL) {
- state = xcalloc(1, sizeof(state));
+ state = xcalloc(1, sizeof(*state));
c->mux_ctx = state;
channel_register_cleanup(c->self,
mux_master_control_cleanup_cb, 0);
@@ -1000,26 +1078,43 @@ muxserver_listen(void)
/* Callback on open confirmation in mux master for a mux client session. */
static void
-mux_session_confirm(int id, void *arg)
+mux_session_confirm(int id, int success, void *arg)
{
struct mux_session_confirm_ctx *cctx = arg;
const char *display;
- Channel *c;
+ Channel *c, *cc;
int i;
+ Buffer reply;
if (cctx == NULL)
fatal("%s: cctx == NULL", __func__);
if ((c = channel_by_id(id)) == NULL)
fatal("%s: no channel for id %d", __func__, id);
+ if ((cc = channel_by_id(c->ctl_chan)) == NULL)
+ fatal("%s: channel %d lacks control channel %d", __func__,
+ id, c->ctl_chan);
+
+ if (!success) {
+ debug3("%s: sending failure reply", __func__);
+ /* prepare reply */
+ buffer_init(&reply);
+ buffer_put_int(&reply, MUX_S_FAILURE);
+ buffer_put_int(&reply, cctx->rid);
+ buffer_put_cstring(&reply, "Session open refused by peer");
+ goto done;
+ }
display = getenv("DISPLAY");
if (cctx->want_x_fwd && options.forward_x11 && display != NULL) {
char *proto, *data;
+
/* Get reasonable local authentication information. */
client_x11_get_proto(display, options.xauth_location,
- options.forward_x11_trusted, &proto, &data);
+ options.forward_x11_trusted, options.forward_x11_timeout,
+ &proto, &data);
/* Request forwarding with authentication spoofing. */
- debug("Requesting X11 forwarding with authentication spoofing.");
+ debug("Requesting X11 forwarding with authentication "
+ "spoofing.");
x11_request_forwarding_with_spoofing(id, display, proto, data);
/* XXX wait for reply */
}
@@ -1033,6 +1128,21 @@ mux_session_confirm(int id, void *arg)
client_session2_setup(id, cctx->want_tty, cctx->want_subsys,
cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env);
+ debug3("%s: sending success reply", __func__);
+ /* prepare reply */
+ buffer_init(&reply);
+ buffer_put_int(&reply, MUX_S_SESSION_OPENED);
+ buffer_put_int(&reply, cctx->rid);
+ buffer_put_int(&reply, c->self);
+
+ done:
+ /* Send reply */
+ buffer_put_string(&cc->output, buffer_ptr(&reply), buffer_len(&reply));
+ buffer_free(&reply);
+
+ if (cc->mux_pause <= 0)
+ fatal("%s: mux_pause %d", __func__, cc->mux_pause);
+ cc->mux_pause = 0; /* start processing messages again */
c->open_confirm_ctx = NULL;
buffer_free(&cctx->cmd);
xfree(cctx->term);
@@ -1365,6 +1475,15 @@ mux_client_request_forward(int fd, u_int ftype, Forward *fwd)
switch (type) {
case MUX_S_OK:
break;
+ case MUX_S_REMOTE_PORT:
+ fwd->allocated_port = buffer_get_int(&m);
+ logit("Allocated port %u for remote forward to %s:%d",
+ fwd->allocated_port,
+ fwd->connect_host ? fwd->connect_host : "",
+ fwd->connect_port);
+ if (muxclient_command == SSHMUX_COMMAND_FORWARD)
+ fprintf(stdout, "%u\n", fwd->allocated_port);
+ break;
case MUX_S_PERMISSION_DENIED:
e = buffer_get_string(&m, NULL);
buffer_free(&m);
@@ -1731,6 +1850,10 @@ muxclient(const char *path)
mux_client_request_terminate(sock);
fprintf(stderr, "Exit request sent.\r\n");
exit(0);
+ case SSHMUX_COMMAND_FORWARD:
+ if (mux_client_request_forwards(sock) != 0)
+ fatal("%s: master forward request failed", __func__);
+ exit(0);
case SSHMUX_COMMAND_OPEN:
if (mux_client_request_forwards(sock) != 0) {
error("%s: master forward request failed", __func__);
diff --git a/myproposal.h b/myproposal.h
index 98f27fd1593d..7bedfab0a935 100644
--- a/myproposal.h
+++ b/myproposal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: myproposal.h,v 1.24 2010/02/26 20:29:54 djm Exp $ */
+/* $OpenBSD: myproposal.h,v 1.25 2010/04/16 01:47:26 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -40,9 +40,12 @@
"diffie-hellman-group1-sha1"
#endif
-#define KEX_DEFAULT_PK_ALG "ssh-rsa-cert-v00@openssh.com," \
- "ssh-dss-cert-v00@openssh.com," \
- "ssh-rsa,ssh-dss"
+#define KEX_DEFAULT_PK_ALG \
+ "ssh-rsa-cert-v01@openssh.com," \
+ "ssh-dss-cert-v01@openssh.com," \
+ "ssh-rsa-cert-v00@openssh.com," \
+ "ssh-dss-cert-v00@openssh.com," \
+ "ssh-rsa,ssh-dss"
#define KEX_DEFAULT_ENCRYPT \
"aes128-ctr,aes192-ctr,aes256-ctr," \
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in
index d65b77b5b1f5..d22efd66cb7b 100644
--- a/openbsd-compat/Makefile.in
+++ b/openbsd-compat/Makefile.in
@@ -1,4 +1,4 @@
-# $Id: Makefile.in,v 1.44 2010/01/15 01:38:30 dtucker Exp $
+# $Id: Makefile.in,v 1.45 2010/08/16 03:15:23 dtucker Exp $
sysconfdir=@sysconfdir@
piddir=@piddir@
@@ -16,7 +16,7 @@ RANLIB=@RANLIB@
INSTALL=@INSTALL@
LDFLAGS=-L. @LDFLAGS@
-OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtonum.o strtoll.o strtoul.o vis.o
+OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o vis.o
COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o
diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h
index cad2408d6a08..e15d2bd96900 100644
--- a/openbsd-compat/openbsd-compat.h
+++ b/openbsd-compat/openbsd-compat.h
@@ -1,4 +1,4 @@
-/* $Id: openbsd-compat.h,v 1.49 2010/01/16 12:58:37 dtucker Exp $ */
+/* $Id: openbsd-compat.h,v 1.50 2010/08/16 03:15:23 dtucker Exp $ */
/*
* Copyright (c) 1999-2003 Damien Miller. All rights reserved.
@@ -87,6 +87,11 @@ int setenv(register const char *name, register const char *value, int rewrite);
void strmode(int mode, char *p);
#endif
+#ifndef HAVE_STRPTIME
+#include <time.h>
+char *strptime(const char *buf, const char *fmt, struct tm *tm);
+#endif
+
#if !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP)
int mkstemps(char *path, int slen);
int mkstemp(char *path);
diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h
index fcc762867d5d..b7caa650c24a 100644
--- a/openbsd-compat/openssl-compat.h
+++ b/openbsd-compat/openssl-compat.h
@@ -1,4 +1,4 @@
-/* $Id: openssl-compat.h,v 1.14 2009/03/07 11:22:35 dtucker Exp $ */
+/* $Id: openssl-compat.h,v 1.15 2010/05/12 07:50:02 djm Exp $ */
/*
* Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au>
@@ -18,6 +18,16 @@
#include "includes.h"
#include <openssl/evp.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+
+/* Only in 0.9.8 */
+#ifndef OPENSSL_DSA_MAX_MODULUS_BITS
+# define OPENSSL_DSA_MAX_MODULUS_BITS 10000
+#endif
+#ifndef OPENSSL_RSA_MAX_MODULUS_BITS
+# define OPENSSL_RSA_MAX_MODULUS_BITS 16384
+#endif
/* OPENSSL_free() is Free() in versions before OpenSSL 0.9.6 */
#if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090600f)
@@ -97,3 +107,4 @@ 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);
#endif /* SSH_DONT_OVERLOAD_OPENSSL_FUNCS */
+
diff --git a/openbsd-compat/port-tun.c b/openbsd-compat/port-tun.c
index ddc92d0f3f55..0d756f74f806 100644
--- a/openbsd-compat/port-tun.c
+++ b/openbsd-compat/port-tun.c
@@ -173,9 +173,11 @@ sys_tun_open(int tun, int mode)
if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)
goto failed;
- ifr.ifr_flags |= IFF_UP;
- if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
- goto failed;
+ if ((ifr.ifr_flags & IFF_UP) == 0) {
+ ifr.ifr_flags |= IFF_UP;
+ if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
+ goto failed;
+ }
close(sock);
return (fd);
diff --git a/openbsd-compat/port-uw.c b/openbsd-compat/port-uw.c
index be9905a6af9b..b1fbfa208557 100644
--- a/openbsd-compat/port-uw.c
+++ b/openbsd-compat/port-uw.c
@@ -39,10 +39,10 @@
#include "xmalloc.h"
#include "packet.h"
#include "buffer.h"
+#include "key.h"
#include "auth-options.h"
#include "log.h"
#include "servconf.h"
-#include "key.h"
#include "hostfile.h"
#include "auth.h"
#include "ssh.h"
diff --git a/openbsd-compat/strptime.c b/openbsd-compat/strptime.c
new file mode 100644
index 000000000000..d8d83d9079f7
--- /dev/null
+++ b/openbsd-compat/strptime.c
@@ -0,0 +1,401 @@
+/* $OpenBSD: strptime.c,v 1.12 2008/06/26 05:42:05 ray Exp $ */
+/* $NetBSD: strptime.c,v 1.12 1998/01/20 21:39:40 mycroft Exp $ */
+
+/*-
+ * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code was contributed to The NetBSD Foundation by Klaus Klein.
+ *
+ * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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.
+ */
+
+/* OPENBSD ORIGINAL: lib/libc/time/strptime.c */
+
+#include "includes.h"
+
+#ifndef HAVE_STRPTIME
+
+#define TM_YEAR_BASE 1900 /* from tzfile.h */
+
+#include <ctype.h>
+#include <locale.h>
+#include <string.h>
+#include <time.h>
+
+/* #define _ctloc(x) (_CurrentTimeLocale->x) */
+
+/*
+ * We do not implement alternate representations. However, we always
+ * check whether a given modifier is allowed for a certain conversion.
+ */
+#define _ALT_E 0x01
+#define _ALT_O 0x02
+#define _LEGAL_ALT(x) { if (alt_format & ~(x)) return (0); }
+
+
+static int _conv_num(const unsigned char **, int *, int, int);
+static char *_strptime(const char *, const char *, struct tm *, int);
+
+
+char *
+strptime(const char *buf, const char *fmt, struct tm *tm)
+{
+ return(_strptime(buf, fmt, tm, 1));
+}
+
+static char *
+_strptime(const char *buf, const char *fmt, struct tm *tm, int initialize)
+{
+ unsigned char c;
+ const unsigned char *bp;
+ size_t len;
+ int alt_format, i;
+ static int century, relyear;
+
+ if (initialize) {
+ century = TM_YEAR_BASE;
+ relyear = -1;
+ }
+
+ bp = (unsigned char *)buf;
+ while ((c = *fmt) != '\0') {
+ /* Clear `alternate' modifier prior to new conversion. */
+ alt_format = 0;
+
+ /* Eat up white-space. */
+ if (isspace(c)) {
+ while (isspace(*bp))
+ bp++;
+
+ fmt++;
+ continue;
+ }
+
+ if ((c = *fmt++) != '%')
+ goto literal;
+
+
+again: switch (c = *fmt++) {
+ case '%': /* "%%" is converted to "%". */
+literal:
+ if (c != *bp++)
+ return (NULL);
+
+ break;
+
+ /*
+ * "Alternative" modifiers. Just set the appropriate flag
+ * and start over again.
+ */
+ case 'E': /* "%E?" alternative conversion modifier. */
+ _LEGAL_ALT(0);
+ alt_format |= _ALT_E;
+ goto again;
+
+ case 'O': /* "%O?" alternative conversion modifier. */
+ _LEGAL_ALT(0);
+ alt_format |= _ALT_O;
+ goto again;
+
+ /*
+ * "Complex" conversion rules, implemented through recursion.
+ */
+#if 0
+ case 'c': /* Date and time, using the locale's format. */
+ _LEGAL_ALT(_ALT_E);
+ if (!(bp = _strptime(bp, _ctloc(d_t_fmt), tm, 0)))
+ return (NULL);
+ break;
+#endif
+ case 'D': /* The date as "%m/%d/%y". */
+ _LEGAL_ALT(0);
+ if (!(bp = _strptime(bp, "%m/%d/%y", tm, 0)))
+ return (NULL);
+ break;
+
+ case 'R': /* The time as "%H:%M". */
+ _LEGAL_ALT(0);
+ if (!(bp = _strptime(bp, "%H:%M", tm, 0)))
+ return (NULL);
+ break;
+
+ case 'r': /* The time as "%I:%M:%S %p". */
+ _LEGAL_ALT(0);
+ if (!(bp = _strptime(bp, "%I:%M:%S %p", tm, 0)))
+ return (NULL);
+ break;
+
+ case 'T': /* The time as "%H:%M:%S". */
+ _LEGAL_ALT(0);
+ if (!(bp = _strptime(bp, "%H:%M:%S", tm, 0)))
+ return (NULL);
+ break;
+#if 0
+ case 'X': /* The time, using the locale's format. */
+ _LEGAL_ALT(_ALT_E);
+ if (!(bp = _strptime(bp, _ctloc(t_fmt), tm, 0)))
+ return (NULL);
+ break;
+
+ case 'x': /* The date, using the locale's format. */
+ _LEGAL_ALT(_ALT_E);
+ if (!(bp = _strptime(bp, _ctloc(d_fmt), tm, 0)))
+ return (NULL);
+ break;
+#endif
+ /*
+ * "Elementary" conversion rules.
+ */
+#if 0
+ case 'A': /* The day of week, using the locale's form. */
+ case 'a':
+ _LEGAL_ALT(0);
+ for (i = 0; i < 7; i++) {
+ /* Full name. */
+ len = strlen(_ctloc(day[i]));
+ if (strncasecmp(_ctloc(day[i]), bp, len) == 0)
+ break;
+
+ /* Abbreviated name. */
+ len = strlen(_ctloc(abday[i]));
+ if (strncasecmp(_ctloc(abday[i]), bp, len) == 0)
+ break;
+ }
+
+ /* Nothing matched. */
+ if (i == 7)
+ return (NULL);
+
+ tm->tm_wday = i;
+ bp += len;
+ break;
+
+ case 'B': /* The month, using the locale's form. */
+ case 'b':
+ case 'h':
+ _LEGAL_ALT(0);
+ for (i = 0; i < 12; i++) {
+ /* Full name. */
+ len = strlen(_ctloc(mon[i]));
+ if (strncasecmp(_ctloc(mon[i]), bp, len) == 0)
+ break;
+
+ /* Abbreviated name. */
+ len = strlen(_ctloc(abmon[i]));
+ if (strncasecmp(_ctloc(abmon[i]), bp, len) == 0)
+ break;
+ }
+
+ /* Nothing matched. */
+ if (i == 12)
+ return (NULL);
+
+ tm->tm_mon = i;
+ bp += len;
+ break;
+#endif
+
+ case 'C': /* The century number. */
+ _LEGAL_ALT(_ALT_E);
+ if (!(_conv_num(&bp, &i, 0, 99)))
+ return (NULL);
+
+ century = i * 100;
+ break;
+
+ case 'd': /* The day of month. */
+ case 'e':
+ _LEGAL_ALT(_ALT_O);
+ if (!(_conv_num(&bp, &tm->tm_mday, 1, 31)))
+ return (NULL);
+ break;
+
+ case 'k': /* The hour (24-hour clock representation). */
+ _LEGAL_ALT(0);
+ /* FALLTHROUGH */
+ case 'H':
+ _LEGAL_ALT(_ALT_O);
+ if (!(_conv_num(&bp, &tm->tm_hour, 0, 23)))
+ return (NULL);
+ break;
+
+ case 'l': /* The hour (12-hour clock representation). */
+ _LEGAL_ALT(0);
+ /* FALLTHROUGH */
+ case 'I':
+ _LEGAL_ALT(_ALT_O);
+ if (!(_conv_num(&bp, &tm->tm_hour, 1, 12)))
+ return (NULL);
+ break;
+
+ case 'j': /* The day of year. */
+ _LEGAL_ALT(0);
+ if (!(_conv_num(&bp, &tm->tm_yday, 1, 366)))
+ return (NULL);
+ tm->tm_yday--;
+ break;
+
+ case 'M': /* The minute. */
+ _LEGAL_ALT(_ALT_O);
+ if (!(_conv_num(&bp, &tm->tm_min, 0, 59)))
+ return (NULL);
+ break;
+
+ case 'm': /* The month. */
+ _LEGAL_ALT(_ALT_O);
+ if (!(_conv_num(&bp, &tm->tm_mon, 1, 12)))
+ return (NULL);
+ tm->tm_mon--;
+ break;
+
+#if 0
+ case 'p': /* The locale's equivalent of AM/PM. */
+ _LEGAL_ALT(0);
+ /* AM? */
+ len = strlen(_ctloc(am_pm[0]));
+ if (strncasecmp(_ctloc(am_pm[0]), bp, len) == 0) {
+ if (tm->tm_hour > 12) /* i.e., 13:00 AM ?! */
+ return (NULL);
+ else if (tm->tm_hour == 12)
+ tm->tm_hour = 0;
+
+ bp += len;
+ break;
+ }
+ /* PM? */
+ len = strlen(_ctloc(am_pm[1]));
+ if (strncasecmp(_ctloc(am_pm[1]), bp, len) == 0) {
+ if (tm->tm_hour > 12) /* i.e., 13:00 PM ?! */
+ return (NULL);
+ else if (tm->tm_hour < 12)
+ tm->tm_hour += 12;
+
+ bp += len;
+ break;
+ }
+
+ /* Nothing matched. */
+ return (NULL);
+#endif
+ case 'S': /* The seconds. */
+ _LEGAL_ALT(_ALT_O);
+ if (!(_conv_num(&bp, &tm->tm_sec, 0, 61)))
+ return (NULL);
+ break;
+
+ case 'U': /* The week of year, beginning on sunday. */
+ case 'W': /* The week of year, beginning on monday. */
+ _LEGAL_ALT(_ALT_O);
+ /*
+ * XXX This is bogus, as we can not assume any valid
+ * information present in the tm structure at this
+ * point to calculate a real value, so just check the
+ * range for now.
+ */
+ if (!(_conv_num(&bp, &i, 0, 53)))
+ return (NULL);
+ break;
+
+ case 'w': /* The day of week, beginning on sunday. */
+ _LEGAL_ALT(_ALT_O);
+ if (!(_conv_num(&bp, &tm->tm_wday, 0, 6)))
+ return (NULL);
+ break;
+
+ case 'Y': /* The year. */
+ _LEGAL_ALT(_ALT_E);
+ if (!(_conv_num(&bp, &i, 0, 9999)))
+ return (NULL);
+
+ relyear = -1;
+ tm->tm_year = i - TM_YEAR_BASE;
+ break;
+
+ case 'y': /* The year within the century (2 digits). */
+ _LEGAL_ALT(_ALT_E | _ALT_O);
+ if (!(_conv_num(&bp, &relyear, 0, 99)))
+ return (NULL);
+ break;
+
+ /*
+ * Miscellaneous conversions.
+ */
+ case 'n': /* Any kind of white-space. */
+ case 't':
+ _LEGAL_ALT(0);
+ while (isspace(*bp))
+ bp++;
+ break;
+
+
+ default: /* Unknown/unsupported conversion. */
+ return (NULL);
+ }
+
+
+ }
+
+ /*
+ * We need to evaluate the two digit year spec (%y)
+ * last as we can get a century spec (%C) at any time.
+ */
+ if (relyear != -1) {
+ if (century == TM_YEAR_BASE) {
+ if (relyear <= 68)
+ tm->tm_year = relyear + 2000 - TM_YEAR_BASE;
+ else
+ tm->tm_year = relyear + 1900 - TM_YEAR_BASE;
+ } else {
+ tm->tm_year = relyear + century - TM_YEAR_BASE;
+ }
+ }
+
+ return ((char *)bp);
+}
+
+
+static int
+_conv_num(const unsigned char **buf, int *dest, int llim, int ulim)
+{
+ int result = 0;
+ int rulim = ulim;
+
+ if (**buf < '0' || **buf > '9')
+ return (0);
+
+ /* we use rulim to break out of the loop when we run out of digits */
+ do {
+ result *= 10;
+ result += *(*buf)++ - '0';
+ rulim /= 10;
+ } while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9');
+
+ if (result < llim || result > ulim)
+ return (0);
+
+ *dest = result;
+ return (1);
+}
+
+#endif /* HAVE_STRPTIME */
+
diff --git a/packet.c b/packet.c
index 994e35b6df50..48f7fe61332d 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.c,v 1.166 2009/06/27 09:29:06 andreas Exp $ */
+/* $OpenBSD: packet.c,v 1.168 2010/07/13 23:13:16 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1307,7 +1307,7 @@ packet_read_poll2(u_int32_t *seqnr_p)
macbuf = mac_compute(mac, active_state->p_read.seqnr,
buffer_ptr(&active_state->incoming_packet),
buffer_len(&active_state->incoming_packet));
- if (memcmp(macbuf, buffer_ptr(&active_state->input),
+ if (timingsafe_bcmp(macbuf, buffer_ptr(&active_state->input),
mac->mac_len) != 0) {
logit("Corrupted MAC on input.");
if (need > PACKET_MAX_SIZE)
diff --git a/readconf.c b/readconf.c
index 8bdc8caf1abd..0296590e2f41 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.183 2010/02/08 10:50:20 markus Exp $ */
+/* $OpenBSD: readconf.c,v 1.187 2010/07/19 09:15:12 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -110,8 +110,8 @@
typedef enum {
oBadOption,
- oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
- oExitOnForwardFailure,
+ oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
+ oGatewayPorts, oExitOnForwardFailure,
oPasswordAuthentication, oRSAAuthentication,
oChallengeResponseAuthentication, oXAuthLocation,
oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
@@ -128,7 +128,8 @@ typedef enum {
oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
oAddressFamily, oGssAuthentication, oGssDelegateCreds,
oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
- oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
+ oSendEnv, oControlPath, oControlMaster, oControlPersist,
+ oHashKnownHosts,
oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
oDeprecated, oUnsupported
@@ -143,6 +144,7 @@ static struct {
{ "forwardagent", oForwardAgent },
{ "forwardx11", oForwardX11 },
{ "forwardx11trusted", oForwardX11Trusted },
+ { "forwardx11timeout", oForwardX11Timeout },
{ "exitonforwardfailure", oExitOnForwardFailure },
{ "xauthlocation", oXAuthLocation },
{ "gatewayports", oGatewayPorts },
@@ -224,6 +226,7 @@ static struct {
{ "sendenv", oSendEnv },
{ "controlpath", oControlPath },
{ "controlmaster", oControlMaster },
+ { "controlpersist", oControlPersist },
{ "hashknownhosts", oHashKnownHosts },
{ "tunnel", oTunnel },
{ "tunneldevice", oTunnelDevice },
@@ -255,8 +258,9 @@ add_local_forward(Options *options, const Forward *newfwd)
if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
fatal("Privileged ports can only be forwarded by root.");
#endif
- if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
- fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
+ options->local_forwards = xrealloc(options->local_forwards,
+ options->num_local_forwards + 1,
+ sizeof(*options->local_forwards));
fwd = &options->local_forwards[options->num_local_forwards++];
fwd->listen_host = newfwd->listen_host;
@@ -274,15 +278,17 @@ void
add_remote_forward(Options *options, const Forward *newfwd)
{
Forward *fwd;
- if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
- fatal("Too many remote forwards (max %d).",
- SSH_MAX_FORWARDS_PER_DIRECTION);
+
+ options->remote_forwards = xrealloc(options->remote_forwards,
+ options->num_remote_forwards + 1,
+ sizeof(*options->remote_forwards));
fwd = &options->remote_forwards[options->num_remote_forwards++];
fwd->listen_host = newfwd->listen_host;
fwd->listen_port = newfwd->listen_port;
fwd->connect_host = newfwd->connect_host;
fwd->connect_port = newfwd->connect_port;
+ fwd->allocated_port = 0;
}
static void
@@ -295,12 +301,20 @@ clear_forwardings(Options *options)
xfree(options->local_forwards[i].listen_host);
xfree(options->local_forwards[i].connect_host);
}
+ if (options->num_local_forwards > 0) {
+ xfree(options->local_forwards);
+ options->local_forwards = NULL;
+ }
options->num_local_forwards = 0;
for (i = 0; i < options->num_remote_forwards; i++) {
if (options->remote_forwards[i].listen_host != NULL)
xfree(options->remote_forwards[i].listen_host);
xfree(options->remote_forwards[i].connect_host);
}
+ if (options->num_remote_forwards > 0) {
+ xfree(options->remote_forwards);
+ options->remote_forwards = NULL;
+ }
options->num_remote_forwards = 0;
options->tun_open = SSH_TUNMODE_NO;
}
@@ -403,6 +417,10 @@ parse_flag:
case oForwardX11Trusted:
intptr = &options->forward_x11_trusted;
goto parse_flag;
+
+ case oForwardX11Timeout:
+ intptr = &options->forward_x11_timeout;
+ goto parse_time;
case oGatewayPorts:
intptr = &options->gateway_ports;
@@ -866,6 +884,30 @@ parse_int:
*intptr = value;
break;
+ case oControlPersist:
+ /* no/false/yes/true, or a time spec */
+ intptr = &options->control_persist;
+ arg = strdelim(&s);
+ if (!arg || *arg == '\0')
+ fatal("%.200s line %d: Missing ControlPersist"
+ " argument.", filename, linenum);
+ value = 0;
+ value2 = 0; /* timeout */
+ if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
+ value = 0;
+ else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
+ value = 1;
+ else if ((value2 = convtime(arg)) >= 0)
+ value = 1;
+ else
+ fatal("%.200s line %d: Bad ControlPersist argument.",
+ filename, linenum);
+ if (*activep && *intptr == -1) {
+ *intptr = value;
+ options->control_persist_timeout = value2;
+ }
+ break;
+
case oHashKnownHosts:
intptr = &options->hash_known_hosts;
goto parse_flag;
@@ -1007,6 +1049,7 @@ initialize_options(Options * options)
options->forward_agent = -1;
options->forward_x11 = -1;
options->forward_x11_trusted = -1;
+ options->forward_x11_timeout = -1;
options->exit_on_forward_failure = -1;
options->xauth_location = NULL;
options->gateway_ports = -1;
@@ -1047,7 +1090,9 @@ initialize_options(Options * options)
options->user_hostfile = NULL;
options->system_hostfile2 = NULL;
options->user_hostfile2 = NULL;
+ options->local_forwards = NULL;
options->num_local_forwards = 0;
+ options->remote_forwards = NULL;
options->num_remote_forwards = 0;
options->clear_forwardings = -1;
options->log_level = SYSLOG_LEVEL_NOT_SET;
@@ -1064,6 +1109,8 @@ initialize_options(Options * options)
options->num_send_env = 0;
options->control_path = NULL;
options->control_master = -1;
+ options->control_persist = -1;
+ options->control_persist_timeout = 0;
options->hash_known_hosts = -1;
options->tun_open = -1;
options->tun_local = -1;
@@ -1091,6 +1138,8 @@ fill_default_options(Options * options)
options->forward_x11 = 0;
if (options->forward_x11_trusted == -1)
options->forward_x11_trusted = 0;
+ if (options->forward_x11_timeout == -1)
+ options->forward_x11_timeout = 1200;
if (options->exit_on_forward_failure == -1)
options->exit_on_forward_failure = 0;
if (options->xauth_location == NULL)
@@ -1197,6 +1246,10 @@ fill_default_options(Options * options)
options->server_alive_count_max = 3;
if (options->control_master == -1)
options->control_master = 0;
+ if (options->control_persist == -1) {
+ options->control_persist = 0;
+ options->control_persist_timeout = 0;
+ }
if (options->hash_known_hosts == -1)
options->hash_known_hosts = 0;
if (options->tun_open == -1)
diff --git a/readconf.h b/readconf.h
index 4264751c516c..95d104674724 100644
--- a/readconf.h
+++ b/readconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.h,v 1.82 2010/02/08 10:50:20 markus Exp $ */
+/* $OpenBSD: readconf.h,v 1.86 2010/07/19 09:15:12 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -23,6 +23,7 @@ typedef struct {
int listen_port; /* Port to forward. */
char *connect_host; /* Host to connect. */
int connect_port; /* Port to connect on connect_host. */
+ int allocated_port; /* Dynamically allocated listen port */
} Forward;
/* Data structure for representing option data. */
@@ -31,6 +32,7 @@ typedef struct {
typedef struct {
int forward_agent; /* Forward authentication agent. */
int forward_x11; /* Forward X11 display. */
+ int forward_x11_timeout; /* Expiration for Cookies */
int forward_x11_trusted; /* Trust Forward X11 display. */
int exit_on_forward_failure; /* Exit if bind(2) fails for -L/-R */
char *xauth_location; /* Location for xauth program */
@@ -93,11 +95,11 @@ typedef struct {
/* Local TCP/IP forward requests. */
int num_local_forwards;
- Forward local_forwards[SSH_MAX_FORWARDS_PER_DIRECTION];
+ Forward *local_forwards;
/* Remote TCP/IP forward requests. */
int num_remote_forwards;
- Forward remote_forwards[SSH_MAX_FORWARDS_PER_DIRECTION];
+ Forward *remote_forwards;
int clear_forwardings;
int enable_ssh_keysign;
@@ -112,6 +114,8 @@ typedef struct {
char *control_path;
int control_master;
+ int control_persist; /* ControlPersist flag */
+ int control_persist_timeout; /* ControlPersist timeout (seconds) */
int hash_known_hosts;
diff --git a/regress/Makefile b/regress/Makefile
index d25a64555214..9762ab204ed1 100644
--- a/regress/Makefile
+++ b/regress/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.52 2010/02/26 20:33:21 djm Exp $
+# $OpenBSD: Makefile,v 1.54 2010/06/27 19:19:56 phessler Exp $
REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t-exec
tests: $(REGRESS_TARGETS)
@@ -69,7 +69,8 @@ CLEANFILES= t2.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \
scp-ssh-wrapper.scp ssh_proxy_envpass remote_pid \
sshd_proxy_bak rsa_ssh2_cr.prv rsa_ssh2_crnl.prv \
known_hosts-cert host_ca_key* cert_host_key* \
- putty.rsa2 sshd_proxy_orig
+ putty.rsa2 sshd_proxy_orig \
+ authorized_principals_${USER}
# Enable all malloc(3) randomisations and checks
TEST_ENV= "MALLOC_OPTIONS=AFGJPRX"
@@ -112,13 +113,13 @@ t-exec: ${LTESTS:=.sh}
@if [ "x$?" = "x" ]; then exit 0; fi; \
for TEST in ""$?; do \
echo "run test $${TEST}" ... 1>&2; \
- (env SUDO=${SUDO} TEST_ENV=${TEST_ENV} sh ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \
+ (env SUDO="${SUDO}" TEST_ENV=${TEST_ENV} sh ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \
done
t-exec-interop: ${INTEROP_TESTS:=.sh}
@if [ "x$?" = "x" ]; then exit 0; fi; \
for TEST in ""$?; do \
echo "run test $${TEST}" ... 1>&2; \
- (env SUDO=${SUDO} TEST_ENV=${TEST_ENV} sh ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \
+ (env SUDO="${SUDO}" TEST_ENV=${TEST_ENV} sh ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \
done
diff --git a/regress/README.regress b/regress/README.regress
index 5aaf734bde92..da9bb6a99c9d 100644
--- a/regress/README.regress
+++ b/regress/README.regress
@@ -29,7 +29,7 @@ TEST_SSH_x: path to "ssh" command under test, where x=SSH,SSHD,SSHAGENT,SSHADD
OBJ: used by test scripts to access build dir.
TEST_SHELL: shell used for running the test scripts.
TEST_SSH_PORT: TCP port to be used for the listening tests.
-TEST_SSH_SSH_CONFOTPS: Configuration directives to be added to ssh_config
+TEST_SSH_SSH_CONFOPTS: Configuration directives to be added to ssh_config
before running each test.
TEST_SSH_SSHD_CONFOTPS: Configuration directives to be added to sshd_config
before running each test.
@@ -105,4 +105,4 @@ Known Issues.
test to fail. The old behaviour can be restored by setting (and
exporting) _POSIX2_VERSION=199209 before running the tests.
-$Id: README.regress,v 1.10 2005/10/03 10:14:18 dtucker Exp $
+$Id: README.regress,v 1.11 2010/08/16 21:04:29 djm Exp $
diff --git a/regress/cert-hostkey.sh b/regress/cert-hostkey.sh
index 3fda667cbab4..0265e8f6b04e 100755
--- a/regress/cert-hostkey.sh
+++ b/regress/cert-hostkey.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: cert-hostkey.sh,v 1.3 2010/03/04 10:38:23 djm Exp $
+# $OpenBSD: cert-hostkey.sh,v 1.4 2010/04/16 01:58:45 djm Exp $
# Placed in the Public Domain.
tid="certified host keys"
@@ -28,11 +28,17 @@ for ktype in rsa dsa ; do
-I "regress host key for $USER" \
-n $HOSTS $OBJ/cert_host_key_${ktype} ||
fail "couldn't sign cert_host_key_${ktype}"
+ cp $OBJ/cert_host_key_${ktype} $OBJ/cert_host_key_${ktype}_v00
+ cp $OBJ/cert_host_key_${ktype}.pub $OBJ/cert_host_key_${ktype}_v00.pub
+ ${SSHKEYGEN} -t v00 -h -q -s $OBJ/host_ca_key \
+ -I "regress host key for $USER" \
+ -n $HOSTS $OBJ/cert_host_key_${ktype}_v00 ||
+ fail "couldn't sign cert_host_key_${ktype}_v00"
done
# Basic connect tests
for privsep in yes no ; do
- for ktype in rsa dsa ; do
+ for ktype in rsa dsa rsa_v00 dsa_v00; do
verbose "$tid: host ${ktype} cert connect privsep $privsep"
(
cat $OBJ/sshd_proxy_bak
@@ -61,9 +67,15 @@ done
echon '@revoked '
echon "* "
cat $OBJ/cert_host_key_dsa.pub
+ echon '@revoked '
+ echon "* "
+ cat $OBJ/cert_host_key_rsa_v00.pub
+ echon '@revoked '
+ echon "* "
+ cat $OBJ/cert_host_key_dsa_v00.pub
) > $OBJ/known_hosts-cert
for privsep in yes no ; do
- for ktype in rsa dsa ; do
+ for ktype in rsa dsa rsa_v00 dsa_v00; do
verbose "$tid: host ${ktype} revoked cert privsep $privsep"
(
cat $OBJ/sshd_proxy_bak
@@ -90,7 +102,7 @@ done
echon "* "
cat $OBJ/host_ca_key.pub
) > $OBJ/known_hosts-cert
-for ktype in rsa dsa ; do
+for ktype in rsa dsa rsa_v00 dsa_v00 ; do
verbose "$tid: host ${ktype} revoked cert"
(
cat $OBJ/sshd_proxy_bak
@@ -116,32 +128,39 @@ test_one() {
ident=$1
result=$2
sign_opts=$3
-
- verbose "$tid: test host cert connect $ident expect $result"
-
- ${SSHKEYGEN} -q -s $OBJ/host_ca_key -I "regress host key for $USER" \
- $sign_opts \
- $OBJ/cert_host_key_rsa ||
- fail "couldn't sign cert_host_key_rsa"
- (
- cat $OBJ/sshd_proxy_bak
- echo HostKey $OBJ/cert_host_key_rsa
- echo HostCertificate $OBJ/cert_host_key_rsa-cert.pub
- ) > $OBJ/sshd_proxy
- ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
- -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
- -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
- rc=$?
- if [ "x$result" = "xsuccess" ] ; then
- if [ $rc -ne 0 ]; then
- fail "ssh cert connect $ident failed unexpectedly"
- fi
- else
- if [ $rc -eq 0 ]; then
- fail "ssh cert connect $ident succeeded unexpectedly"
+ for kt in rsa rsa_v00 ; do
+ case $kt in
+ *_v00) args="-t v00" ;;
+ *) args="" ;;
+ esac
+
+ verbose "$tid: host cert connect $ident $kt expect $result"
+ ${SSHKEYGEN} -q -s $OBJ/host_ca_key \
+ -I "regress host key for $USER" \
+ $sign_opts $args \
+ $OBJ/cert_host_key_${kt} ||
+ fail "couldn't sign cert_host_key_${kt}"
+ (
+ cat $OBJ/sshd_proxy_bak
+ echo HostKey $OBJ/cert_host_key_${kt}
+ echo HostCertificate $OBJ/cert_host_key_${kt}-cert.pub
+ ) > $OBJ/sshd_proxy
+
+ ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
+ -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ rc=$?
+ if [ "x$result" = "xsuccess" ] ; then
+ if [ $rc -ne 0 ]; then
+ fail "ssh cert connect $ident failed unexpectedly"
+ fi
+ else
+ if [ $rc -eq 0 ]; then
+ fail "ssh cert connect $ident succeeded unexpectedly"
+ fi
fi
- fi
+ done
}
test_one "user-certificate" failure "-n $HOSTS"
@@ -153,32 +172,35 @@ test_one "cert valid interval" success "-h -V-1w:+2w"
test_one "cert has constraints" failure "-h -Oforce-command=false"
# Check downgrade of cert to raw key when no CA found
-rm -f $OBJ/known_hosts-cert $OBJ/cert_host_key*
-for ktype in rsa dsa ; do
- verbose "$tid: host ${ktype} cert downgrade to raw key"
- # Generate and sign a host key
- ${SSHKEYGEN} -q -N '' -t ${ktype} \
- -f $OBJ/cert_host_key_${ktype} || \
- fail "ssh-keygen of cert_host_key_${ktype} failed"
- ${SSHKEYGEN} -h -q -s $OBJ/host_ca_key -I "regress host key for $USER" \
- -n $HOSTS $OBJ/cert_host_key_${ktype} ||
- fail "couldn't sign cert_host_key_${ktype}"
- (
- echon "$HOSTS "
- cat $OBJ/cert_host_key_${ktype}.pub
- ) > $OBJ/known_hosts-cert
- (
- cat $OBJ/sshd_proxy_bak
- echo HostKey $OBJ/cert_host_key_${ktype}
- echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub
- ) > $OBJ/sshd_proxy
-
- ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
- -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
- -F $OBJ/ssh_proxy somehost true
- if [ $? -ne 0 ]; then
- fail "ssh cert connect failed"
- fi
+for v in v01 v00 ; do
+ for ktype in rsa dsa ; do
+ rm -f $OBJ/known_hosts-cert $OBJ/cert_host_key*
+ verbose "$tid: host ${ktype} ${v} cert downgrade to raw key"
+ # Generate and sign a host key
+ ${SSHKEYGEN} -q -N '' -t ${ktype} \
+ -f $OBJ/cert_host_key_${ktype} || \
+ fail "ssh-keygen of cert_host_key_${ktype} failed"
+ ${SSHKEYGEN} -t ${v} -h -q -s $OBJ/host_ca_key \
+ -I "regress host key for $USER" \
+ -n $HOSTS $OBJ/cert_host_key_${ktype} ||
+ fail "couldn't sign cert_host_key_${ktype}"
+ (
+ echon "$HOSTS "
+ cat $OBJ/cert_host_key_${ktype}.pub
+ ) > $OBJ/known_hosts-cert
+ (
+ cat $OBJ/sshd_proxy_bak
+ echo HostKey $OBJ/cert_host_key_${ktype}
+ echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub
+ ) > $OBJ/sshd_proxy
+
+ ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
+ -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
+ -F $OBJ/ssh_proxy somehost true
+ if [ $? -ne 0 ]; then
+ fail "ssh cert connect failed"
+ fi
+ done
done
# Wrong certificate
@@ -187,25 +209,31 @@ done
echon "$HOSTS "
cat $OBJ/host_ca_key.pub
) > $OBJ/known_hosts-cert
-for ktype in rsa dsa ; do
- # Self-sign key
- ${SSHKEYGEN} -h -q -s $OBJ/cert_host_key_${ktype} \
- -I "regress host key for $USER" \
- -n $HOSTS $OBJ/cert_host_key_${ktype} ||
- fail "couldn't sign cert_host_key_${ktype}"
- verbose "$tid: host ${ktype} connect wrong cert"
- (
- cat $OBJ/sshd_proxy_bak
- echo HostKey $OBJ/cert_host_key_${ktype}
- echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub
- ) > $OBJ/sshd_proxy
-
- ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
- -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
- -F $OBJ/ssh_proxy -q somehost true >/dev/null 2>&1
- if [ $? -eq 0 ]; then
- fail "ssh cert connect $ident succeeded unexpectedly"
- fi
+for v in v01 v00 ; do
+ for kt in rsa dsa ; do
+ rm -f $OBJ/cert_host_key*
+ # Self-sign key
+ ${SSHKEYGEN} -q -N '' -t ${kt} \
+ -f $OBJ/cert_host_key_${kt} || \
+ fail "ssh-keygen of cert_host_key_${kt} failed"
+ ${SSHKEYGEN} -t ${v} -h -q -s $OBJ/cert_host_key_${kt} \
+ -I "regress host key for $USER" \
+ -n $HOSTS $OBJ/cert_host_key_${kt} ||
+ fail "couldn't sign cert_host_key_${kt}"
+ verbose "$tid: host ${kt} connect wrong cert"
+ (
+ cat $OBJ/sshd_proxy_bak
+ echo HostKey $OBJ/cert_host_key_${kt}
+ echo HostCertificate $OBJ/cert_host_key_${kt}-cert.pub
+ ) > $OBJ/sshd_proxy
+
+ ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
+ -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
+ -F $OBJ/ssh_proxy -q somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect $ident succeeded unexpectedly"
+ fi
+ done
done
rm -f $OBJ/known_hosts-cert $OBJ/host_ca_key* $OBJ/cert_host_key*
diff --git a/regress/cert-userkey.sh b/regress/cert-userkey.sh
index 7a58e7b75f30..a41a9a9c012b 100755
--- a/regress/cert-userkey.sh
+++ b/regress/cert-userkey.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: cert-userkey.sh,v 1.3 2010/03/04 10:38:23 djm Exp $
+# $OpenBSD: cert-userkey.sh,v 1.6 2010/06/29 23:59:54 djm Exp $
# Placed in the Public Domain.
tid="certified user keys"
@@ -18,8 +18,128 @@ for ktype in rsa dsa ; do
fail "ssh-keygen of cert_user_key_${ktype} failed"
${SSHKEYGEN} -q -s $OBJ/user_ca_key -I \
"regress user key for $USER" \
- -n $USER $OBJ/cert_user_key_${ktype} ||
+ -n ${USER},mekmitasdigoat $OBJ/cert_user_key_${ktype} ||
fail "couldn't sign cert_user_key_${ktype}"
+ cp $OBJ/cert_user_key_${ktype} $OBJ/cert_user_key_${ktype}_v00
+ cp $OBJ/cert_user_key_${ktype}.pub $OBJ/cert_user_key_${ktype}_v00.pub
+ ${SSHKEYGEN} -q -t v00 -s $OBJ/user_ca_key -I \
+ "regress user key for $USER" \
+ -n ${USER},mekmitasdigoat $OBJ/cert_user_key_${ktype}_v00 ||
+ fail "couldn't sign cert_user_key_${ktype}_v00"
+done
+
+# Test explicitly-specified principals
+for ktype in rsa dsa rsa_v00 dsa_v00 ; do
+ for privsep in yes no ; do
+ _prefix="${ktype} privsep $privsep"
+
+ # Setup for AuthorizedPrincipalsFile
+ rm -f $OBJ/authorized_keys_$USER
+ (
+ cat $OBJ/sshd_proxy_bak
+ echo "UsePrivilegeSeparation $privsep"
+ echo "AuthorizedPrincipalsFile " \
+ "$OBJ/authorized_principals_%u"
+ echo "TrustedUserCAKeys $OBJ/user_ca_key.pub"
+ ) > $OBJ/sshd_proxy
+
+ # Missing authorized_principals
+ verbose "$tid: ${_prefix} missing authorized_principals"
+ rm -f $OBJ/authorized_principals_$USER
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect succeeded unexpectedly"
+ fi
+
+ # Empty authorized_principals
+ verbose "$tid: ${_prefix} empty authorized_principals"
+ echo > $OBJ/authorized_principals_$USER
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect succeeded unexpectedly"
+ fi
+
+ # Wrong authorized_principals
+ verbose "$tid: ${_prefix} wrong authorized_principals"
+ echo gregorsamsa > $OBJ/authorized_principals_$USER
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect succeeded unexpectedly"
+ fi
+
+ # Correct authorized_principals
+ verbose "$tid: ${_prefix} correct authorized_principals"
+ echo mekmitasdigoat > $OBJ/authorized_principals_$USER
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ fail "ssh cert connect failed"
+ fi
+
+ # authorized_principals with bad key option
+ verbose "$tid: ${_prefix} authorized_principals bad key opt"
+ echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect succeeded unexpectedly"
+ fi
+
+ # authorized_principals with command=false
+ verbose "$tid: ${_prefix} authorized_principals command=false"
+ echo 'command="false" mekmitasdigoat' > \
+ $OBJ/authorized_principals_$USER
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect succeeded unexpectedly"
+ fi
+
+
+ # authorized_principals with command=true
+ verbose "$tid: ${_prefix} authorized_principals command=true"
+ echo 'command="true" mekmitasdigoat' > \
+ $OBJ/authorized_principals_$USER
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost false >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ fail "ssh cert connect failed"
+ fi
+
+ # Setup for principals= key option
+ rm -f $OBJ/authorized_principals_$USER
+ (
+ cat $OBJ/sshd_proxy_bak
+ echo "UsePrivilegeSeparation $privsep"
+ ) > $OBJ/sshd_proxy
+
+ # Wrong principals list
+ verbose "$tid: ${_prefix} wrong principals key option"
+ (
+ echon 'cert-authority,principals="gregorsamsa" '
+ cat $OBJ/user_ca_key.pub
+ ) > $OBJ/authorized_keys_$USER
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect succeeded unexpectedly"
+ fi
+
+ # Correct principals list
+ verbose "$tid: ${_prefix} correct principals key option"
+ (
+ echon 'cert-authority,principals="mekmitasdigoat" '
+ cat $OBJ/user_ca_key.pub
+ ) > $OBJ/authorized_keys_$USER
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ fail "ssh cert connect failed"
+ fi
+ done
done
basic_tests() {
@@ -35,7 +155,7 @@ basic_tests() {
extra_sshd="TrustedUserCAKeys $OBJ/user_ca_key.pub"
fi
- for ktype in rsa dsa ; do
+ for ktype in rsa dsa rsa_v00 dsa_v00 ; do
for privsep in yes no ; do
_prefix="${ktype} privsep $privsep $auth"
# Simple connect
@@ -102,45 +222,50 @@ test_one() {
result=$2
sign_opts=$3
auth_choice=$4
+ auth_opt=$5
if test "x$auth_choice" = "x" ; then
auth_choice="authorized_keys TrustedUserCAKeys"
fi
for auth in $auth_choice ; do
- cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy
- if test "x$auth" = "xauthorized_keys" ; then
- # Add CA to authorized_keys
- (
- echon 'cert-authority '
- cat $OBJ/user_ca_key.pub
- ) > $OBJ/authorized_keys_$USER
- else
- echo > $OBJ/authorized_keys_$USER
- echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" >> \
- $OBJ/sshd_proxy
-
- fi
-
- verbose "$tid: $ident auth $auth expect $result"
- ${SSHKEYGEN} -q -s $OBJ/user_ca_key \
- -I "regress user key for $USER" \
- $sign_opts \
- $OBJ/cert_user_key_rsa ||
- fail "couldn't sign cert_user_key_rsa"
-
- ${SSH} -2i $OBJ/cert_user_key_rsa -F $OBJ/ssh_proxy \
- somehost true >/dev/null 2>&1
- rc=$?
- if [ "x$result" = "xsuccess" ] ; then
- if [ $rc -ne 0 ]; then
- fail "$ident failed unexpectedly"
+ for ktype in rsa rsa_v00 ; do
+ cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy
+ if test "x$auth" = "xauthorized_keys" ; then
+ # Add CA to authorized_keys
+ (
+ echon "cert-authority${auth_opt} "
+ cat $OBJ/user_ca_key.pub
+ ) > $OBJ/authorized_keys_$USER
+ else
+ echo > $OBJ/authorized_keys_$USER
+ echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" \
+ >> $OBJ/sshd_proxy
+ if test "x$auth_opt" != "x" ; then
+ echo $auth_opt >> $OBJ/sshd_proxy
+ fi
fi
- else
- if [ $rc -eq 0 ]; then
- fail "$ident succeeded unexpectedly"
+
+ verbose "$tid: $ident auth $auth expect $result $ktype"
+ ${SSHKEYGEN} -q -s $OBJ/user_ca_key \
+ -I "regress user key for $USER" \
+ $sign_opts \
+ $OBJ/cert_user_key_${ktype} ||
+ fail "couldn't sign cert_user_key_${ktype}"
+
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ rc=$?
+ if [ "x$result" = "xsuccess" ] ; then
+ if [ $rc -ne 0 ]; then
+ fail "$ident failed unexpectedly"
+ fi
+ else
+ if [ $rc -eq 0 ]; then
+ fail "$ident succeeded unexpectedly"
+ fi
fi
- fi
+ done
done
}
@@ -157,10 +282,33 @@ test_one "force-command" failure "-n ${USER} -Oforce-command=false"
test_one "empty principals" success "" authorized_keys
test_one "empty principals" failure "" TrustedUserCAKeys
+# Check explicitly-specified principals: an empty principals list in the cert
+# should always be refused.
+
+# AuthorizedPrincipalsFile
+rm -f $OBJ/authorized_keys_$USER
+echo mekmitasdigoat > $OBJ/authorized_principals_$USER
+test_one "AuthorizedPrincipalsFile principals" success "-n mekmitasdigoat" \
+ TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u"
+test_one "AuthorizedPrincipalsFile no principals" failure "" \
+ TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u"
+
+# principals= key option
+rm -f $OBJ/authorized_principals_$USER
+test_one "principals key option principals" success "-n mekmitasdigoat" \
+ authorized_keys ',principals="mekmitasdigoat"'
+test_one "principals key option no principals" failure "" \
+ authorized_keys ',principals="mekmitasdigoat"'
+
# Wrong certificate
-for ktype in rsa dsa ; do
+cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy
+for ktype in rsa dsa rsa_v00 dsa_v00 ; do
+ case $ktype in
+ *_v00) args="-t v00" ;;
+ *) args="" ;;
+ esac
# Self-sign
- ${SSHKEYGEN} -q -s $OBJ/cert_user_key_${ktype} -I \
+ ${SSHKEYGEN} $args -q -s $OBJ/cert_user_key_${ktype} -I \
"regress user key for $USER" \
-n $USER $OBJ/cert_user_key_${ktype} ||
fail "couldn't sign cert_user_key_${ktype}"
@@ -173,4 +321,5 @@ for ktype in rsa dsa ; do
done
rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key*
+rm -f $OBJ/authorized_principals_$USER
diff --git a/regress/login-timeout.sh b/regress/login-timeout.sh
index 15a887f74b1d..55fbb324d11c 100644
--- a/regress/login-timeout.sh
+++ b/regress/login-timeout.sh
@@ -15,7 +15,7 @@ if [ $? -ne 0 ]; then
fail "ssh connect after login grace timeout failed with privsep"
fi
-$SUDO kill `cat $PIDFILE`
+$SUDO kill `$SUDO cat $PIDFILE`
trace "test login grace without privsep"
echo "UsePrivilegeSeparation no" >> $OBJ/sshd_config
diff --git a/regress/reconfigure.sh b/regress/reconfigure.sh
index 1daf29f9a6e8..9fd2895314e4 100644
--- a/regress/reconfigure.sh
+++ b/regress/reconfigure.sh
@@ -15,7 +15,7 @@ esac
start_sshd
-PID=`cat $PIDFILE`
+PID=`$SUDO cat $PIDFILE`
rm -f $PIDFILE
$SUDO kill -HUP $PID
diff --git a/regress/reexec.sh b/regress/reexec.sh
index 4f824a31d961..6edfc318e897 100644
--- a/regress/reexec.sh
+++ b/regress/reexec.sh
@@ -41,7 +41,7 @@ echo "InvalidXXX=no" >> $OBJ/sshd_config
copy_tests
-$SUDO kill `cat $PIDFILE`
+$SUDO kill `$SUDO cat $PIDFILE`
rm -f $PIDFILE
cp $OBJ/sshd_config.orig $OBJ/sshd_config
@@ -53,7 +53,7 @@ rm -f $SSHD_COPY
copy_tests
-$SUDO kill `cat $PIDFILE`
+$SUDO kill `$SUDO cat $PIDFILE`
rm -f $PIDFILE
verbose "test reexec fallback without privsep"
@@ -66,7 +66,7 @@ rm -f $SSHD_COPY
copy_tests
-$SUDO kill `cat $PIDFILE`
+$SUDO kill `$SUDO cat $PIDFILE`
rm -f $PIDFILE
diff --git a/regress/test-exec.sh b/regress/test-exec.sh
index b3a19389dcf4..b64dcdbcf86c 100644
--- a/regress/test-exec.sh
+++ b/regress/test-exec.sh
@@ -167,7 +167,7 @@ have_prog()
cleanup ()
{
if [ -f $PIDFILE ]; then
- pid=`cat $PIDFILE`
+ pid=`$SUDO cat $PIDFILE`
if [ "X$pid" = "X" ]; then
echo no sshd running
else
diff --git a/scp.0 b/scp.0
index fc9f75594ab6..f5af8ccd5824 100644
--- a/scp.0
+++ b/scp.0
@@ -6,7 +6,7 @@ NAME
SYNOPSIS
scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
[-l limit] [-o ssh_option] [-P port] [-S program]
- [[user@]host1:]file1 ... [[user@]host2:]file2
+ [[user@]host1:]file1 ... [[user@]host2:]file2
DESCRIPTION
scp copies files between hosts on a network. It uses ssh(1) for data
@@ -15,8 +15,8 @@ DESCRIPTION
they are needed for authentication.
File names may contain a user and host specification to indicate that the
- file is to be copied to/from that host. Local file names can be made ex-
- plicit using absolute or relative pathnames to avoid scp treating file
+ file is to be copied to/from that host. Local file names can be made
+ explicit using absolute or relative pathnames to avoid scp treating file
names containing `:' as host specifiers. Copies between two remote hosts
are also permitted.
@@ -30,11 +30,11 @@ DESCRIPTION
-6 Forces scp to use IPv6 addresses only.
- -B Selects batch mode (prevents asking for passwords or passphras-
- es).
+ -B Selects batch mode (prevents asking for passwords or
+ passphrases).
- -C Compression enable. Passes the -C flag to ssh(1) to enable com-
- pression.
+ -C Compression enable. Passes the -C flag to ssh(1) to enable
+ compression.
-c cipher
Selects the cipher to use for encrypting the data transfer. This
@@ -120,8 +120,8 @@ DESCRIPTION
-q Quiet mode: disables the progress meter as well as warning and
diagnostic messages from ssh(1).
- -r Recursively copy entire directories. Note that scp follows sym-
- bolic links encountered in the tree traversal.
+ -r Recursively copy entire directories. Note that scp follows
+ symbolic links encountered in the tree traversal.
-S program
Name of program to use for the encrypted connection. The program
@@ -145,4 +145,4 @@ AUTHORS
Timo Rinne <tri@iki.fi>
Tatu Ylonen <ylo@cs.hut.fi>
-OpenBSD 4.7 February 8, 2010 3
+OpenBSD 4.8 February 8, 2010 OpenBSD 4.8
diff --git a/scp.c b/scp.c
index 09efb82acb3e..e07de42f776d 100644
--- a/scp.c
+++ b/scp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: scp.c,v 1.165 2009/12/20 07:28:36 guenther Exp $ */
+/* $OpenBSD: scp.c,v 1.166 2010/07/01 13:06:59 millert Exp $ */
/*
* scp - secure remote copy. This is basically patched BSD rcp which
* uses ssh to do the data transfer (instead of using rcmd).
@@ -156,6 +156,20 @@ killchild(int signo)
exit(1);
}
+static void
+suspchild(int signo)
+{
+ int status;
+
+ if (do_cmd_pid > 1) {
+ kill(do_cmd_pid, signo);
+ while (waitpid(do_cmd_pid, &status, WUNTRACED) == -1 &&
+ errno == EINTR)
+ ;
+ kill(getpid(), SIGSTOP);
+ }
+}
+
static int
do_local_cmd(arglist *a)
{
@@ -232,6 +246,10 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
close(reserved[0]);
close(reserved[1]);
+ signal(SIGTSTP, suspchild);
+ signal(SIGTTIN, suspchild);
+ signal(SIGTTOU, suspchild);
+
/* Fork a child to execute the command on the remote host using ssh. */
do_cmd_pid = fork();
if (do_cmd_pid == 0) {
diff --git a/servconf.c b/servconf.c
index 7d027ddb990a..986a5b92f692 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.c,v 1.207 2010/03/25 23:38:28 djm Exp $ */
+/* $OpenBSD: servconf.c,v 1.209 2010/06/22 04:22:59 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -131,6 +131,7 @@ initialize_server_options(ServerOptions *options)
options->zero_knowledge_password_authentication = -1;
options->revoked_keys_file = NULL;
options->trusted_user_ca_keys = NULL;
+ options->authorized_principals_file = NULL;
}
void
@@ -310,7 +311,7 @@ typedef enum {
sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
sUsePrivilegeSeparation, sAllowAgentForwarding,
sZeroKnowledgePasswordAuthentication, sHostCertificate,
- sRevokedKeys, sTrustedUserCAKeys,
+ sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
sDeprecated, sUnsupported
} ServerOpCodes;
@@ -345,7 +346,7 @@ static struct {
{ "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
{ "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
{ "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
- { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
+ { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL },
{ "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
@@ -420,11 +421,11 @@ static struct {
{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
{ "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
- { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
- { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
+ { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
+ { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_ALL },
{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL},
{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
- { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
+ { "permittunnel", sPermitTunnel, SSHCFG_ALL },
{ "match", sMatch, SSHCFG_ALL },
{ "permitopen", sPermitOpen, SSHCFG_ALL },
{ "forcecommand", sForceCommand, SSHCFG_ALL },
@@ -432,6 +433,7 @@ static struct {
{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
+ { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
{ NULL, sBadOption, 0 }
};
@@ -1218,10 +1220,14 @@ 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 = (opcode == sAuthorizedKeysFile) ?
- &options->authorized_keys_file :
- &options->authorized_keys_file2;
+ charptr = &options->authorized_keys_file2;
+ goto parse_tilde_filename;
+ case sAuthorizedPrincipalsFile:
+ charptr = &options->authorized_principals_file;
+ parse_tilde_filename:
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing file name.",
@@ -1440,6 +1446,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
M_CP_INTOPT(pubkey_authentication);
M_CP_INTOPT(kerberos_authentication);
M_CP_INTOPT(hostbased_authentication);
+ M_CP_INTOPT(hostbased_uses_name_from_packet_only);
M_CP_INTOPT(kbd_interactive_authentication);
M_CP_INTOPT(zero_knowledge_password_authentication);
M_CP_INTOPT(permit_root_login);
@@ -1447,6 +1454,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
M_CP_INTOPT(allow_tcp_forwarding);
M_CP_INTOPT(allow_agent_forwarding);
+ M_CP_INTOPT(permit_tun);
M_CP_INTOPT(gateway_ports);
M_CP_INTOPT(x11_display_offset);
M_CP_INTOPT(x11_forwarding);
@@ -1461,6 +1469,9 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
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
@@ -1682,6 +1693,8 @@ dump_config(ServerOptions *o)
dump_cfg_string(sChrootDirectory, o->chroot_directory);
dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
+ dump_cfg_string(sAuthorizedPrincipalsFile,
+ o->authorized_principals_file);
/* string arguments requiring a lookup */
dump_cfg_string(sLogLevel, log_level_name(o->log_level));
diff --git a/servconf.h b/servconf.h
index 860009f9c739..45d2a2ae3552 100644
--- a/servconf.h
+++ b/servconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.h,v 1.92 2010/03/04 10:36:03 djm Exp $ */
+/* $OpenBSD: servconf.h,v 1.93 2010/05/07 11:30:30 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -156,6 +156,7 @@ typedef struct {
char *chroot_directory;
char *revoked_keys_file;
char *trusted_user_ca_keys;
+ char *authorized_principals_file;
} ServerOptions;
void initialize_server_options(ServerOptions *);
diff --git a/session.c b/session.c
index e032de6926f5..71e4fbe7cfc8 100644
--- a/session.c
+++ b/session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.252 2010/03/07 11:57:13 dtucker Exp $ */
+/* $OpenBSD: session.c,v 1.256 2010/06/25 07:20:04 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -47,6 +47,7 @@
#include <arpa/inet.h>
#include <errno.h>
+#include <fcntl.h>
#include <grp.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
@@ -104,7 +105,7 @@
/* func */
Session *session_new(void);
-void session_set_fds(Session *, int, int, int, int);
+void session_set_fds(Session *, int, int, int, int, int);
void session_pty_cleanup(Session *);
void session_proctitle(Session *);
int session_setup_x11fwd(Session *);
@@ -447,6 +448,9 @@ do_exec_no_pty(Session *s, const char *command)
#ifdef USE_PIPES
int pin[2], pout[2], perr[2];
+ if (s == NULL)
+ fatal("do_exec_no_pty: no session");
+
/* Allocate pipes for communicating with the program. */
if (pipe(pin) < 0) {
error("%s: pipe in: %.100s", __func__, strerror(errno));
@@ -459,7 +463,8 @@ do_exec_no_pty(Session *s, const char *command)
return -1;
}
if (pipe(perr) < 0) {
- error("%s: pipe err: %.100s", __func__, strerror(errno));
+ error("%s: pipe err: %.100s", __func__,
+ strerror(errno));
close(pin[0]);
close(pin[1]);
close(pout[0]);
@@ -469,22 +474,23 @@ do_exec_no_pty(Session *s, const char *command)
#else
int inout[2], err[2];
+ if (s == NULL)
+ fatal("do_exec_no_pty: no session");
+
/* Uses socket pairs to communicate with the program. */
if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0) {
error("%s: socketpair #1: %.100s", __func__, strerror(errno));
return -1;
}
if (socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) {
- error("%s: socketpair #2: %.100s", __func__, strerror(errno));
+ error("%s: socketpair #2: %.100s", __func__,
+ strerror(errno));
close(inout[0]);
close(inout[1]);
return -1;
}
#endif
- if (s == NULL)
- fatal("do_exec_no_pty: no session");
-
session_proctitle(s);
/* Fork the child. */
@@ -595,11 +601,8 @@ do_exec_no_pty(Session *s, const char *command)
close(perr[1]);
if (compat20) {
- if (s->is_subsystem) {
- close(perr[0]);
- perr[0] = -1;
- }
- session_set_fds(s, pin[1], pout[0], perr[0], 0);
+ session_set_fds(s, pin[1], pout[0], perr[0],
+ s->is_subsystem, 0);
} else {
/* Enter the interactive session. */
server_loop(pid, pin[1], pout[0], perr[0]);
@@ -615,10 +618,8 @@ do_exec_no_pty(Session *s, const char *command)
* handle the case that fdin and fdout are the same.
*/
if (compat20) {
- session_set_fds(s, inout[1], inout[1],
- s->is_subsystem ? -1 : err[1], 0);
- if (s->is_subsystem)
- close(err[1]);
+ session_set_fds(s, inout[1], inout[1], err[1],
+ s->is_subsystem, 0);
} else {
server_loop(pid, inout[1], inout[1], err[1]);
/* server_loop has closed inout[1] and err[1]. */
@@ -740,7 +741,7 @@ do_exec_pty(Session *s, const char *command)
s->ptymaster = ptymaster;
packet_set_interactive(1);
if (compat20) {
- session_set_fds(s, ptyfd, fdout, -1, 1);
+ session_set_fds(s, ptyfd, fdout, -1, 1, 1);
} else {
server_loop(pid, ptyfd, fdout, -1);
/* server_loop _has_ closed ptyfd and fdout. */
@@ -1792,7 +1793,8 @@ do_child(Session *s, const char *command)
#ifdef HAVE_LOGIN_CAP
r = login_getcapbool(lc, "requirehome", 0);
#endif
- if (r || options.chroot_directory == NULL)
+ if (r || options.chroot_directory == NULL ||
+ strcasecmp(options.chroot_directory, "none") == 0)
fprintf(stderr, "Could not chdir to home "
"directory %s: %s\n", pw->pw_dir,
strerror(errno));
@@ -2137,7 +2139,8 @@ session_subsystem_req(Session *s)
u_int i;
packet_check_eom();
- logit("subsystem request for %.100s", subsys);
+ logit("subsystem request for %.100s by user %s", subsys,
+ s->pw->pw_name);
for (i = 0; i < options.num_subsystems; i++) {
if (strcmp(subsys, options.subsystem_name[i]) == 0) {
@@ -2319,7 +2322,8 @@ session_input_channel_req(Channel *c, const char *rtype)
}
void
-session_set_fds(Session *s, int fdin, int fdout, int fderr, int is_tty)
+session_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr,
+ int is_tty)
{
if (!compat20)
fatal("session_set_fds: called for proto != 2.0");
@@ -2331,7 +2335,7 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr, int is_tty)
fatal("no channel for session %d", s->self);
channel_set_fds(s->chanid,
fdout, fdin, fderr,
- fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
+ ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
1, is_tty, CHAN_SES_WINDOW_DEFAULT);
}
diff --git a/sftp-client.c b/sftp-client.c
index 6124c0f408cc..9dab477806aa 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-client.c,v 1.90 2009/10/11 10:41:26 dtucker Exp $ */
+/* $OpenBSD: sftp-client.c,v 1.92 2010/07/19 03:16:33 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@@ -713,7 +713,8 @@ do_realpath(struct sftp_conn *conn, char *path)
u_int status = buffer_get_int(&msg);
error("Couldn't canonicalise: %s", fx2txt(status));
- return(NULL);
+ buffer_free(&msg);
+ return NULL;
} else if (type != SSH2_FXP_NAME)
fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
SSH2_FXP_NAME, type);
@@ -1522,7 +1523,7 @@ upload_dir_internal(struct sftp_conn *conn, char *src, char *dst,
continue;
if (upload_dir_internal(conn, new_src, new_dst,
- pflag, depth + 1, printflag) == -1)
+ pflag, printflag, depth + 1) == -1)
ret = -1;
} else if (S_ISREG(sb.st_mode)) {
if (do_upload(conn, new_src, new_dst, pflag) == -1) {
diff --git a/sftp-server.0 b/sftp-server.0
index 0c2654c8d2a0..05b9ddc9c589 100644
--- a/sftp-server.0
+++ b/sftp-server.0
@@ -8,9 +8,9 @@ SYNOPSIS
DESCRIPTION
sftp-server is a program that speaks the server side of SFTP protocol to
- stdout and expects client requests from stdin. sftp-server is not in-
- tended to be called directly, but from sshd(8) using the Subsystem op-
- tion.
+ stdout and expects client requests from stdin. sftp-server is not
+ intended to be called directly, but from sshd(8) using the Subsystem
+ option.
Command-line flags to sftp-server should be specified in the Subsystem
declaration. See sshd_config(5) for more information.
@@ -29,15 +29,15 @@ DESCRIPTION
-h Displays sftp-server usage information.
-l log_level
- Specifies which messages will be logged by sftp-server. The pos-
- sible values are: QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DE-
- BUG1, DEBUG2, and DEBUG3. INFO and VERBOSE log transactions that
- sftp-server performs on behalf of the client. DEBUG and DEBUG1
- are equivalent. DEBUG2 and DEBUG3 each specify higher levels of
- debugging output. The default is ERROR.
-
- -R Places this instance of sftp-server into a read-only mode. At-
- tempts to open files for writing, as well as other operations
+ Specifies which messages will be logged by sftp-server. The
+ possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG,
+ DEBUG1, DEBUG2, and DEBUG3. INFO and VERBOSE log transactions
+ that sftp-server performs on behalf of the client. DEBUG and
+ DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify higher
+ levels of debugging output. The default is ERROR.
+
+ -R Places this instance of sftp-server into a read-only mode.
+ Attempts to open files for writing, as well as other operations
that change the state of the filesystem, will be denied.
-u umask
@@ -51,8 +51,9 @@ DESCRIPTION
SEE ALSO
sftp(1), ssh(1), sshd_config(5), sshd(8)
- T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh-
- filexfer-00.txt, January 2001, work in progress material.
+ T. Ylonen, S. Lehtinen, SSH File Transfer Protocol,
+ draft-ietf-secsh-filexfer-00.txt, January 2001, work in progress
+ material.
HISTORY
sftp-server first appeared in OpenBSD 2.8.
@@ -60,4 +61,4 @@ HISTORY
AUTHORS
Markus Friedl <markus@openbsd.org>
-OpenBSD 4.7 January 9, 2010 1
+OpenBSD 4.8 January 9, 2010 OpenBSD 4.8
diff --git a/sftp.0 b/sftp.0
index 488548a6ed7d..40de1a0cd990 100644
--- a/sftp.0
+++ b/sftp.0
@@ -15,20 +15,20 @@ SYNOPSIS
DESCRIPTION
sftp is an interactive file transfer program, similar to ftp(1), which
performs all operations over an encrypted ssh(1) transport. It may also
- use many features of ssh, such as public key authentication and compres-
- sion. sftp connects and logs into the specified host, then enters an in-
- teractive command mode.
+ use many features of ssh, such as public key authentication and
+ compression. sftp connects and logs into the specified host, then enters
+ an interactive command mode.
- The second usage format will retrieve files automatically if a non-inter-
- active authentication method is used; otherwise it will do so after suc-
- cessful interactive authentication.
+ The second usage format will retrieve files automatically if a non-
+ interactive authentication method is used; otherwise it will do so after
+ successful interactive authentication.
The third usage format allows sftp to start in a remote directory.
The final usage format allows for automated sessions using the -b option.
- In such cases, it is necessary to configure non-interactive authentica-
- tion to obviate the need to enter a password at connection time (see
- sshd(8) and ssh-keygen(1) for details). The options are as follows:
+ In such cases, it is necessary to configure non-interactive
+ authentication to obviate the need to enter a password at connection time
+ (see sshd(8) and ssh-keygen(1) for details). The options are as follows:
-1 Specify the use of protocol version 1.
@@ -44,8 +44,8 @@ DESCRIPTION
higher memory consumption. The default is 32768 bytes.
-b batchfile
- Batch mode reads a series of commands from an input batchfile in-
- stead of stdin. Since it lacks user interaction it should be
+ Batch mode reads a series of commands from an input batchfile
+ instead of stdin. Since it lacks user interaction it should be
used in conjunction with non-interactive authentication. A
batchfile of `-' may be used to indicate standard input. sftp
will abort if any of the following commands fail: get, put,
@@ -144,9 +144,9 @@ DESCRIPTION
Increasing this may slightly improve file transfer speed but will
increase memory usage. The default is 64 outstanding requests.
- -r Recursively copy entire directories when uploading and download-
- ing. Note that sftp does not follow symbolic links encountered
- in the tree traversal.
+ -r Recursively copy entire directories when uploading and
+ downloading. Note that sftp does not follow symbolic links
+ encountered in the tree traversal.
-S program
Name of the program to use for the encrypted connection. The
@@ -155,8 +155,8 @@ DESCRIPTION
-s subsystem | sftp_server
Specifies the SSH2 subsystem or the path for an sftp server on
the remote host. A path is useful for using sftp over protocol
- version 1, or when the remote sshd(8) does not have an sftp sub-
- system configured.
+ version 1, or when the remote sshd(8) does not have an sftp
+ subsystem configured.
-v Raise logging level. This option is also passed to ssh.
@@ -173,16 +173,18 @@ INTERACTIVE COMMANDS
Change remote directory to path.
chgrp grp path
- Change group of file path to grp. path may contain glob(3) char-
- acters and may match multiple files. grp must be a numeric GID.
+ Change group of file path to grp. path may contain glob(3)
+ characters and may match multiple files. grp must be a numeric
+ GID.
chmod mode path
Change permissions of file path to mode. path may contain
glob(3) characters and may match multiple files.
chown own path
- Change owner of file path to own. path may contain glob(3) char-
- acters and may match multiple files. own must be a numeric UID.
+ Change owner of file path to own. path may contain glob(3)
+ characters and may match multiple files. own must be a numeric
+ UID.
df [-hi] [path]
Display usage information for the filesystem holding the current
@@ -198,14 +200,15 @@ INTERACTIVE COMMANDS
Retrieve the remote-path and store it on the local machine. If
the local path name is not specified, it is given the same name
it has on the remote machine. remote-path may contain glob(3)
- characters and may match multiple files. If it does and local-
- path is specified, then local-path must specify a directory.
+ characters and may match multiple files. If it does and
+ local-path is specified, then local-path must specify a
+ directory.
- If either the -P or -p flag is specified, then full file permis-
- sions and access times are copied too.
+ If either the -P or -p flag is specified, then full file
+ permissions and access times are copied too.
- If the -r flag is specified then directories will be copied re-
- cursively. Note that sftp does not follow symbolic links when
+ If the -r flag is specified then directories will be copied
+ recursively. Note that sftp does not follow symbolic links when
performing recursive transfers.
help Display help text.
@@ -214,10 +217,10 @@ INTERACTIVE COMMANDS
Change local directory to path.
lls [ls-options [path]]
- Display local directory listing of either path or current direc-
- tory if path is not specified. ls-options may contain any flags
- supported by the local system's ls(1) command. path may contain
- glob(3) characters and may match multiple files.
+ Display local directory listing of either path or current
+ directory if path is not specified. ls-options may contain any
+ flags supported by the local system's ls(1) command. path may
+ contain glob(3) characters and may match multiple files.
lmkdir path
Create local directory specified by path.
@@ -239,8 +242,8 @@ INTERACTIVE COMMANDS
-a List files beginning with a dot (`.').
- -f Do not sort the listing. The default sort order is lexi-
- cographical.
+ -f Do not sort the listing. The default sort order is
+ lexicographical.
-h When used with a long format option, use unit suffixes:
Byte, Kilobyte, Megabyte, Gigabyte, Terabyte, Petabyte,
@@ -248,8 +251,8 @@ INTERACTIVE COMMANDS
four or fewer using powers of 2 for sizes (K=1024,
M=1048576, etc.).
- -l Display additional details including permissions and own-
- ership information.
+ -l Display additional details including permissions and
+ ownership information.
-n Produce a long listing with user and group information
presented numerically.
@@ -270,17 +273,18 @@ INTERACTIVE COMMANDS
Toggle display of progress meter.
put [-Ppr] local-path [remote-path]
- Upload local-path and store it on the remote machine. If the re-
- mote path name is not specified, it is given the same name it has
- on the local machine. local-path may contain glob(3) characters
- and may match multiple files. If it does and remote-path is
- specified, then remote-path must specify a directory.
-
- If ether the -P or -p flag is specified, then full file permis-
- sions and access times are copied too.
-
- If the -r flag is specified then directories will be copied re-
- cursively. Note that sftp does not follow symbolic links when
+ Upload local-path and store it on the remote machine. If the
+ remote path name is not specified, it is given the same name it
+ has on the local machine. local-path may contain glob(3)
+ characters and may match multiple files. If it does and
+ remote-path is specified, then remote-path must specify a
+ directory.
+
+ If ether the -P or -p flag is specified, then full file
+ permissions and access times are copied too.
+
+ If the -r flag is specified then directories will be copied
+ recursively. Note that sftp does not follow symbolic links when
performing recursive transfers.
pwd Display remote working directory.
@@ -313,7 +317,8 @@ SEE ALSO
ftp(1), ls(1), scp(1), ssh(1), ssh-add(1), ssh-keygen(1), glob(3),
ssh_config(5), sftp-server(8), sshd(8)
- T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh-
- filexfer-00.txt, January 2001, work in progress material.
+ T. Ylonen, S. Lehtinen, SSH File Transfer Protocol,
+ draft-ietf-secsh-filexfer-00.txt, January 2001, work in progress
+ material.
-OpenBSD 4.7 February 8, 2010 5
+OpenBSD 4.8 February 8, 2010 OpenBSD 4.8
diff --git a/sftp.c b/sftp.c
index d65d4ec62ea7..229f12987e50 100644
--- a/sftp.c
+++ b/sftp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp.c,v 1.123 2010/01/27 19:21:39 djm Exp $ */
+/* $OpenBSD: sftp.c,v 1.125 2010/06/18 00:58:39 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@@ -181,6 +181,8 @@ static const struct CMD cmds[] = {
{ "ls", I_LS, REMOTE },
{ "lumask", I_LUMASK, NOARGS },
{ "mkdir", I_MKDIR, REMOTE },
+ { "mget", I_GET, REMOTE },
+ { "mput", I_PUT, LOCAL },
{ "progress", I_PROGRESS, NOARGS },
{ "put", I_PUT, LOCAL },
{ "pwd", I_PWD, REMOTE },
@@ -1366,7 +1368,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
break;
case I_LS:
if (!path1) {
- do_globbed_ls(conn, *pwd, *pwd, lflag);
+ do_ls_dir(conn, *pwd, *pwd, lflag);
break;
}
diff --git a/ssh-add.0 b/ssh-add.0
index 0d49c5ea34eb..86f3994c4cb5 100644
--- a/ssh-add.0
+++ b/ssh-add.0
@@ -11,31 +11,33 @@ SYNOPSIS
DESCRIPTION
ssh-add adds RSA or DSA identities to the authentication agent,
ssh-agent(1). When run without arguments, it adds the files
- ~/.ssh/id_rsa, ~/.ssh/id_dsa and ~/.ssh/identity. After loading a pri-
- vate key, ssh-add will try to load corresponding certificate information
- from the filename obtained by appending -cert.pub to the name of the pri-
- vate key file. Alternative file names can be given on the command line.
+ ~/.ssh/id_rsa, ~/.ssh/id_dsa and ~/.ssh/identity. After loading a
+ private key, ssh-add will try to load corresponding certificate
+ information from the filename obtained by appending -cert.pub to the name
+ of the private key file. Alternative file names can be given on the
+ command line.
If any file requires a passphrase, ssh-add asks for the passphrase from
the user. The passphrase is read from the user's tty. ssh-add retries
the last passphrase if multiple identity files are given.
- The authentication agent must be running and the SSH_AUTH_SOCK environ-
- ment variable must contain the name of its socket for ssh-add to work.
+ The authentication agent must be running and the SSH_AUTH_SOCK
+ environment variable must contain the name of its socket for ssh-add to
+ work.
The options are as follows:
-c Indicates that added identities should be subject to confirmation
before being used for authentication. Confirmation is performed
- by the SSH_ASKPASS program mentioned below. Successful confirma-
- tion is signaled by a zero exit status from the SSH_ASKPASS pro-
- gram, rather than text entered into the requester.
+ by the SSH_ASKPASS program mentioned below. Successful
+ confirmation is signaled by a zero exit status from the
+ SSH_ASKPASS program, rather than text entered into the requester.
-D Deletes all identities from the agent.
-d Instead of adding identities, removes identities from the agent.
- If ssh-add has been run without arguments, the keys for the de-
- fault identities will be removed. Otherwise, the argument list
+ If ssh-add has been run without arguments, the keys for the
+ default identities will be removed. Otherwise, the argument list
will be interpreted as a list of paths to public key files and
matching keys will be removed from the agent. If no public key
is found at a given path, ssh-add will append .pub and retry.
@@ -43,8 +45,8 @@ DESCRIPTION
-e pkcs11
Remove keys provided by the PKCS#11 shared library pkcs11.
- -L Lists public key parameters of all identities currently repre-
- sented by the agent.
+ -L Lists public key parameters of all identities currently
+ represented by the agent.
-l Lists fingerprints of all identities currently represented by the
agent.
@@ -54,8 +56,8 @@ DESCRIPTION
-t life
Set a maximum lifetime when adding identities to an agent. The
- lifetime may be specified in seconds or in a time format speci-
- fied in sshd_config(5).
+ lifetime may be specified in seconds or in a time format
+ specified in sshd_config(5).
-X Unlock the agent.
@@ -102,8 +104,8 @@ SEE ALSO
AUTHORS
OpenSSH is a derivative of the original and free ssh 1.2.12 release by
Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo
- de Raadt and Dug Song removed many bugs, re-added newer features and cre-
- ated OpenSSH. Markus Friedl contributed the support for SSH protocol
+ de Raadt and Dug Song removed many bugs, re-added newer features and
+ created OpenSSH. Markus Friedl contributed the support for SSH protocol
versions 1.5 and 2.0.
-OpenBSD 4.7 March 5, 2010 2
+OpenBSD 4.8 March 5, 2010 OpenBSD 4.8
diff --git a/ssh-add.c b/ssh-add.c
index ad9f7a83e405..fb641ec489ad 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-add.c,v 1.94 2010/03/01 11:07:06 otto Exp $ */
+/* $OpenBSD: ssh-add.c,v 1.96 2010/05/14 00:47:22 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -194,7 +194,7 @@ add_file(AuthenticationConnection *ac, const char *filename)
"Lifetime set to %d seconds\n", lifetime);
if (confirm != 0)
fprintf(stderr,
- "The user has to confirm each use of the key\n");
+ "The user must confirm each use of the key\n");
} else {
fprintf(stderr, "Could not add identity: %s\n", filename);
}
@@ -202,29 +202,37 @@ add_file(AuthenticationConnection *ac, const char *filename)
/* Now try to add the certificate flavour too */
xasprintf(&certpath, "%s-cert.pub", filename);
- if ((cert = key_load_public(certpath, NULL)) != NULL) {
- /* Graft with private bits */
- if (key_to_certified(private) != 0)
- fatal("%s: key_to_certified failed", __func__);
- key_cert_copy(cert, private);
+ if ((cert = key_load_public(certpath, NULL)) == NULL)
+ goto out;
+
+ if (!key_equal_public(cert, private)) {
+ error("Certificate %s does not match private key %s",
+ certpath, filename);
key_free(cert);
+ goto out;
+ }
- if (ssh_add_identity_constrained(ac, private, comment,
- lifetime, confirm)) {
- fprintf(stderr, "Certificate added: %s (%s)\n",
- certpath, private->cert->key_id);
- if (lifetime != 0)
- fprintf(stderr, "Lifetime set to %d seconds\n",
- lifetime);
- if (confirm != 0)
- fprintf(stderr, "The user has to confirm each "
- "use of the key\n");
- } else {
- error("Certificate %s (%s) add failed", certpath,
- private->cert->key_id);
- }
+ /* Graft with private bits */
+ if (key_to_certified(private, key_cert_is_legacy(cert)) != 0) {
+ error("%s: key_to_certified failed", __func__);
+ key_free(cert);
+ goto out;
}
+ key_cert_copy(cert, private);
+ key_free(cert);
+ if (!ssh_add_identity_constrained(ac, private, comment,
+ lifetime, confirm)) {
+ error("Certificate %s (%s) add failed", certpath,
+ private->cert->key_id);
+ }
+ fprintf(stderr, "Certificate added: %s (%s)\n", certpath,
+ private->cert->key_id);
+ if (lifetime != 0)
+ fprintf(stderr, "Lifetime set to %d seconds\n", lifetime);
+ if (confirm != 0)
+ fprintf(stderr, "The user must confirm each use of the key\n");
+ out:
xfree(certpath);
xfree(comment);
key_free(private);
diff --git a/ssh-agent.0 b/ssh-agent.0
index 536eac756acb..dfc82a966f6b 100644
--- a/ssh-agent.0
+++ b/ssh-agent.0
@@ -8,18 +8,18 @@ SYNOPSIS
ssh-agent [-c | -s] -k
DESCRIPTION
- ssh-agent is a program to hold private keys used for public key authenti-
- cation (RSA, DSA). The idea is that ssh-agent is started in the begin-
- ning of an X-session or a login session, and all other windows or pro-
- grams are started as clients to the ssh-agent program. Through use of
+ ssh-agent is a program to hold private keys used for public key
+ authentication (RSA, DSA). The idea is that ssh-agent is started in the
+ beginning of an X-session or a login session, and all other windows or
+ programs are started as clients to the ssh-agent program. Through use of
environment variables the agent can be located and automatically used for
authentication when logging in to other machines using ssh(1).
The options are as follows:
-a bind_address
- Bind the agent to the UNIX-domain socket bind_address. The de-
- fault is /tmp/ssh-XXXXXXXXXX/agent.<ppid>.
+ Bind the agent to the UNIX-domain socket bind_address. The
+ default is /tmp/ssh-XXXXXXXXXX/agent.<ppid>.
-c Generate C-shell commands on stdout. This is the default if
SHELL looks like it's a csh style of shell.
@@ -50,15 +50,15 @@ DESCRIPTION
one or from a small X11 program if running under X11. If neither of
these is the case then the authentication will fail. It then sends the
identity to the agent. Several identities can be stored in the agent;
- the agent can automatically use any of these identities. ssh-add -l dis-
- plays the identities currently held by the agent.
+ the agent can automatically use any of these identities. ssh-add -l
+ displays the identities currently held by the agent.
- The idea is that the agent is run in the user's local PC, laptop, or ter-
- minal. Authentication data need not be stored on any other machine, and
- authentication passphrases never go over the network. However, the con-
- nection to the agent is forwarded over SSH remote logins, and the user
- can thus use the privileges given by the identities anywhere in the net-
- work in a secure way.
+ The idea is that the agent is run in the user's local PC, laptop, or
+ terminal. Authentication data need not be stored on any other machine,
+ and authentication passphrases never go over the network. However, the
+ connection to the agent is forwarded over SSH remote logins, and the user
+ can thus use the privileges given by the identities anywhere in the
+ network in a secure way.
There are two main ways to get an agent set up: The first is that the
agent starts a new subcommand into which some environment variables are
@@ -68,18 +68,18 @@ DESCRIPTION
Bourne-type shells such as sh(1) or ksh(1) and eval `ssh-agent -c` for
csh(1) and derivatives.
- Later ssh(1) looks at these variables and uses them to establish a con-
- nection to the agent.
+ Later ssh(1) looks at these variables and uses them to establish a
+ connection to the agent.
- The agent will never send a private key over its request channel. In-
- stead, operations that require a private key will be performed by the
- agent, and the result will be returned to the requester. This way, pri-
- vate keys are not exposed to clients using the agent.
+ The agent will never send a private key over its request channel.
+ Instead, operations that require a private key will be performed by the
+ agent, and the result will be returned to the requester. This way,
+ private keys are not exposed to clients using the agent.
A UNIX-domain socket is created and the name of this socket is stored in
the SSH_AUTH_SOCK environment variable. The socket is made accessible
- only to the current user. This method is easily abused by root or anoth-
- er instance of the same user.
+ only to the current user. This method is easily abused by root or
+ another instance of the same user.
The SSH_AGENT_PID environment variable holds the agent's process ID.
@@ -100,9 +100,9 @@ FILES
the user.
/tmp/ssh-XXXXXXXXXX/agent.<ppid>
- UNIX-domain sockets used to contain the connection to the authen-
- tication agent. These sockets should only be readable by the
- owner. The sockets should get automatically removed when the
+ UNIX-domain sockets used to contain the connection to the
+ authentication agent. These sockets should only be readable by
+ the owner. The sockets should get automatically removed when the
agent exits.
SEE ALSO
@@ -111,8 +111,8 @@ SEE ALSO
AUTHORS
OpenSSH is a derivative of the original and free ssh 1.2.12 release by
Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo
- de Raadt and Dug Song removed many bugs, re-added newer features and cre-
- ated OpenSSH. Markus Friedl contributed the support for SSH protocol
+ de Raadt and Dug Song removed many bugs, re-added newer features and
+ created OpenSSH. Markus Friedl contributed the support for SSH protocol
versions 1.5 and 2.0.
-OpenBSD 4.7 January 17, 2010 2
+OpenBSD 4.8 January 17, 2010 OpenBSD 4.8
diff --git a/ssh-agent.c b/ssh-agent.c
index b5c565271839..2c0e2869600e 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.165 2010/02/26 20:29:54 djm Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.166 2010/04/16 01:47:26 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -500,6 +500,7 @@ process_add_identity(SocketEntry *e, int version)
buffer_get_bignum2(&e->request, k->dsa->pub_key);
buffer_get_bignum2(&e->request, k->dsa->priv_key);
break;
+ case KEY_DSA_CERT_V00:
case KEY_DSA_CERT:
cert = buffer_get_string(&e->request, &len);
if ((k = key_from_blob(cert, len)) == NULL)
@@ -520,6 +521,7 @@ process_add_identity(SocketEntry *e, int version)
/* Generate additional parameters */
rsa_generate_additional_parameters(k->rsa);
break;
+ case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
cert = buffer_get_string(&e->request, &len);
if ((k = key_from_blob(cert, len)) == NULL)
@@ -540,6 +542,7 @@ process_add_identity(SocketEntry *e, int version)
/* enable blinding */
switch (k->type) {
case KEY_RSA:
+ case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
case KEY_RSA1:
if (RSA_blinding_on(k->rsa, NULL) != 1) {
diff --git a/ssh-dss.c b/ssh-dss.c
index 449f493b4053..175e4d030110 100644
--- a/ssh-dss.c
+++ b/ssh-dss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-dss.c,v 1.25 2010/02/26 20:29:54 djm Exp $ */
+/* $OpenBSD: ssh-dss.c,v 1.26 2010/04/16 01:47:26 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -53,9 +53,8 @@ ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp,
u_int rlen, slen, len, dlen;
Buffer b;
- if (key == NULL ||
- (key->type != KEY_DSA && key->type != KEY_DSA_CERT) ||
- key->dsa == NULL) {
+ if (key == NULL || key->dsa == NULL || (key->type != KEY_DSA &&
+ key->type != KEY_DSA_CERT && key->type != KEY_DSA_CERT_V00)) {
error("ssh_dss_sign: no DSA key");
return -1;
}
@@ -118,9 +117,8 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
int rlen, ret;
Buffer b;
- if (key == NULL ||
- (key->type != KEY_DSA && key->type != KEY_DSA_CERT) ||
- key->dsa == NULL) {
+ if (key == NULL || key->dsa == NULL || (key->type != KEY_DSA &&
+ key->type != KEY_DSA_CERT && key->type != KEY_DSA_CERT_V00)) {
error("ssh_dss_verify: no DSA key");
return -1;
}
diff --git a/ssh-keygen.0 b/ssh-keygen.0
index aed4a14ad917..fb78387241b2 100644
--- a/ssh-keygen.0
+++ b/ssh-keygen.0
@@ -7,8 +7,8 @@ SYNOPSIS
ssh-keygen [-q] [-b bits] -t type [-N new_passphrase] [-C comment]
[-f output_keyfile]
ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]
- ssh-keygen -i [-f input_keyfile]
- ssh-keygen -e [-f input_keyfile]
+ ssh-keygen -i [-m key_format] [-f input_keyfile]
+ ssh-keygen -e [-m key_format] [-f input_keyfile]
ssh-keygen -y [-f input_keyfile]
ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]
ssh-keygen -l [-f input_keyfile]
@@ -22,7 +22,7 @@ SYNOPSIS
ssh-keygen -T output_file -f input_file [-v] [-a num_trials]
[-W generator]
ssh-keygen -s ca_key -I certificate_identity [-h] [-n principals]
- [-O constraint] [-V validity_interval] file ...
+ [-O option] [-V validity_interval] [-z serial_number] file ...
ssh-keygen -L [-f input_keyfile]
DESCRIPTION
@@ -46,14 +46,14 @@ DESCRIPTION
name but ``.pub'' appended. The program also asks for a passphrase. The
passphrase may be empty to indicate no passphrase (host keys must have an
empty passphrase), or it may be a string of arbitrary length. A
- passphrase is similar to a password, except it can be a phrase with a se-
- ries of words, punctuation, numbers, whitespace, or any string of charac-
- ters you want. Good passphrases are 10-30 characters long, are not sim-
- ple sentences or otherwise easily guessable (English prose has only 1-2
- bits of entropy per character, and provides very bad passphrases), and
- contain a mix of upper and lowercase letters, numbers, and non-alphanu-
- meric characters. The passphrase can be changed later by using the -p
- option.
+ passphrase is similar to a password, except it can be a phrase with a
+ series of words, punctuation, numbers, whitespace, or any string of
+ characters you want. Good passphrases are 10-30 characters long, are not
+ simple sentences or otherwise easily guessable (English prose has only 1-
+ 2 bits of entropy per character, and provides very bad passphrases), and
+ contain a mix of upper and lowercase letters, numbers, and non-
+ alphanumeric characters. The passphrase can be changed later by using
+ the -p option.
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
@@ -61,9 +61,9 @@ DESCRIPTION
For RSA1 keys, there is also a comment field in the key file that is only
for convenience to the user to help identify the key. The comment can
- tell what the key is for, or whatever is useful. The comment is initial-
- ized to ``user@host'' when the key is created, but can be changed using
- the -c option.
+ tell what the key is for, or whatever is useful. The comment is
+ initialized to ``user@host'' when the key is created, but can be changed
+ using the -c option.
After a key is generated, instructions below detail where the keys should
be placed to be activated.
@@ -79,26 +79,29 @@ DESCRIPTION
-b bits
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. Gen-
- erally, 2048 bits is considered sufficient. DSA keys must be ex-
- actly 1024 bits as specified by FIPS 186-2.
+ 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.
-C comment
Provides a new comment.
-c Requests changing the comment in the private and public key
- files. This operation is only supported for RSA1 keys. The pro-
- gram will prompt for the file containing the private keys, for
+ files. This operation is only supported for RSA1 keys. The
+ program will prompt for the file containing the private keys, for
the passphrase if the key has one, and for the new comment.
-D pkcs11
- Download the RSA public keys provided by the PKCS#11 shared li-
- brary pkcs11.
+ Download the RSA public keys provided by the PKCS#11 shared
+ library pkcs11. When used in combination with -s, this option
+ indicates that a CA key resides in a PKCS#11 token (see the
+ CERTIFICATES section for details).
-e This option will read a private or public OpenSSH key file and
- print the key in RFC 4716 SSH Public Key File Format to stdout.
- This option allows exporting keys for use by several commercial
- SSH implementations.
+ print to stdout the key in one of the formats specified by the -m
+ option. The default export format is ``RFC4716''. This option
+ allows exporting OpenSSH keys for use by other programs,
+ including several commercial SSH implementations.
-F hostname
Search for the specified hostname in a known_hosts file, listing
@@ -116,8 +119,8 @@ DESCRIPTION
-g Use generic DNS format when printing fingerprint resource records
using the -r command.
- -H Hash a known_hosts file. This replaces all hostnames and ad-
- dresses with hashed representations within the specified file;
+ -H Hash a known_hosts file. This replaces all hostnames and
+ addresses with hashed representations within the specified file;
the original content is moved to a file with a .old suffix.
These hashes may be used normally by ssh and sshd, but they do
not reveal identifying information should the file's contents be
@@ -133,41 +136,48 @@ DESCRIPTION
the CERTIFICATES section for details.
-i This option will read an unencrypted private (or public) key file
- in SSH2-compatible format and print an OpenSSH compatible private
- (or public) key to stdout. ssh-keygen also reads the RFC 4716
- SSH Public Key File Format. This option allows importing keys
- from several commercial SSH implementations.
+ in the format specified by the -m option and print an OpenSSH
+ compatible private (or public) key to stdout. This option allows
+ importing keys from other software, including several commercial
+ SSH implementations. The default import format is ``RFC4716''.
-L Prints the contents of a certificate.
-l Show fingerprint of specified public key file. Private RSA1 keys
are also supported. For RSA and DSA keys ssh-keygen tries to
find the matching public key file and prints its fingerprint. If
- combined with -v, an ASCII art representation of the key is sup-
- plied with the fingerprint.
+ combined with -v, an ASCII art representation of the key is
+ supplied with the fingerprint.
-M memory
- Specify the amount of memory to use (in megabytes) when generat-
- ing candidate moduli for DH-GEX.
+ Specify the amount of memory to use (in megabytes) when
+ generating candidate moduli for DH-GEX.
+
+ -m key_format
+ Specify a key format for the -i (import) or -e (export)
+ conversion options. The supported key formats are: ``RFC4716''
+ (RFC 4716/SSH2 public or private key), ``PKCS8'' (PEM PKCS8
+ public key) or ``PEM'' (PEM public key). The default conversion
+ format is ``RFC4716''.
-N new_passphrase
Provides the new passphrase.
-n principals
- Specify one or more principals (user or host names) to be includ-
- ed in a certificate when signing a key. Multiple principals may
- be specified, separated by commas. Please see the CERTIFICATES
- section for details.
+ Specify one or more principals (user or host names) to be
+ included in a certificate when signing a key. Multiple
+ principals may be specified, separated by commas. Please see the
+ CERTIFICATES section for details.
- -O constraint
- Specify a certificate constraint when signing a key. This option
- may be specified multiple times. Please see the CERTIFICATES
- section for details. The constraints that are valid for user
- certificates are:
+ -O option
+ Specify a certificate option when signing a key. This option may
+ be specified multiple times. Please see the CERTIFICATES section
+ for details. The options that are valid for user certificates
+ are:
- clear Clear all enabled permissions. This is useful for clear-
- ing the default set of permissions so permissions may be
- added individually.
+ clear Clear all enabled permissions. This is useful for
+ clearing the default set of permissions so permissions
+ may be added individually.
force-command=command
Forces the execution of command instead of any shell or
@@ -206,11 +216,11 @@ DESCRIPTION
source-address=address_list
Restrict the source addresses from which the certificate
- is considered valid. The address_list is a comma-sepa-
- rated list of one or more address/netmask pairs in CIDR
- format.
+ is considered valid. The address_list is a comma-
+ separated list of one or more address/netmask pairs in
+ CIDR format.
- At present, no constraints are valid for host keys.
+ At present, no options are valid for host keys.
-P passphrase
Provides the (old) passphrase.
@@ -245,21 +255,21 @@ DESCRIPTION
-t type
Specifies the type of key to create. The possible values are
- ``rsa1'' for protocol version 1 and ``rsa'' or ``dsa'' for proto-
- col version 2.
+ ``rsa1'' for protocol version 1 and ``rsa'' or ``dsa'' for
+ protocol version 2.
-V validity_interval
- Specify a validity interval when signing a certificate. A valid-
- ity interval may consist of a single time, indicating that the
- certificate is valid beginning now and expiring at that time, or
- may consist of two times separated by a colon to indicate an ex-
- plicit time interval. The start time may be specified as a date
- in YYYYMMDD format, a time in YYYYMMDDHHMMSS format or a relative
- time (to the current time) consisting of a minus sign followed by
- a relative time in the format described in the TIME FORMATS sec-
- tion of sshd_config(5). The end time may be specified as a
- YYYYMMDD date, a YYYYMMDDHHMMSS time or a relative time starting
- with a plus character.
+ Specify a validity interval when signing a certificate. A
+ validity interval may consist of a single time, indicating that
+ the certificate is valid beginning now and expiring at that time,
+ or may consist of two times separated by a colon to indicate an
+ explicit time interval. The start time may be specified as a
+ date in YYYYMMDD format, a time in YYYYMMDDHHMMSS format or a
+ relative time (to the current time) consisting of a minus sign
+ followed by a relative time in the format described in the TIME
+ FORMATS section of sshd_config(5). The end time may be specified
+ as a YYYYMMDD date, a YYYYMMDDHHMMSS time or a relative time
+ starting with a plus character.
For example: ``+52w1d'' (valid from now to 52 weeks and one day
from now), ``-4w:+4w'' (valid from four weeks ago to four weeks
@@ -269,9 +279,9 @@ DESCRIPTION
2011).
-v Verbose mode. Causes ssh-keygen to print debugging messages
- about its progress. This is helpful for debugging moduli genera-
- tion. Multiple -v options increase the verbosity. The maximum
- is 3.
+ about its progress. This is helpful for debugging moduli
+ generation. Multiple -v options increase the verbosity. The
+ maximum is 3.
-W generator
Specify desired generator when testing candidate moduli for DH-
@@ -280,12 +290,17 @@ DESCRIPTION
-y This option will read a private OpenSSH format file and print an
OpenSSH public key to stdout.
+ -z serial_number
+ Specifies a serial number to be embedded in the certificate to
+ distinguish this certificate from others from the same CA. The
+ default serial number is zero.
+
MODULI GENERATION
ssh-keygen may be used to generate groups for the Diffie-Hellman Group
- Exchange (DH-GEX) protocol. Generating these groups is a two-step pro-
- cess: first, candidate primes are generated using a fast, but memory in-
- tensive process. These candidate primes are then tested for suitability
- (a CPU-intensive process).
+ Exchange (DH-GEX) protocol. Generating these groups is a two-step
+ process: first, candidate primes are generated using a fast, but memory
+ intensive process. These candidate primes are then tested for
+ suitability (a CPU-intensive process).
Generation of primes is performed using the -G option. The desired
length of the primes may be specified by the -b option. For example:
@@ -293,8 +308,8 @@ MODULI GENERATION
# ssh-keygen -G moduli-2048.candidates -b 2048
By default, the search for primes begins at a random point in the desired
- length range. This may be overridden using the -S option, which speci-
- fies a different start point (in hex).
+ length range. This may be overridden using the -S option, which
+ specifies a different start point (in hex).
Once a set of candidates have been generated, they must be tested for
suitability. This may be performed using the -T option. In this mode
@@ -317,15 +332,15 @@ CERTIFICATES
ssh-keygen supports signing of keys to produce certificates that may be
used for user or host authentication. Certificates consist of a public
key, some identity information, zero or more principal (user or host)
- names and an optional set of constraints that are signed by a Certifica-
- tion Authority (CA) key. Clients or servers may then trust only the CA
- key and verify its signature on a certificate rather than trusting many
- user/host keys. Note that OpenSSH certificates are a different, and much
- simpler, format to the X.509 certificates used in ssl(8).
+ names and a set of options that are signed by a Certification Authority
+ (CA) key. Clients or servers may then trust only the CA key and verify
+ its signature on a certificate rather than trusting many user/host keys.
+ Note that OpenSSH certificates are a different, and much simpler, format
+ to the X.509 certificates used in ssl(8).
- ssh-keygen supports two types of certificates: user and host. User cer-
- tificates authenticate users to servers, whereas host certificates au-
- thenticate server hosts to users. To generate a user certificate:
+ ssh-keygen supports two types of certificates: user and host. User
+ certificates authenticate users to servers, whereas host certificates
+ authenticate server hosts to users. To generate a user certificate:
$ ssh-keygen -s /path/to/ca_key -I key_id /path/to/user_key.pub
@@ -334,83 +349,90 @@ CERTIFICATES
$ ssh-keygen -s /path/to/ca_key -I key_id -h /path/to/host_key.pub
- The host certificate will be output to /path/to/host_key-cert.pub. In
- both cases, key_id is a "key identifier" that is logged by the server
+ The host certificate will be output to /path/to/host_key-cert.pub.
+
+ It is possible to sign using a CA key stored in a PKCS#11 token by
+ providing the token library using -D and identifying the CA key by
+ providing its public half as an argument to -s:
+
+ $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id host_key.pub
+
+ In all cases, key_id is a "key identifier" that is logged by the server
when the certificate is used for authentication.
- Certificates may be limited to be valid for a set of principal (us-
- er/host) names. By default, generated certificates are valid for all
- users or hosts. To generate a certificate for a specified set of princi-
- pals:
+ Certificates may be limited to be valid for a set of principal
+ (user/host) names. By default, generated certificates are valid for all
+ users or hosts. To generate a certificate for a specified set of
+ principals:
$ ssh-keygen -s ca_key -I key_id -n user1,user2 user_key.pub
$ ssh-keygen -s ca_key -I key_id -h -n host.domain user_key.pub
Additional limitations on the validity and use of user certificates may
- be specified through certificate constraints. A constrained certificate
- may disable features of the SSH session, may be valid only when presented
- from particular source addresses or may force the use of a specific com-
- mand. For a list of valid certificate constraints, see the documentation
+ be specified through certificate options. A certificate option may
+ disable features of the SSH session, may be valid only when presented
+ from particular source addresses or may force the use of a specific
+ command. For a list of valid certificate options, see the documentation
for the -O option above.
Finally, certificates may be defined with a validity lifetime. The -V
- option allows specification of certificate start and end times. A cer-
- tificate that is presented at a time outside this range will not be con-
- sidered valid. By default, certificates have a maximum validity inter-
- val.
+ option allows specification of certificate start and end times. A
+ certificate that is presented at a time outside this range will not be
+ considered valid. By default, certificates have a maximum validity
+ interval.
- For certificates to be used for user or host authentication, the CA pub-
- lic key must be trusted by sshd(8) or ssh(1). Please refer to those man-
- ual pages for details.
+ For certificates to be used for user or host authentication, the CA
+ public key must be trusted by sshd(8) or ssh(1). Please refer to those
+ manual pages for details.
FILES
~/.ssh/identity
Contains the protocol version 1 RSA authentication identity of
- the user. This file should not be readable by anyone but the us-
- er. It is possible to specify a passphrase when generating the
+ the user. This file should not be readable by anyone but the
+ user. It is possible to specify a passphrase when generating the
key; that passphrase will be used to encrypt the private part of
- this file using 128-bit AES. This file is not automatically ac-
- cessed by ssh-keygen but it is offered as the default file for
+ this file using 128-bit AES. This file is not automatically
+ accessed by ssh-keygen but it is offered as the default file for
the private key. ssh(1) will read this file when a login attempt
is made.
~/.ssh/identity.pub
- Contains the protocol version 1 RSA public key for authentica-
- tion. The contents of this file should be added to
+ Contains the protocol version 1 RSA public key for
+ authentication. The contents of this file should be added to
~/.ssh/authorized_keys on all machines where the user wishes to
log in using RSA authentication. There is no need to keep the
contents of this file secret.
~/.ssh/id_dsa
Contains the protocol version 2 DSA authentication identity of
- the user. This file should not be readable by anyone but the us-
- er. It is possible to specify a passphrase when generating the
+ the user. This file should not be readable by anyone but the
+ user. It is possible to specify a passphrase when generating the
key; that passphrase will be used to encrypt the private part of
- this file using 128-bit AES. This file is not automatically ac-
- cessed by ssh-keygen but it is offered as the default file for
+ this file using 128-bit AES. This file is not automatically
+ accessed by ssh-keygen but it is offered as the default file for
the private key. ssh(1) will read this file when a login attempt
is made.
~/.ssh/id_dsa.pub
- Contains the protocol version 2 DSA public key for authentica-
- tion. The contents of this file should be added to
+ Contains the protocol version 2 DSA public key for
+ authentication. The contents of this file should be added to
~/.ssh/authorized_keys on all machines where the user wishes to
log in using public key authentication. There is no need to keep
the contents of this file secret.
~/.ssh/id_rsa
Contains the protocol version 2 RSA authentication identity of
- the user. This file should not be readable by anyone but the us-
- er. It is possible to specify a passphrase when generating the
+ the user. This file should not be readable by anyone but the
+ user. It is possible to specify a passphrase when generating the
key; that passphrase will be used to encrypt the private part of
- this file using 128-bit AES. This file is not automatically ac-
- cessed by ssh-keygen but it is offered as the default file for
+ this file using 128-bit AES. This file is not automatically
+ accessed by ssh-keygen but it is offered as the default file for
the private key. ssh(1) will read this file when a login attempt
is made.
~/.ssh/id_rsa.pub
- Contains the protocol version 2 RSA public key for authentica-
- tion. The contents of this file should be added to
+ Contains the protocol version 2 RSA public key for
+ authentication. The contents of this file should be added to
~/.ssh/authorized_keys on all machines where the user wishes to
log in using public key authentication. There is no need to keep
the contents of this file secret.
@@ -431,4 +453,4 @@ AUTHORS
created OpenSSH. Markus Friedl contributed the support for SSH protocol
versions 1.5 and 2.0.
-OpenBSD 4.7 March 13, 2010 7
+OpenBSD 4.8 August 4, 2010 OpenBSD 4.8
diff --git a/ssh-keygen.1 b/ssh-keygen.1
index 3e03a9bd0cd9..9acd8f8c9288 100644
--- a/ssh-keygen.1
+++ b/ssh-keygen.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-keygen.1,v 1.92 2010/03/13 23:38:13 jmc Exp $
+.\" $OpenBSD: ssh-keygen.1,v 1.98 2010/08/04 06:07:11 djm Exp $
.\"
.\" -*- nroff -*-
.\"
@@ -37,15 +37,15 @@
.\" (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 $Mdocdate: March 13 2010 $
+.Dd $Mdocdate: August 4 2010 $
.Dt SSH-KEYGEN 1
.Os
.Sh NAME
.Nm ssh-keygen
.Nd authentication key generation, management and conversion
.Sh SYNOPSIS
-.Nm ssh-keygen
.Bk -words
+.Nm ssh-keygen
.Op Fl q
.Op Fl b Ar bits
.Fl t Ar type
@@ -59,9 +59,11 @@
.Op Fl f Ar keyfile
.Nm ssh-keygen
.Fl i
+.Op Fl m Ar key_format
.Op Fl f Ar input_keyfile
.Nm ssh-keygen
.Fl e
+.Op Fl m Ar key_format
.Op Fl f Ar input_keyfile
.Nm ssh-keygen
.Fl y
@@ -110,8 +112,9 @@
.Fl I Ar certificate_identity
.Op Fl h
.Op Fl n Ar principals
-.Op Fl O Ar constraint
+.Op Fl O Ar option
.Op Fl V Ar validity_interval
+.Op Fl z Ar serial_number
.Ar
.Nm ssh-keygen
.Fl L
@@ -212,13 +215,20 @@ the passphrase if the key has one, and for the new comment.
.It Fl D Ar pkcs11
Download the RSA public keys provided by the PKCS#11 shared library
.Ar pkcs11 .
+When used in combination with
+.Fl s ,
+this option indicates that a CA key resides in a PKCS#11 token (see the
+.Sx CERTIFICATES
+section for details).
.It Fl e
This option will read a private or public OpenSSH key file and
-print the key in
-RFC 4716 SSH Public Key File Format
-to stdout.
-This option allows exporting keys for use by several commercial
-SSH implementations.
+print to stdout the key in one of the formats specified by the
+.Fl m
+option.
+The default export format is
+.Dq RFC4716 .
+This option allows exporting OpenSSH keys for use by other programs, including
+several commercial SSH implementations.
.It Fl F Ar hostname
Search for the specified
.Ar hostname
@@ -269,13 +279,14 @@ Please see the
section for details.
.It Fl i
This option will read an unencrypted private (or public) key file
-in SSH2-compatible format and print an OpenSSH compatible private
+in the format specified by the
+.Fl m
+option and print an OpenSSH compatible private
(or public) key to stdout.
-.Nm
-also reads the
-RFC 4716 SSH Public Key File Format.
-This option allows importing keys from several commercial
-SSH implementations.
+This option allows importing keys from other software, including several
+commercial SSH implementations.
+The default import format is
+.Dq RFC4716 .
.It Fl L
Prints the contents of a certificate.
.It Fl l
@@ -290,6 +301,22 @@ an ASCII art representation of the key is supplied with the fingerprint.
.It Fl M Ar memory
Specify the amount of memory to use (in megabytes) when generating
candidate moduli for DH-GEX.
+.It Fl m Ar key_format
+Specify a key format for the
+.Fl i
+(import) or
+.Fl e
+(export) conversion options.
+The supported key formats are:
+.Dq RFC4716
+(RFC 4716/SSH2 public or private key),
+.Dq PKCS8
+(PEM PKCS8 public key)
+or
+.Dq PEM
+(PEM public key).
+The default conversion format is
+.Dq RFC4716 .
.It Fl N Ar new_passphrase
Provides the new passphrase.
.It Fl n Ar principals
@@ -299,13 +326,13 @@ Multiple principals may be specified, separated by commas.
Please see the
.Sx CERTIFICATES
section for details.
-.It Fl O Ar constraint
-Specify a certificate constraint when signing a key.
+.It Fl O Ar option
+Specify a certificate option when signing a key.
This option may be specified multiple times.
Please see the
.Sx CERTIFICATES
section for details.
-The constraints that are valid for user certificates are:
+The options that are valid for user certificates are:
.Bl -tag -width Ds
.It Ic clear
Clear all enabled permissions.
@@ -355,7 +382,7 @@ is a comma-separated list of one or more address/netmask pairs in CIDR
format.
.El
.Pp
-At present, no constraints are valid for host keys.
+At present, no options are valid for host keys.
.It Fl P Ar passphrase
Provides the (old) passphrase.
.It Fl p
@@ -441,6 +468,10 @@ Specify desired generator when testing candidate moduli for DH-GEX.
.It Fl y
This option will read a private
OpenSSH format file and print an OpenSSH public key to stdout.
+.It Fl z Ar serial_number
+Specifies a serial number to be embedded in the certificate to distinguish
+this certificate from others from the same CA.
+The default serial number is zero.
.El
.Sh MODULI GENERATION
.Nm
@@ -501,7 +532,7 @@ that both ends of a connection share common moduli.
supports signing of keys to produce certificates that may be used for
user or host authentication.
Certificates consist of a public key, some identity information, zero or
-more principal (user or host) names and an optional set of constraints that
+more principal (user or host) names and a set of options that
are signed by a Certification Authority (CA) key.
Clients or servers may then trust only the CA key and verify its signature
on a certificate rather than trusting many user/host keys.
@@ -527,7 +558,17 @@ option:
.Pp
The host certificate will be output to
.Pa /path/to/host_key-cert.pub .
-In both cases,
+.Pp
+It is possible to sign using a CA key stored in a PKCS#11 token by
+providing the token library using
+.Fl D
+and identifying the CA key by providing its public half as an argument
+to
+.Fl s :
+.Pp
+.Dl $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id host_key.pub
+.Pp
+In all cases,
.Ar key_id
is a "key identifier" that is logged by the server when the certificate
is used for authentication.
@@ -541,11 +582,11 @@ To generate a certificate for a specified set of principals:
.Dl "$ ssh-keygen -s ca_key -I key_id -h -n host.domain user_key.pub"
.Pp
Additional limitations on the validity and use of user certificates may
-be specified through certificate constraints.
-A constrained certificate may disable features of the SSH session, may be
+be specified through certificate options.
+A certificate option may disable features of the SSH session, may be
valid only when presented from particular source addresses or may
force the use of a specific command.
-For a list of valid certificate constraints, see the documentation for the
+For a list of valid certificate options, see the documentation for the
.Fl O
option above.
.Pp
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 37e516ff2f1a..d90b1dfdd389 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keygen.c,v 1.185 2010/03/15 19:40:02 stevesk Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.197 2010/08/04 06:07:11 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -105,6 +105,9 @@ char *identity_comment = NULL;
/* Path to CA key when certifying keys. */
char *ca_key_path = NULL;
+/* Certificate serial number */
+long long cert_serial = 0;
+
/* Key type when certifying */
u_int cert_key_type = SSH2_CERT_TYPE_USER;
@@ -118,27 +121,34 @@ char *cert_principals = NULL;
u_int64_t cert_valid_from = 0;
u_int64_t cert_valid_to = ~0ULL;
-/* Certificate constraints */
-#define CONSTRAINT_X_FWD (1)
-#define CONSTRAINT_AGENT_FWD (1<<1)
-#define CONSTRAINT_PORT_FWD (1<<2)
-#define CONSTRAINT_PTY (1<<3)
-#define CONSTRAINT_USER_RC (1<<4)
-#define CONSTRAINT_DEFAULT (CONSTRAINT_X_FWD|CONSTRAINT_AGENT_FWD| \
- CONSTRAINT_PORT_FWD|CONSTRAINT_PTY| \
- CONSTRAINT_USER_RC)
-u_int32_t constraint_flags = CONSTRAINT_DEFAULT;
-char *constraint_command = NULL;
-char *constraint_src_addr = NULL;
-
-/* Dump public key file in format used by real and the original SSH 2 */
-int convert_to_ssh2 = 0;
-int convert_from_ssh2 = 0;
+/* Certificate options */
+#define CERTOPT_X_FWD (1)
+#define CERTOPT_AGENT_FWD (1<<1)
+#define CERTOPT_PORT_FWD (1<<2)
+#define CERTOPT_PTY (1<<3)
+#define CERTOPT_USER_RC (1<<4)
+#define CERTOPT_DEFAULT (CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \
+ CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC)
+u_int32_t certflags_flags = CERTOPT_DEFAULT;
+char *certflags_command = NULL;
+char *certflags_src_addr = NULL;
+
+/* Conversion to/from various formats */
+int convert_to = 0;
+int convert_from = 0;
+enum {
+ FMT_RFC4716,
+ FMT_PKCS8,
+ FMT_PEM
+} convert_format = FMT_RFC4716;
int print_public = 0;
int print_generic = 0;
char *key_type_name = NULL;
+/* Load key from this PKCS#11 provider */
+char *pkcs11provider = NULL;
+
/* argv0 */
extern char *__progname;
@@ -161,9 +171,13 @@ ask_filename(struct passwd *pw, const char *prompt)
case KEY_RSA1:
name = _PATH_SSH_CLIENT_IDENTITY;
break;
+ case KEY_DSA_CERT:
+ case KEY_DSA_CERT_V00:
case KEY_DSA:
name = _PATH_SSH_CLIENT_ID_DSA;
break;
+ case KEY_RSA_CERT:
+ case KEY_RSA_CERT_V00:
case KEY_RSA:
name = _PATH_SSH_CLIENT_ID_RSA;
break;
@@ -209,30 +223,12 @@ load_identity(char *filename)
#define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb
static void
-do_convert_to_ssh2(struct passwd *pw)
+do_convert_to_ssh2(struct passwd *pw, Key *k)
{
- Key *k;
u_int len;
u_char *blob;
char comment[61];
- struct stat st;
- if (!have_identity)
- ask_filename(pw, "Enter file in which the key is");
- if (stat(identity_file, &st) < 0) {
- perror(identity_file);
- exit(1);
- }
- if ((k = key_load_public(identity_file, NULL)) == NULL) {
- if ((k = load_identity(identity_file)) == NULL) {
- fprintf(stderr, "load failed\n");
- exit(1);
- }
- }
- if (k->type == KEY_RSA1) {
- fprintf(stderr, "version 1 keys are not supported\n");
- exit(1);
- }
if (key_to_blob(k, &blob, &len) <= 0) {
fprintf(stderr, "key_to_blob failed\n");
exit(1);
@@ -253,6 +249,81 @@ do_convert_to_ssh2(struct passwd *pw)
}
static void
+do_convert_to_pkcs8(Key *k)
+{
+ switch (key_type_plain(k->type)) {
+ case KEY_RSA:
+ if (!PEM_write_RSA_PUBKEY(stdout, k->rsa))
+ fatal("PEM_write_RSA_PUBKEY failed");
+ break;
+ case KEY_DSA:
+ if (!PEM_write_DSA_PUBKEY(stdout, k->dsa))
+ fatal("PEM_write_DSA_PUBKEY failed");
+ break;
+ default:
+ fatal("%s: unsupported key type %s", __func__, key_type(k));
+ }
+ exit(0);
+}
+
+static void
+do_convert_to_pem(Key *k)
+{
+ switch (key_type_plain(k->type)) {
+ case KEY_RSA:
+ if (!PEM_write_RSAPublicKey(stdout, k->rsa))
+ fatal("PEM_write_RSAPublicKey failed");
+ break;
+#if notyet /* OpenSSH 0.9.8 lacks this function */
+ case KEY_DSA:
+ if (!PEM_write_DSAPublicKey(stdout, k->dsa))
+ fatal("PEM_write_DSAPublicKey failed");
+ break;
+#endif
+ default:
+ fatal("%s: unsupported key type %s", __func__, key_type(k));
+ }
+ exit(0);
+}
+
+static void
+do_convert_to(struct passwd *pw)
+{
+ Key *k;
+ struct stat st;
+
+ if (!have_identity)
+ ask_filename(pw, "Enter file in which the key is");
+ if (stat(identity_file, &st) < 0)
+ fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
+ if ((k = key_load_public(identity_file, NULL)) == NULL) {
+ if ((k = load_identity(identity_file)) == NULL) {
+ fprintf(stderr, "load failed\n");
+ exit(1);
+ }
+ }
+ if (k->type == KEY_RSA1) {
+ fprintf(stderr, "version 1 keys are not supported\n");
+ exit(1);
+ }
+
+ switch (convert_format) {
+ case FMT_RFC4716:
+ do_convert_to_ssh2(pw, k);
+ break;
+ case FMT_PKCS8:
+ do_convert_to_pkcs8(k);
+ break;
+ case FMT_PEM:
+ do_convert_to_pem(k);
+ break;
+ default:
+ fatal("%s: unknown key format %d", __func__, convert_format);
+ }
+ exit(0);
+}
+
+static void
buffer_get_bignum_bits(Buffer *b, BIGNUM *value)
{
u_int bignum_bits = buffer_get_int(b);
@@ -390,29 +461,18 @@ get_line(FILE *fp, char *line, size_t len)
}
static void
-do_convert_from_ssh2(struct passwd *pw)
+do_convert_from_ssh2(struct passwd *pw, Key **k, int *private)
{
- Key *k;
int blen;
u_int len;
char line[1024];
u_char blob[8096];
char encoded[8096];
- struct stat st;
- int escaped = 0, private = 0, ok;
+ int escaped = 0;
FILE *fp;
- if (!have_identity)
- ask_filename(pw, "Enter file in which the key is");
- if (stat(identity_file, &st) < 0) {
- perror(identity_file);
- exit(1);
- }
- fp = fopen(identity_file, "r");
- if (fp == NULL) {
- perror(identity_file);
- exit(1);
- }
+ if ((fp = fopen(identity_file, "r")) == NULL)
+ fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
encoded[0] = '\0';
while ((blen = get_line(fp, line, sizeof(line))) != -1) {
if (line[blen - 1] == '\\')
@@ -420,7 +480,7 @@ do_convert_from_ssh2(struct passwd *pw)
if (strncmp(line, "----", 4) == 0 ||
strstr(line, ": ") != NULL) {
if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL)
- private = 1;
+ *private = 1;
if (strstr(line, " END ") != NULL) {
break;
}
@@ -445,26 +505,130 @@ do_convert_from_ssh2(struct passwd *pw)
fprintf(stderr, "uudecode failed.\n");
exit(1);
}
- k = private ?
+ *k = *private ?
do_convert_private_ssh2_from_blob(blob, blen) :
key_from_blob(blob, blen);
- if (k == NULL) {
+ if (*k == NULL) {
fprintf(stderr, "decode blob failed.\n");
exit(1);
}
- ok = private ?
- (k->type == KEY_DSA ?
- PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, NULL, 0, NULL, NULL) :
- PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, NULL, 0, NULL, NULL)) :
- key_write(k, stdout);
+ fclose(fp);
+}
+
+static void
+do_convert_from_pkcs8(Key **k, int *private)
+{
+ EVP_PKEY *pubkey;
+ FILE *fp;
+
+ if ((fp = fopen(identity_file, "r")) == NULL)
+ fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
+ if ((pubkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL)) == NULL) {
+ fatal("%s: %s is not a recognised public key format", __func__,
+ identity_file);
+ }
+ fclose(fp);
+ switch (EVP_PKEY_type(pubkey->type)) {
+ case EVP_PKEY_RSA:
+ *k = key_new(KEY_UNSPEC);
+ (*k)->type = KEY_RSA;
+ (*k)->rsa = EVP_PKEY_get1_RSA(pubkey);
+ break;
+ case EVP_PKEY_DSA:
+ *k = key_new(KEY_UNSPEC);
+ (*k)->type = KEY_DSA;
+ (*k)->dsa = EVP_PKEY_get1_DSA(pubkey);
+ break;
+ default:
+ fatal("%s: unsupported pubkey type %d", __func__,
+ EVP_PKEY_type(pubkey->type));
+ }
+ EVP_PKEY_free(pubkey);
+ return;
+}
+
+static void
+do_convert_from_pem(Key **k, int *private)
+{
+ FILE *fp;
+ RSA *rsa;
+#ifdef notyet
+ DSA *dsa;
+#endif
+
+ if ((fp = fopen(identity_file, "r")) == NULL)
+ fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
+ if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) {
+ *k = key_new(KEY_UNSPEC);
+ (*k)->type = KEY_RSA;
+ (*k)->rsa = rsa;
+ fclose(fp);
+ return;
+ }
+#if notyet /* OpenSSH 0.9.8 lacks this function */
+ rewind(fp);
+ if ((dsa = PEM_read_DSAPublicKey(fp, NULL, NULL, NULL)) != NULL) {
+ *k = key_new(KEY_UNSPEC);
+ (*k)->type = KEY_DSA;
+ (*k)->dsa = dsa;
+ fclose(fp);
+ return;
+ }
+#endif
+ fatal("%s: unrecognised raw private key format", __func__);
+}
+
+static void
+do_convert_from(struct passwd *pw)
+{
+ Key *k = NULL;
+ int private = 0, ok = 0;
+ struct stat st;
+
+ if (!have_identity)
+ ask_filename(pw, "Enter file in which the key is");
+ if (stat(identity_file, &st) < 0)
+ fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
+
+ switch (convert_format) {
+ case FMT_RFC4716:
+ do_convert_from_ssh2(pw, &k, &private);
+ break;
+ case FMT_PKCS8:
+ do_convert_from_pkcs8(&k, &private);
+ break;
+ case FMT_PEM:
+ do_convert_from_pem(&k, &private);
+ break;
+ default:
+ fatal("%s: unknown key format %d", __func__, convert_format);
+ }
+
+ if (!private)
+ ok = key_write(k, stdout);
+ if (ok)
+ fprintf(stdout, "\n");
+ else {
+ switch (k->type) {
+ case KEY_DSA:
+ ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL,
+ NULL, 0, NULL, NULL);
+ break;
+ case KEY_RSA:
+ ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL,
+ NULL, 0, NULL, NULL);
+ break;
+ default:
+ fatal("%s: unsupported key type %s", __func__,
+ key_type(k));
+ }
+ }
+
if (!ok) {
fprintf(stderr, "key write failed\n");
exit(1);
}
key_free(k);
- if (!private)
- fprintf(stdout, "\n");
- fclose(fp);
exit(0);
}
@@ -493,7 +657,7 @@ do_print_public(struct passwd *pw)
}
static void
-do_download(struct passwd *pw, char *pkcs11provider)
+do_download(struct passwd *pw)
{
#ifdef ENABLE_PKCS11
Key **keys = NULL;
@@ -555,67 +719,68 @@ do_fingerprint(struct passwd *pw)
comment = NULL;
}
- f = fopen(identity_file, "r");
- if (f != NULL) {
- while (fgets(line, sizeof(line), f)) {
- if ((cp = strchr(line, '\n')) == NULL) {
- error("line %d too long: %.40s...",
- num + 1, line);
- skip = 1;
- continue;
- }
- num++;
- if (skip) {
- skip = 0;
- continue;
- }
- *cp = '\0';
+ if ((f = fopen(identity_file, "r")) == NULL)
+ fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
- /* Skip leading whitespace, empty and comment lines. */
- for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
- ;
- if (!*cp || *cp == '\n' || *cp == '#')
- continue;
- i = strtol(cp, &ep, 10);
- if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) {
- int quoted = 0;
- comment = cp;
- for (; *cp && (quoted || (*cp != ' ' &&
- *cp != '\t')); cp++) {
- if (*cp == '\\' && cp[1] == '"')
- cp++; /* Skip both */
- else if (*cp == '"')
- quoted = !quoted;
- }
- if (!*cp)
- continue;
- *cp++ = '\0';
+ while (fgets(line, sizeof(line), f)) {
+ if ((cp = strchr(line, '\n')) == NULL) {
+ error("line %d too long: %.40s...",
+ num + 1, line);
+ skip = 1;
+ continue;
+ }
+ num++;
+ if (skip) {
+ skip = 0;
+ continue;
+ }
+ *cp = '\0';
+
+ /* Skip leading whitespace, empty and comment lines. */
+ for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
+ ;
+ if (!*cp || *cp == '\n' || *cp == '#')
+ continue;
+ i = strtol(cp, &ep, 10);
+ if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) {
+ int quoted = 0;
+ comment = cp;
+ for (; *cp && (quoted || (*cp != ' ' &&
+ *cp != '\t')); cp++) {
+ if (*cp == '\\' && cp[1] == '"')
+ cp++; /* Skip both */
+ else if (*cp == '"')
+ quoted = !quoted;
}
- ep = cp;
- public = key_new(KEY_RSA1);
+ if (!*cp)
+ continue;
+ *cp++ = '\0';
+ }
+ ep = cp;
+ public = key_new(KEY_RSA1);
+ if (key_read(public, &cp) != 1) {
+ cp = ep;
+ key_free(public);
+ public = key_new(KEY_UNSPEC);
if (key_read(public, &cp) != 1) {
- cp = ep;
key_free(public);
- public = key_new(KEY_UNSPEC);
- if (key_read(public, &cp) != 1) {
- key_free(public);
- continue;
- }
+ continue;
}
- comment = *cp ? cp : comment;
- fp = key_fingerprint(public, fptype, rep);
- ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
- printf("%u %s %s (%s)\n", key_size(public), fp,
- comment ? comment : "no comment", key_type(public));
- if (log_level >= SYSLOG_LEVEL_VERBOSE)
- printf("%s\n", ra);
- xfree(ra);
- xfree(fp);
- key_free(public);
- invalid = 0;
}
- fclose(f);
+ comment = *cp ? cp : comment;
+ fp = key_fingerprint(public, fptype, rep);
+ ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
+ printf("%u %s %s (%s)\n", key_size(public), fp,
+ comment ? comment : "no comment", key_type(public));
+ if (log_level >= SYSLOG_LEVEL_VERBOSE)
+ printf("%s\n", ra);
+ xfree(ra);
+ xfree(fp);
+ key_free(public);
+ invalid = 0;
}
+ fclose(f);
+
if (invalid) {
printf("%s is not a public key file.\n", identity_file);
exit(1);
@@ -670,7 +835,7 @@ do_known_hosts(struct passwd *pw, const char *name)
have_identity = 1;
}
if ((in = fopen(identity_file, "r")) == NULL)
- fatal("fopen: %s", strerror(errno));
+ fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
/*
* Find hosts goes to stdout, hash and deletions happen in-place
@@ -1104,7 +1269,7 @@ fmt_validity(u_int64_t valid_from, u_int64_t valid_to)
}
static void
-add_flag_constraint(Buffer *c, const char *name)
+add_flag_option(Buffer *c, const char *name)
{
debug3("%s: %s", __func__, name);
buffer_put_cstring(c, name);
@@ -1112,7 +1277,7 @@ add_flag_constraint(Buffer *c, const char *name)
}
static void
-add_string_constraint(Buffer *c, const char *name, const char *value)
+add_string_option(Buffer *c, const char *name, const char *value)
{
Buffer b;
@@ -1126,25 +1291,62 @@ add_string_constraint(Buffer *c, const char *name, const char *value)
buffer_free(&b);
}
+#define OPTIONS_CRITICAL 1
+#define OPTIONS_EXTENSIONS 2
static void
-prepare_constraint_buf(Buffer *c)
+prepare_options_buf(Buffer *c, int which)
{
-
buffer_clear(c);
- if ((constraint_flags & CONSTRAINT_X_FWD) != 0)
- add_flag_constraint(c, "permit-X11-forwarding");
- if ((constraint_flags & CONSTRAINT_AGENT_FWD) != 0)
- add_flag_constraint(c, "permit-agent-forwarding");
- if ((constraint_flags & CONSTRAINT_PORT_FWD) != 0)
- add_flag_constraint(c, "permit-port-forwarding");
- if ((constraint_flags & CONSTRAINT_PTY) != 0)
- add_flag_constraint(c, "permit-pty");
- if ((constraint_flags & CONSTRAINT_USER_RC) != 0)
- add_flag_constraint(c, "permit-user-rc");
- if (constraint_command != NULL)
- add_string_constraint(c, "force-command", constraint_command);
- if (constraint_src_addr != NULL)
- add_string_constraint(c, "source-address", constraint_src_addr);
+ if ((which & OPTIONS_CRITICAL) != 0 &&
+ certflags_command != NULL)
+ add_string_option(c, "force-command", certflags_command);
+ if ((which & OPTIONS_EXTENSIONS) != 0 &&
+ (certflags_flags & CERTOPT_AGENT_FWD) != 0)
+ add_flag_option(c, "permit-agent-forwarding");
+ if ((which & OPTIONS_EXTENSIONS) != 0 &&
+ (certflags_flags & CERTOPT_PORT_FWD) != 0)
+ add_flag_option(c, "permit-port-forwarding");
+ if ((which & OPTIONS_EXTENSIONS) != 0 &&
+ (certflags_flags & CERTOPT_PTY) != 0)
+ add_flag_option(c, "permit-pty");
+ 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);
+}
+
+static Key *
+load_pkcs11_key(char *path)
+{
+#ifdef ENABLE_PKCS11
+ Key **keys = NULL, *public, *private = NULL;
+ int i, nkeys;
+
+ if ((public = key_load_public(path, NULL)) == NULL)
+ fatal("Couldn't load CA public key \"%s\"", path);
+
+ nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase, &keys);
+ debug3("%s: %d keys", __func__, nkeys);
+ if (nkeys <= 0)
+ fatal("cannot read public key from pkcs11");
+ for (i = 0; i < nkeys; i++) {
+ if (key_equal_public(public, keys[i])) {
+ private = keys[i];
+ continue;
+ }
+ key_free(keys[i]);
+ }
+ xfree(keys);
+ key_free(public);
+ return private;
+#else
+ fatal("no pkcs11 support");
+#endif /* ENABLE_PKCS11 */
}
static void
@@ -1155,9 +1357,33 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
Key *ca, *public;
char *otmp, *tmp, *cp, *out, *comment, **plist = NULL;
FILE *f;
+ int v00 = 0; /* legacy keys */
+
+ if (key_type_name != NULL) {
+ switch (key_type_from_name(key_type_name)) {
+ case KEY_RSA_CERT_V00:
+ case KEY_DSA_CERT_V00:
+ v00 = 1;
+ break;
+ case KEY_UNSPEC:
+ if (strcasecmp(key_type_name, "v00") == 0) {
+ v00 = 1;
+ break;
+ } else if (strcasecmp(key_type_name, "v01") == 0)
+ break;
+ /* FALLTHROUGH */
+ default:
+ fprintf(stderr, "unknown key type %s\n", key_type_name);
+ exit(1);
+ }
+ }
+ pkcs11_init(1);
tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
- if ((ca = load_identity(tmp)) == NULL)
+ if (pkcs11provider != NULL) {
+ if ((ca = load_pkcs11_key(tmp)) == NULL)
+ fatal("No PKCS#11 key matching %s found", ca_key_path);
+ } else if ((ca = load_identity(tmp)) == NULL)
fatal("Couldn't load CA key \"%s\"", tmp);
xfree(tmp);
@@ -1183,15 +1409,24 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
__func__, tmp, key_type(public));
/* Prepare certificate to sign */
- if (key_to_certified(public) != 0)
+ if (key_to_certified(public, v00) != 0)
fatal("Could not upgrade key %s to certificate", tmp);
public->cert->type = cert_key_type;
+ public->cert->serial = (u_int64_t)cert_serial;
public->cert->key_id = xstrdup(cert_key_id);
public->cert->nprincipals = n;
public->cert->principals = plist;
public->cert->valid_after = cert_valid_from;
public->cert->valid_before = cert_valid_to;
- prepare_constraint_buf(&public->cert->constraints);
+ if (v00) {
+ prepare_options_buf(&public->cert->critical,
+ OPTIONS_CRITICAL|OPTIONS_EXTENSIONS);
+ } else {
+ prepare_options_buf(&public->cert->critical,
+ OPTIONS_CRITICAL);
+ prepare_options_buf(&public->cert->extensions,
+ OPTIONS_EXTENSIONS);
+ }
public->cert->signature_key = key_from_private(ca);
if (key_certify(public, ca) != 0)
@@ -1212,17 +1447,19 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
fprintf(f, " %s\n", comment);
fclose(f);
- if (!quiet)
- logit("Signed %s key %s: id \"%s\"%s%s valid %s",
- cert_key_type == SSH2_CERT_TYPE_USER?"user":"host",
- out, cert_key_id,
+ if (!quiet) {
+ logit("Signed %s key %s: id \"%s\" serial %llu%s%s "
+ "valid %s", key_cert_type(public),
+ out, public->cert->key_id, public->cert->serial,
cert_principals != NULL ? " for " : "",
cert_principals != NULL ? cert_principals : "",
fmt_validity(cert_valid_from, cert_valid_to));
+ }
key_free(public);
xfree(out);
}
+ pkcs11_terminate();
exit(0);
}
@@ -1321,50 +1558,92 @@ parse_cert_times(char *timespec)
}
static void
-add_cert_constraint(char *opt)
+add_cert_option(char *opt)
{
char *val;
if (strcmp(opt, "clear") == 0)
- constraint_flags = 0;
+ certflags_flags = 0;
else if (strcasecmp(opt, "no-x11-forwarding") == 0)
- constraint_flags &= ~CONSTRAINT_X_FWD;
+ certflags_flags &= ~CERTOPT_X_FWD;
else if (strcasecmp(opt, "permit-x11-forwarding") == 0)
- constraint_flags |= CONSTRAINT_X_FWD;
+ certflags_flags |= CERTOPT_X_FWD;
else if (strcasecmp(opt, "no-agent-forwarding") == 0)
- constraint_flags &= ~CONSTRAINT_AGENT_FWD;
+ certflags_flags &= ~CERTOPT_AGENT_FWD;
else if (strcasecmp(opt, "permit-agent-forwarding") == 0)
- constraint_flags |= CONSTRAINT_AGENT_FWD;
+ certflags_flags |= CERTOPT_AGENT_FWD;
else if (strcasecmp(opt, "no-port-forwarding") == 0)
- constraint_flags &= ~CONSTRAINT_PORT_FWD;
+ certflags_flags &= ~CERTOPT_PORT_FWD;
else if (strcasecmp(opt, "permit-port-forwarding") == 0)
- constraint_flags |= CONSTRAINT_PORT_FWD;
+ certflags_flags |= CERTOPT_PORT_FWD;
else if (strcasecmp(opt, "no-pty") == 0)
- constraint_flags &= ~CONSTRAINT_PTY;
+ certflags_flags &= ~CERTOPT_PTY;
else if (strcasecmp(opt, "permit-pty") == 0)
- constraint_flags |= CONSTRAINT_PTY;
+ certflags_flags |= CERTOPT_PTY;
else if (strcasecmp(opt, "no-user-rc") == 0)
- constraint_flags &= ~CONSTRAINT_USER_RC;
+ certflags_flags &= ~CERTOPT_USER_RC;
else if (strcasecmp(opt, "permit-user-rc") == 0)
- constraint_flags |= CONSTRAINT_USER_RC;
+ certflags_flags |= CERTOPT_USER_RC;
else if (strncasecmp(opt, "force-command=", 14) == 0) {
val = opt + 14;
if (*val == '\0')
- fatal("Empty force-command constraint");
- if (constraint_command != NULL)
+ fatal("Empty force-command option");
+ if (certflags_command != NULL)
fatal("force-command already specified");
- constraint_command = xstrdup(val);
+ certflags_command = xstrdup(val);
} else if (strncasecmp(opt, "source-address=", 15) == 0) {
val = opt + 15;
if (*val == '\0')
- fatal("Empty source-address constraint");
- if (constraint_src_addr != NULL)
+ fatal("Empty source-address option");
+ if (certflags_src_addr != NULL)
fatal("source-address already specified");
if (addr_match_cidr_list(NULL, val) != 0)
fatal("Invalid source-address list");
- constraint_src_addr = xstrdup(val);
+ certflags_src_addr = xstrdup(val);
} else
- fatal("Unsupported certificate constraint \"%s\"", opt);
+ fatal("Unsupported certificate option \"%s\"", opt);
+}
+
+static void
+show_options(const Buffer *optbuf, int v00, int in_critical)
+{
+ u_char *name, *data;
+ u_int dlen;
+ Buffer options, option;
+
+ buffer_init(&options);
+ buffer_append(&options, buffer_ptr(optbuf), buffer_len(optbuf));
+
+ buffer_init(&option);
+ while (buffer_len(&options) != 0) {
+ name = buffer_get_string(&options, NULL);
+ data = buffer_get_string_ptr(&options, &dlen);
+ buffer_append(&option, data, dlen);
+ printf(" %s", name);
+ if ((v00 || !in_critical) &&
+ (strcmp(name, "permit-X11-forwarding") == 0 ||
+ strcmp(name, "permit-agent-forwarding") == 0 ||
+ strcmp(name, "permit-port-forwarding") == 0 ||
+ strcmp(name, "permit-pty") == 0 ||
+ strcmp(name, "permit-user-rc") == 0))
+ printf("\n");
+ else if ((v00 || in_critical) &&
+ (strcmp(name, "force-command") == 0 ||
+ strcmp(name, "source-address") == 0)) {
+ data = buffer_get_string(&option, NULL);
+ printf(" %s\n", data);
+ xfree(data);
+ } else {
+ printf(" UNKNOWN OPTION (len %u)\n",
+ buffer_len(&option));
+ buffer_clear(&option);
+ }
+ xfree(name);
+ if (buffer_len(&option) != 0)
+ fatal("Option corrupt: extra data at end");
+ }
+ buffer_free(&option);
+ buffer_free(&options);
}
static void
@@ -1373,31 +1652,31 @@ do_show_cert(struct passwd *pw)
Key *key;
struct stat st;
char *key_fp, *ca_fp;
- Buffer constraints, constraint;
- u_char *name, *data;
- u_int i, dlen;
+ u_int i, v00;
if (!have_identity)
ask_filename(pw, "Enter file in which the key is");
- if (stat(identity_file, &st) < 0) {
- perror(identity_file);
- exit(1);
- }
+ if (stat(identity_file, &st) < 0)
+ fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
if ((key = key_load_public(identity_file, NULL)) == NULL)
fatal("%s is not a public key", identity_file);
if (!key_is_cert(key))
fatal("%s is not a certificate", identity_file);
-
+ v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00;
+
key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
ca_fp = key_fingerprint(key->cert->signature_key,
SSH_FP_MD5, SSH_FP_HEX);
printf("%s:\n", identity_file);
- printf(" %s %s certificate %s\n", key_type(key),
- key_cert_type(key), key_fp);
- printf(" Signed by %s CA %s\n",
+ printf(" Type: %s %s certificate\n", key_ssh_name(key),
+ key_cert_type(key));
+ printf(" Public key: %s %s\n", key_type(key), key_fp);
+ printf(" Signing CA: %s %s\n",
key_type(key->cert->signature_key), ca_fp);
- printf(" Key ID \"%s\"\n", key->cert->key_id);
+ printf(" Key ID: \"%s\"\n", key->cert->key_id);
+ if (!v00)
+ printf(" Serial: %llu\n", key->cert->serial);
printf(" Valid: %s\n",
fmt_validity(key->cert->valid_after, key->cert->valid_before));
printf(" Principals: ");
@@ -1409,45 +1688,22 @@ do_show_cert(struct passwd *pw)
key->cert->principals[i]);
printf("\n");
}
- printf(" Constraints: ");
- if (buffer_len(&key->cert->constraints) == 0)
+ printf(" Critical Options: ");
+ if (buffer_len(&key->cert->critical) == 0)
printf("(none)\n");
else {
printf("\n");
- buffer_init(&constraints);
- buffer_append(&constraints,
- buffer_ptr(&key->cert->constraints),
- buffer_len(&key->cert->constraints));
- buffer_init(&constraint);
- while (buffer_len(&constraints) != 0) {
- name = buffer_get_string(&constraints, NULL);
- data = buffer_get_string_ptr(&constraints, &dlen);
- buffer_append(&constraint, data, dlen);
- printf(" %s", name);
- if (strcmp(name, "permit-X11-forwarding") == 0 ||
- strcmp(name, "permit-agent-forwarding") == 0 ||
- strcmp(name, "permit-port-forwarding") == 0 ||
- strcmp(name, "permit-pty") == 0 ||
- strcmp(name, "permit-user-rc") == 0)
- printf("\n");
- else if (strcmp(name, "force-command") == 0 ||
- strcmp(name, "source-address") == 0) {
- data = buffer_get_string(&constraint, NULL);
- printf(" %s\n", data);
- xfree(data);
- } else {
- printf(" UNKNOWN CONSTRAINT (len %u)\n",
- buffer_len(&constraint));
- buffer_clear(&constraint);
- }
- xfree(name);
- if (buffer_len(&constraint) != 0)
- fatal("Constraint corrupt: extra data at end");
+ show_options(&key->cert->critical, v00, 1);
+ }
+ if (!v00) {
+ printf(" Extensions: ");
+ if (buffer_len(&key->cert->extensions) == 0)
+ printf("(none)\n");
+ else {
+ printf("\n");
+ show_options(&key->cert->extensions, v00, 0);
}
- buffer_free(&constraint);
- buffer_free(&constraints);
}
-
exit(0);
}
@@ -1464,7 +1720,7 @@ usage(void)
#ifdef ENABLE_PKCS11
fprintf(stderr, " -D pkcs11 Download public key from pkcs11 token.\n");
#endif
- fprintf(stderr, " -e Convert OpenSSH to RFC 4716 key file.\n");
+ fprintf(stderr, " -e Export OpenSSH to foreign format key file.\n");
fprintf(stderr, " -F hostname Find hostname in known hosts file.\n");
fprintf(stderr, " -f filename Filename of the key file.\n");
fprintf(stderr, " -G file Generate candidates for DH-GEX moduli.\n");
@@ -1472,26 +1728,28 @@ usage(void)
fprintf(stderr, " -H Hash names in known_hosts file.\n");
fprintf(stderr, " -h Generate host certificate instead of a user certificate.\n");
fprintf(stderr, " -I key_id Key identifier to include in certificate.\n");
- fprintf(stderr, " -i Convert RFC 4716 to OpenSSH key file.\n");
+ fprintf(stderr, " -i Import foreign format to OpenSSH key file.\n");
fprintf(stderr, " -L Print the contents of a certificate.\n");
fprintf(stderr, " -l Show fingerprint of key file.\n");
fprintf(stderr, " -M memory Amount of memory (MB) to use for generating DH-GEX moduli.\n");
- fprintf(stderr, " -n name,... User/host principal names to include in certificate\n");
+ fprintf(stderr, " -m key_fmt Conversion format for -e/-i (PEM|PKCS8|RFC4716).\n");
fprintf(stderr, " -N phrase Provide new passphrase.\n");
- fprintf(stderr, " -O cnstr Specify a certificate constraint.\n");
+ fprintf(stderr, " -n name,... User/host principal names to include in certificate\n");
+ fprintf(stderr, " -O option Specify a certificate option.\n");
fprintf(stderr, " -P phrase Provide old passphrase.\n");
fprintf(stderr, " -p Change passphrase of private key file.\n");
fprintf(stderr, " -q Quiet.\n");
fprintf(stderr, " -R hostname Remove host from known_hosts file.\n");
fprintf(stderr, " -r hostname Print DNS resource record.\n");
- fprintf(stderr, " -s ca_key Certify keys with CA key.\n");
fprintf(stderr, " -S start Start point (hex) for generating DH-GEX moduli.\n");
+ fprintf(stderr, " -s ca_key Certify keys with CA key.\n");
fprintf(stderr, " -T file Screen candidates for DH-GEX moduli.\n");
fprintf(stderr, " -t type Specify type of key to create.\n");
fprintf(stderr, " -V from:to Specify certificate validity interval.\n");
fprintf(stderr, " -v Verbose.\n");
fprintf(stderr, " -W gen Generator to use for generating DH-GEX moduli.\n");
fprintf(stderr, " -y Read private key file and print public key.\n");
+ fprintf(stderr, " -z serial Specify a serial number.\n");
exit(1);
}
@@ -1503,12 +1761,12 @@ int
main(int argc, char **argv)
{
char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2;
- char out_file[MAXPATHLEN], *pkcs11provider = NULL;
- char *rr_hostname = NULL;
+ char out_file[MAXPATHLEN], *rr_hostname = NULL;
Key *private, *public;
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;
BIGNUM *start = NULL;
@@ -1540,8 +1798,8 @@ main(int argc, char **argv)
exit(1);
}
- while ((opt = getopt(argc, argv, "degiqpclBHLhvxXyF:b:f:t:D:I:P:N:n:"
- "O:C:r:g:R:T:G:M:S:s:a:V:W:")) != -1) {
+ while ((opt = getopt(argc, argv, "degiqpclBHLhvxXyF: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 'b':
bits = (u_int32_t)strtonum(optarg, 768, 32768, &errstr);
@@ -1572,6 +1830,21 @@ main(int argc, char **argv)
case 'B':
print_bubblebabble = 1;
break;
+ case 'm':
+ if (strcasecmp(optarg, "RFC4716") == 0 ||
+ strcasecmp(optarg, "ssh2") == 0) {
+ convert_format = FMT_RFC4716;
+ break;
+ }
+ if (strcasecmp(optarg, "PKCS8") == 0) {
+ convert_format = FMT_PKCS8;
+ break;
+ }
+ if (strcasecmp(optarg, "PEM") == 0) {
+ convert_format = FMT_PEM;
+ break;
+ }
+ fatal("Unsupported conversion format \"%s\"", optarg);
case 'n':
cert_principals = optarg;
break;
@@ -1597,7 +1870,7 @@ main(int argc, char **argv)
identity_new_passphrase = optarg;
break;
case 'O':
- add_cert_constraint(optarg);
+ add_cert_option(optarg);
break;
case 'C':
identity_comment = optarg;
@@ -1608,16 +1881,16 @@ main(int argc, char **argv)
case 'e':
case 'x':
/* export key */
- convert_to_ssh2 = 1;
+ convert_to = 1;
break;
case 'h':
cert_key_type = SSH2_CERT_TYPE_HOST;
- constraint_flags = 0;
+ certflags_flags = 0;
break;
case 'i':
case 'X':
/* import key */
- convert_from_ssh2 = 1;
+ convert_from = 1;
break;
case 'y':
print_public = 1;
@@ -1661,9 +1934,8 @@ main(int argc, char **argv)
break;
case 'M':
memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr);
- if (errstr) {
+ if (errstr)
fatal("Memory limit is %s: %s", errstr, optarg);
- }
break;
case 'G':
do_gen_candidates = 1;
@@ -1685,6 +1957,11 @@ main(int argc, char **argv)
case 'V':
parse_cert_times(optarg);
break;
+ case 'z':
+ cert_serial = strtonum(optarg, 0, LLONG_MAX, &errstr);
+ if (errstr)
+ fatal("Invalid serial number: %s", errstr);
+ break;
case '?':
default:
usage();
@@ -1729,10 +2006,10 @@ main(int argc, char **argv)
do_change_passphrase(pw);
if (change_comment)
do_change_comment(pw);
- if (convert_to_ssh2)
- do_convert_to_ssh2(pw);
- if (convert_from_ssh2)
- do_convert_from_ssh2(pw);
+ if (convert_to)
+ do_convert_to(pw);
+ if (convert_from)
+ do_convert_from(pw);
if (print_public)
do_print_public(pw);
if (rr_hostname != NULL) {
@@ -1759,7 +2036,7 @@ main(int argc, char **argv)
}
}
if (pkcs11provider != NULL)
- do_download(pw, pkcs11provider);
+ do_download(pw);
if (do_gen_candidates) {
FILE *out = fopen(out_file, "w");
@@ -1811,6 +2088,12 @@ main(int argc, char **argv)
}
if (bits == 0)
bits = (type == KEY_DSA) ? DEFAULT_BITS_DSA : 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");
if (!quiet)
@@ -1826,13 +2109,19 @@ main(int argc, char **argv)
ask_filename(pw, "Enter file in which to save the key");
/* Create ~/.ssh directory if it doesn't already exist. */
- snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, _PATH_SSH_USER_DIR);
- if (strstr(identity_file, dotsshdir) != NULL &&
- stat(dotsshdir, &st) < 0) {
- if (mkdir(dotsshdir, 0700) < 0)
- error("Could not create directory '%s'.", dotsshdir);
- else if (!quiet)
- printf("Created directory '%s'.\n", dotsshdir);
+ snprintf(dotsshdir, sizeof dotsshdir, "%s/%s",
+ pw->pw_dir, _PATH_SSH_USER_DIR);
+ if (strstr(identity_file, dotsshdir) != NULL) {
+ if (stat(dotsshdir, &st) < 0) {
+ if (errno != ENOENT) {
+ error("Could not stat %s: %s", dotsshdir,
+ strerror(errno));
+ } else if (mkdir(dotsshdir, 0700) < 0) {
+ error("Could not create directory '%s': %s",
+ dotsshdir, strerror(errno));
+ } else if (!quiet)
+ printf("Created directory '%s'.\n", dotsshdir);
+ }
}
/* If the file already exists, ask the user to confirm. */
if (stat(identity_file, &st) >= 0) {
diff --git a/ssh-keyscan.0 b/ssh-keyscan.0
index 8a0ef60e4859..9bf4cc25279b 100644
--- a/ssh-keyscan.0
+++ b/ssh-keyscan.0
@@ -8,17 +8,17 @@ SYNOPSIS
[host | addrlist namelist] ...
DESCRIPTION
- ssh-keyscan is a utility for gathering the public ssh host keys of a num-
- ber of hosts. It was designed to aid in building and verifying
+ ssh-keyscan is a utility for gathering the public ssh host keys of a
+ number of hosts. It was designed to aid in building and verifying
ssh_known_hosts files. ssh-keyscan provides a minimal interface suitable
for use by shell and perl scripts.
- ssh-keyscan uses non-blocking socket I/O to contact as many hosts as pos-
- sible in parallel, so it is very efficient. The keys from a domain of
+ ssh-keyscan uses non-blocking socket I/O to contact as many hosts as
+ possible in parallel, so it is very efficient. The keys from a domain of
1,000 hosts can be collected in tens of seconds, even when some of those
hosts are down or do not run ssh. For scanning, one does not need login
- access to the machines that are being scanned, nor does the scanning pro-
- cess involve any encryption.
+ access to the machines that are being scanned, nor does the scanning
+ process involve any encryption.
The options are as follows:
@@ -32,8 +32,8 @@ DESCRIPTION
read hosts or addrlist namelist pairs from the standard input.
-H Hash all hostnames and addresses in the output. Hashed names may
- be used normally by ssh and sshd, but they do not reveal identi-
- fying information should the file's contents be disclosed.
+ be used normally by ssh and sshd, but they do not reveal
+ identifying information should the file's contents be disclosed.
-p port
Port to connect to on the remote host.
@@ -42,8 +42,8 @@ DESCRIPTION
Set the timeout for connection attempts. If timeout seconds have
elapsed since a connection was initiated to a host or since the
last time anything was read from that host, then the connection
- is closed and the host in question considered unavailable. De-
- fault is 5 seconds.
+ is closed and the host in question considered unavailable.
+ Default is 5 seconds.
-t type
Specifies the type of the key to fetch from the scanned hosts.
@@ -56,11 +56,12 @@ DESCRIPTION
about its progress.
SECURITY
- If an ssh_known_hosts file is constructed using ssh-keyscan without veri-
- fying the keys, users will be vulnerable to man in the middle attacks.
- On the other hand, if the security model allows such a risk, ssh-keyscan
- can help in the detection of tampered keyfiles or man in the middle at-
- tacks which have begun after the ssh_known_hosts file was created.
+ If an ssh_known_hosts file is constructed using ssh-keyscan without
+ verifying the keys, users will be vulnerable to man in the middle
+ attacks. On the other hand, if the security model allows such a risk,
+ ssh-keyscan can help in the detection of tampered keyfiles or man in the
+ middle attacks which have begun after the ssh_known_hosts file was
+ created.
FILES
Input format:
@@ -104,4 +105,4 @@ BUGS
This is because it opens a connection to the ssh port, reads the public
key, and drops the connection as soon as it gets the key.
-OpenBSD 4.7 January 9, 2010 2
+OpenBSD 4.8 January 9, 2010 OpenBSD 4.8
diff --git a/ssh-keyscan.c b/ssh-keyscan.c
index 7afe446ae288..b6cf427cd62a 100644
--- a/ssh-keyscan.c
+++ b/ssh-keyscan.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keyscan.c,v 1.81 2010/01/09 23:04:13 dtucker Exp $ */
+/* $OpenBSD: ssh-keyscan.c,v 1.82 2010/06/22 04:54:30 djm Exp $ */
/*
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
*
@@ -104,122 +104,6 @@ typedef struct Connection {
TAILQ_HEAD(conlist, Connection) tq; /* Timeout Queue */
con *fdcon;
-/*
- * This is just a wrapper around fgets() to make it usable.
- */
-
-/* Stress-test. Increase this later. */
-#define LINEBUF_SIZE 16
-
-typedef struct {
- char *buf;
- u_int size;
- int lineno;
- const char *filename;
- FILE *stream;
- void (*errfun) (const char *,...);
-} Linebuf;
-
-static Linebuf *
-Linebuf_alloc(const char *filename, void (*errfun) (const char *,...))
-{
- Linebuf *lb;
-
- if (!(lb = malloc(sizeof(*lb)))) {
- if (errfun)
- (*errfun) ("linebuf (%s): malloc failed\n",
- filename ? filename : "(stdin)");
- return (NULL);
- }
- if (filename) {
- lb->filename = filename;
- if (!(lb->stream = fopen(filename, "r"))) {
- xfree(lb);
- if (errfun)
- (*errfun) ("%s: %s\n", filename, strerror(errno));
- return (NULL);
- }
- } else {
- lb->filename = "(stdin)";
- lb->stream = stdin;
- }
-
- if (!(lb->buf = malloc((lb->size = LINEBUF_SIZE)))) {
- if (errfun)
- (*errfun) ("linebuf (%s): malloc failed\n", lb->filename);
- xfree(lb);
- return (NULL);
- }
- lb->errfun = errfun;
- lb->lineno = 0;
- return (lb);
-}
-
-static void
-Linebuf_free(Linebuf * lb)
-{
- fclose(lb->stream);
- xfree(lb->buf);
- xfree(lb);
-}
-
-#if 0
-static void
-Linebuf_restart(Linebuf * lb)
-{
- clearerr(lb->stream);
- rewind(lb->stream);
- lb->lineno = 0;
-}
-
-static int
-Linebuf_lineno(Linebuf * lb)
-{
- return (lb->lineno);
-}
-#endif
-
-static char *
-Linebuf_getline(Linebuf * lb)
-{
- size_t n = 0;
- void *p;
-
- lb->lineno++;
- for (;;) {
- /* Read a line */
- if (!fgets(&lb->buf[n], lb->size - n, lb->stream)) {
- if (ferror(lb->stream) && lb->errfun)
- (*lb->errfun)("%s: %s\n", lb->filename,
- strerror(errno));
- return (NULL);
- }
- n = strlen(lb->buf);
-
- /* Return it or an error if it fits */
- if (n > 0 && lb->buf[n - 1] == '\n') {
- lb->buf[n - 1] = '\0';
- return (lb->buf);
- }
- if (n != lb->size - 1) {
- if (lb->errfun)
- (*lb->errfun)("%s: skipping incomplete last line\n",
- lb->filename);
- return (NULL);
- }
- /* Double the buffer if we need more space */
- lb->size *= 2;
- if ((p = realloc(lb->buf, lb->size)) == NULL) {
- lb->size /= 2;
- if (lb->errfun)
- (*lb->errfun)("linebuf (%s): realloc failed\n",
- lb->filename);
- return (NULL);
- }
- lb->buf = p;
- }
-}
-
static int
fdlim_get(int hard)
{
@@ -724,8 +608,10 @@ int
main(int argc, char **argv)
{
int debug_flag = 0, log_level = SYSLOG_LEVEL_INFO;
- int opt, fopt_count = 0;
- char *tname;
+ int opt, fopt_count = 0, j;
+ char *tname, *cp, line[NI_MAXHOST];
+ FILE *fp;
+ u_long linenum;
extern int optind;
extern char *optarg;
@@ -826,19 +712,40 @@ main(int argc, char **argv)
read_wait_nfdset = howmany(maxfd, NFDBITS);
read_wait = xcalloc(read_wait_nfdset, sizeof(fd_mask));
- if (fopt_count) {
- Linebuf *lb;
- char *line;
- int j;
+ for (j = 0; j < fopt_count; j++) {
+ if (argv[j] == NULL)
+ fp = stdin;
+ else if ((fp = fopen(argv[j], "r")) == NULL)
+ fatal("%s: %s: %s", __progname, argv[j],
+ strerror(errno));
+ linenum = 0;
+
+ while (read_keyfile_line(fp,
+ argv[j] == NULL ? "(stdin)" : argv[j], line, sizeof(line),
+ &linenum) != -1) {
+ /* Chomp off trailing whitespace and comments */
+ if ((cp = strchr(line, '#')) == NULL)
+ cp = line + strlen(line) - 1;
+ while (cp >= line) {
+ if (*cp == ' ' || *cp == '\t' ||
+ *cp == '\n' || *cp == '#')
+ *cp-- = '\0';
+ else
+ break;
+ }
- for (j = 0; j < fopt_count; j++) {
- lb = Linebuf_alloc(argv[j], error);
- if (!lb)
+ /* Skip empty lines */
+ if (*line == '\0')
continue;
- while ((line = Linebuf_getline(lb)) != NULL)
- do_host(line);
- Linebuf_free(lb);
+
+ do_host(line);
}
+
+ if (ferror(fp))
+ fatal("%s: %s: %s", __progname, argv[j],
+ strerror(errno));
+
+ fclose(fp);
}
while (optind < argc)
diff --git a/ssh-keysign.0 b/ssh-keysign.0
index 20a8eaa87943..cd119139f256 100644
--- a/ssh-keysign.0
+++ b/ssh-keysign.0
@@ -16,8 +16,8 @@ DESCRIPTION
to ``yes''.
ssh-keysign is not intended to be invoked by the user, but from ssh(1).
- See ssh(1) and sshd(8) for more information about host-based authentica-
- tion.
+ See ssh(1) and sshd(8) for more information about host-based
+ authentication.
FILES
/etc/ssh/ssh_config
@@ -30,6 +30,11 @@ FILES
are readable only by root, ssh-keysign must be set-uid root if
host-based authentication is used.
+ /etc/ssh/ssh_host_dsa_key-cert.pub, /etc/ssh/ssh_host_rsa_key-cert.pub
+ If these files exist they are assumed to contain public
+ certificate information corresponding with the private keys
+ above.
+
SEE ALSO
ssh(1), ssh-keygen(1), ssh_config(5), sshd(8)
@@ -39,4 +44,4 @@ HISTORY
AUTHORS
Markus Friedl <markus@openbsd.org>
-OpenBSD 4.7 May 31, 2007 1
+OpenBSD 4.8 August 4, 2010 OpenBSD 4.8
diff --git a/ssh-keysign.8 b/ssh-keysign.8
index 3ba54b935ff1..46c0ee9cd9d8 100644
--- a/ssh-keysign.8
+++ b/ssh-keysign.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-keysign.8,v 1.9 2007/05/31 19:20:16 jmc Exp $
+.\" $OpenBSD: ssh-keysign.8,v 1.10 2010/08/04 05:42:47 djm Exp $
.\"
.\" Copyright (c) 2002 Markus Friedl. All rights reserved.
.\"
@@ -22,7 +22,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 $Mdocdate: May 31 2007 $
+.Dd $Mdocdate: August 4 2010 $
.Dt SSH-KEYSIGN 8
.Os
.Sh NAME
@@ -68,6 +68,9 @@ accessible to others.
Since they are readable only by root,
.Nm
must be set-uid root if host-based authentication is used.
+.It Pa /etc/ssh/ssh_host_dsa_key-cert.pub, /etc/ssh/ssh_host_rsa_key-cert.pub
+If these files exist they are assumed to contain public certificate
+information corresponding with the private keys above.
.El
.Sh SEE ALSO
.Xr ssh 1 ,
diff --git a/ssh-keysign.c b/ssh-keysign.c
index 0fdcebbd22c7..0c7077050f37 100644
--- a/ssh-keysign.c
+++ b/ssh-keysign.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keysign.c,v 1.30 2010/01/13 01:20:20 dtucker Exp $ */
+/* $OpenBSD: ssh-keysign.c,v 1.32 2010/08/04 06:08:40 djm Exp $ */
/*
* Copyright (c) 2002 Markus Friedl. All rights reserved.
*
@@ -232,7 +232,7 @@ main(int argc, char **argv)
found = 0;
for (i = 0; i < 2; i++) {
if (keys[i] != NULL &&
- key_equal(key, keys[i])) {
+ key_equal_public(key, keys[i])) {
found = 1;
break;
}
diff --git a/ssh-pkcs11-helper.0 b/ssh-pkcs11-helper.0
index 9eb2bc96a33d..664ec971f1d8 100644
--- a/ssh-pkcs11-helper.0
+++ b/ssh-pkcs11-helper.0
@@ -22,4 +22,4 @@ HISTORY
AUTHORS
Markus Friedl <markus@openbsd.org>
-OpenBSD 4.7 February 10, 2010 1
+OpenBSD 4.8 February 10, 2010 OpenBSD 4.8
diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c
index f0192dcf1c78..286c232c7266 100644
--- a/ssh-pkcs11.c
+++ b/ssh-pkcs11.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-pkcs11.c,v 1.4 2010/02/24 06:12:53 djm Exp $ */
+/* $OpenBSD: ssh-pkcs11.c,v 1.6 2010/06/08 21:32:19 markus Exp $ */
/*
* Copyright (c) 2010 Markus Friedl. All rights reserved.
*
@@ -187,6 +187,34 @@ pkcs11_rsa_finish(RSA *rsa)
return (rv);
}
+/* find a single 'obj' for given attributes */
+static int
+pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr,
+ CK_ULONG nattr, CK_OBJECT_HANDLE *obj)
+{
+ CK_FUNCTION_LIST *f;
+ CK_SESSION_HANDLE session;
+ CK_ULONG nfound = 0;
+ CK_RV rv;
+ int ret = -1;
+
+ f = p->function_list;
+ session = p->slotinfo[slotidx].session;
+ if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) {
+ error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv);
+ return (-1);
+ }
+ if ((rv = f->C_FindObjects(session, obj, 1, &nfound)) != CKR_OK ||
+ nfound != 1) {
+ debug("C_FindObjects failed (nfound %lu nattr %lu): %lu",
+ nfound, nattr, rv);
+ } else
+ ret = 0;
+ if ((rv = f->C_FindObjectsFinal(session)) != CKR_OK)
+ error("C_FindObjectsFinal failed: %lu", rv);
+ return (ret);
+}
+
/* openssl callback doing the actual signing operation */
static int
pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
@@ -196,7 +224,7 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
struct pkcs11_slotinfo *si;
CK_FUNCTION_LIST *f;
CK_OBJECT_HANDLE obj;
- CK_ULONG tlen = 0, nfound = 0;
+ CK_ULONG tlen = 0;
CK_RV rv;
CK_OBJECT_CLASS private_key_class = CKO_PRIVATE_KEY;
CK_BBOOL true_val = CK_TRUE;
@@ -247,13 +275,10 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
}
key_filter[1].pValue = k11->keyid;
key_filter[1].ulValueLen = k11->keyid_len;
- if ((rv = f->C_FindObjectsInit(si->session, key_filter, 3)) != CKR_OK) {
- error("C_FindObjectsInit failed: %lu", rv);
- return (-1);
- }
- if ((rv = f->C_FindObjects(si->session, &obj, 1, &nfound)) != CKR_OK ||
- nfound != 1) {
- error("C_FindObjects failed (%lu nfound): %lu", nfound, rv);
+ /* try to find object w/CKA_SIGN first, retry w/o */
+ if (pkcs11_find(k11->provider, k11->slotidx, key_filter, 3, &obj) < 0 &&
+ pkcs11_find(k11->provider, k11->slotidx, key_filter, 2, &obj) < 0) {
+ error("cannot find private key");
} else if ((rv = f->C_SignInit(si->session, &mech, obj)) != CKR_OK) {
error("C_SignInit failed: %lu", rv);
} else {
@@ -265,8 +290,6 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
else
error("C_Sign failed: %lu", rv);
}
- if ((rv = f->C_FindObjectsFinal(si->session)) != CKR_OK)
- error("C_FindObjectsFinal failed: %lu", rv);
return (rval);
}
@@ -410,7 +433,13 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, Key ***keysp,
error("C_GetAttributeValue failed: %lu", rv);
continue;
}
- /* allocate buffers for attributes, XXX check ulValueLen? */
+ /* check that none of the attributes are zero length */
+ if (attribs[0].ulValueLen == 0 ||
+ attribs[1].ulValueLen == 0 ||
+ attribs[2].ulValueLen == 0) {
+ continue;
+ }
+ /* allocate buffers for attributes */
for (i = 0; i < 3; i++)
attribs[i].pValue = xmalloc(attribs[i].ulValueLen);
/* retrieve ID, modulus and public exponent of RSA key */
diff --git a/ssh-rand-helper.0 b/ssh-rand-helper.0
index 51b6f557158e..5bc19e8a720e 100644
--- a/ssh-rand-helper.0
+++ b/ssh-rand-helper.0
@@ -27,8 +27,8 @@ DESCRIPTION
random numbers from a EGD/PRNGd server via a unix domain or localhost tcp
socket.
- This program is not intended to be run by the end-user, so the few com-
- mandline options are for debugging purposes only.
+ This program is not intended to be run by the end-user, so the few
+ commandline options are for debugging purposes only.
-b bytes
Specify the number of random bytes to include in the output.
@@ -48,4 +48,4 @@ AUTHORS
SEE ALSO
ssh(1), ssh-add(1), ssh-keygen(1), sshd(8)
-OpenBSD 4.7 April 14, 2002 1
+OpenBSD 4.8 April 14, 2002 OpenBSD 4.8
diff --git a/ssh-rsa.c b/ssh-rsa.c
index 842857fee4fe..c471ff323bcf 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-rsa.c,v 1.40 2010/02/26 20:29:54 djm Exp $ */
+/* $OpenBSD: ssh-rsa.c,v 1.44 2010/07/16 14:07:35 djm Exp $ */
/*
* Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
*
@@ -30,6 +30,7 @@
#include "buffer.h"
#include "key.h"
#include "compat.h"
+#include "misc.h"
#include "ssh.h"
static int openssh_RSA_verify(int, u_char *, u_int, u_char *, u_int, RSA *);
@@ -46,9 +47,8 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
int ok, nid;
Buffer b;
- if (key == NULL ||
- (key->type != KEY_RSA && key->type != KEY_RSA_CERT) ||
- key->rsa == NULL) {
+ if (key == NULL || key->rsa == NULL || (key->type != KEY_RSA &&
+ key->type != KEY_RSA_CERT && key->type != KEY_RSA_CERT_V00)) {
error("ssh_rsa_sign: no RSA key");
return -1;
}
@@ -115,9 +115,8 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
u_int len, dlen, modlen;
int rlen, ret, nid;
- if (key == NULL ||
- (key->type != KEY_RSA && key->type != KEY_RSA_CERT) ||
- key->rsa == NULL) {
+ if (key == NULL || key->rsa == NULL || (key->type != KEY_RSA &&
+ key->type != KEY_RSA_CERT && key->type != KEY_RSA_CERT_V00)) {
error("ssh_rsa_verify: no RSA key");
return -1;
}
@@ -212,7 +211,7 @@ openssh_RSA_verify(int type, u_char *hash, u_int hashlen,
u_char *sigbuf, u_int siglen, RSA *rsa)
{
u_int ret, rsasize, oidlen = 0, hlen = 0;
- int len;
+ int len, oidmatch, hashmatch;
const u_char *oid = NULL;
u_char *decrypted = NULL;
@@ -251,11 +250,13 @@ openssh_RSA_verify(int type, u_char *hash, u_int hashlen,
error("bad decrypted len: %d != %d + %d", len, hlen, oidlen);
goto done;
}
- if (memcmp(decrypted, oid, oidlen) != 0) {
+ oidmatch = timingsafe_bcmp(decrypted, oid, oidlen) == 0;
+ hashmatch = timingsafe_bcmp(decrypted + oidlen, hash, hlen) == 0;
+ if (!oidmatch) {
error("oid mismatch");
goto done;
}
- if (memcmp(decrypted + oidlen, hash, hlen) != 0) {
+ if (!hashmatch) {
error("hash mismatch");
goto done;
}
diff --git a/ssh.0 b/ssh.0
index 9c793b8438d1..8d53ad2893ac 100644
--- a/ssh.0
+++ b/ssh.0
@@ -14,14 +14,14 @@ SYNOPSIS
DESCRIPTION
ssh (SSH client) is a program for logging into a remote machine and for
executing commands on a remote machine. It is intended to replace rlogin
- and rsh, and provide secure encrypted communications between two untrust-
- ed hosts over an insecure network. X11 connections and arbitrary TCP
- ports can also be forwarded over the secure channel.
+ and rsh, and provide secure encrypted communications between two
+ untrusted hosts over an insecure network. X11 connections and arbitrary
+ TCP ports can also be forwarded over the secure channel.
ssh connects and logs into the specified hostname (with optional user
name). The user must prove his/her identity to the remote machine using
- one of several methods depending on the protocol version used (see be-
- low).
+ one of several methods depending on the protocol version used (see
+ below).
If command is specified, it is executed on the remote host instead of a
login shell.
@@ -52,8 +52,8 @@ DESCRIPTION
-b bind_address
Use bind_address on the local machine as the source address of
- the connection. Only useful on systems with more than one ad-
- dress.
+ the connection. Only useful on systems with more than one
+ address.
-C Requests compression of all data (including stdin, stdout,
stderr, and data for forwarded X11 and TCP connections). The
@@ -69,17 +69,17 @@ DESCRIPTION
Protocol version 1 allows specification of a single cipher. The
supported values are ``3des'', ``blowfish'', and ``des''. 3des
- (triple-des) is an encrypt-decrypt-encrypt triple with three dif-
- ferent keys. It is believed to be secure. blowfish is a fast
+ (triple-des) is an encrypt-decrypt-encrypt triple with three
+ different keys. It is believed to be secure. blowfish is a fast
block cipher; it appears very secure and is much faster than
- 3des. des is only supported in the ssh client for interoperabil-
- ity with legacy protocol 1 implementations that do not support
- the 3des cipher. Its use is strongly discouraged due to crypto-
- graphic weaknesses. The default is ``3des''.
+ 3des. des is only supported in the ssh client for
+ interoperability with legacy protocol 1 implementations that do
+ not support the 3des cipher. Its use is strongly discouraged due
+ to cryptographic weaknesses. The default is ``3des''.
For protocol version 2, cipher_spec is a comma-separated list of
ciphers listed in order of preference. See the Ciphers keyword
- for more information.
+ in ssh_config(5) for more information.
-D [bind_address:]port
Specifies a local ``dynamic'' application-level port forwarding.
@@ -89,19 +89,18 @@ DESCRIPTION
the secure channel, and the application protocol is then used to
determine where to connect to from the remote machine. Currently
the SOCKS4 and SOCKS5 protocols are supported, and ssh will act
- as a SOCKS server. Only root can forward privileged ports. Dy-
- namic port forwardings can also be specified in the configuration
- file.
-
- IPv6 addresses can be specified with an alternative syntax:
- [bind_address/]port or by enclosing the address in square brack-
- ets. Only the superuser can forward privileged ports. By de-
- fault, the local port is bound in accordance with the
- GatewayPorts setting. However, an explicit bind_address may be
- used to bind the connection to a specific address. The
+ as a SOCKS server. Only root can forward privileged ports.
+ Dynamic port forwardings can also be specified in the
+ configuration file.
+
+ IPv6 addresses can be specified by enclosing the address in
+ square brackets. Only the superuser can forward privileged
+ ports. By default, the local port is bound in accordance with
+ the GatewayPorts setting. However, an explicit bind_address may
+ be used to bind the connection to a specific address. The
bind_address of ``localhost'' indicates that the listening port
- be bound for local use only, while an empty address or `*' indi-
- cates that the port should be available from all interfaces.
+ be bound for local use only, while an empty address or `*'
+ indicates that the port should be available from all interfaces.
-e escape_char
Sets the escape character for sessions with a pty (default: `~').
@@ -113,21 +112,21 @@ DESCRIPTION
fully transparent.
-F configfile
- Specifies an alternative per-user configuration file. If a con-
- figuration file is given on the command line, the system-wide
+ Specifies an alternative per-user configuration file. If a
+ configuration file is given on the command line, the system-wide
configuration file (/etc/ssh/ssh_config) will be ignored. The
default for the per-user configuration file is ~/.ssh/config.
-f Requests ssh to go to background just before command execution.
- This is useful if ssh is going to ask for passwords or passphras-
- es, but the user wants it in the background. This implies -n.
- The recommended way to start X11 programs at a remote site is
- with something like ssh -f host xterm.
+ This is useful if ssh is going to ask for passwords or
+ passphrases, but the user wants it in the background. This
+ implies -n. The recommended way to start X11 programs at a
+ remote site is with something like ssh -f host xterm.
If the ExitOnForwardFailure configuration option is set to
``yes'', then a client started with -f will wait for all remote
- port forwards to be successfully established before placing it-
- self in the background.
+ port forwards to be successfully established before placing
+ itself in the background.
-g Allows remote hosts to connect to local forwarded ports.
@@ -138,13 +137,13 @@ DESCRIPTION
-i identity_file
Selects a file from which the identity (private key) for RSA or
DSA authentication is read. The default is ~/.ssh/identity for
- protocol version 1, and ~/.ssh/id_rsa and ~/.ssh/id_dsa for pro-
- tocol version 2. Identity files may also be specified on a per-
- host basis in the configuration file. It is possible to have
- multiple -i options (and multiple identities specified in config-
- uration files). ssh will also try to load certificate informa-
- tion from the filename obtained by appending -cert.pub to identi-
- ty filenames.
+ protocol version 1, and ~/.ssh/id_rsa and ~/.ssh/id_dsa for
+ protocol version 2. Identity files may also be specified on a
+ per-host basis in the configuration file. It is possible to have
+ multiple -i options (and multiple identities specified in
+ configuration files). ssh will also try to load certificate
+ information from the filename obtained by appending -cert.pub to
+ identity filenames.
-K Enables GSSAPI-based authentication and forwarding (delegation)
of GSSAPI credentials to the server.
@@ -156,60 +155,62 @@ DESCRIPTION
Specifies that the given port on the local (client) host is to be
forwarded to the given host and port on the remote side. This
works by allocating a socket to listen to port on the local side,
- optionally bound to the specified bind_address. Whenever a con-
- nection is made to this port, the connection is forwarded over
+ optionally bound to the specified bind_address. Whenever a
+ connection is made to this port, the connection is forwarded over
the secure channel, and a connection is made to host port
hostport from the remote machine. Port forwardings can also be
- specified in the configuration file. IPv6 addresses can be spec-
- ified with an alternative syntax: [bind_address/]port/host/host-
- port or by enclosing the address in square brackets. Only the
+ specified in the configuration file. IPv6 addresses can be
+ specified by enclosing the address in square brackets. Only the
superuser can forward privileged ports. By default, the local
- port is bound in accordance with the GatewayPorts setting. How-
- ever, an explicit bind_address may be used to bind the connection
- to a specific address. The bind_address of ``localhost'' indi-
- cates that the listening port be bound for local use only, while
- an empty address or `*' indicates that the port should be avail-
- able from all interfaces.
+ port is bound in accordance with the GatewayPorts setting.
+ However, an explicit bind_address may be used to bind the
+ connection to a specific address. The bind_address of
+ ``localhost'' indicates that the listening port be bound for
+ local use only, while an empty address or `*' indicates that the
+ port should be available from all interfaces.
-l login_name
Specifies the user to log in as on the remote machine. This also
may be specified on a per-host basis in the configuration file.
- -M Places the ssh client into ``master'' mode for connection shar-
- ing. Multiple -M options places ssh into ``master'' mode with
- confirmation required before slave connections are accepted. Re-
- fer to the description of ControlMaster in ssh_config(5) for de-
- tails.
+ -M Places the ssh client into ``master'' mode for connection
+ sharing. Multiple -M options places ssh into ``master'' mode
+ with confirmation required before slave connections are accepted.
+ Refer to the description of ControlMaster in ssh_config(5) for
+ details.
-m mac_spec
Additionally, for protocol version 2 a comma-separated list of
MAC (message authentication code) algorithms can be specified in
order of preference. See the MACs keyword for more information.
- -N Do not execute a remote command. This is useful for just for-
- warding ports (protocol version 2 only).
+ -N Do not execute a remote command. This is useful for just
+ forwarding ports (protocol version 2 only).
-n Redirects stdin from /dev/null (actually, prevents reading from
stdin). This must be used when ssh is run in the background. A
- common trick is to use this to run X11 programs on a remote ma-
- chine. For example, ssh -n shadows.cs.hut.fi emacs & will start
- an emacs on shadows.cs.hut.fi, and the X11 connection will be au-
- tomatically forwarded over an encrypted channel. The ssh program
- will be put in the background. (This does not work if ssh needs
- to ask for a password or passphrase; see also the -f option.)
+ common trick is to use this to run X11 programs on a remote
+ machine. For example, ssh -n shadows.cs.hut.fi emacs & will
+ start an emacs on shadows.cs.hut.fi, and the X11 connection will
+ be automatically forwarded over an encrypted channel. The ssh
+ program will be put in the background. (This does not work if
+ ssh needs to ask for a password or passphrase; see also the -f
+ option.)
-O ctl_cmd
Control an active connection multiplexing master process. When
the -O option is specified, the ctl_cmd argument is interpreted
and passed to the master process. Valid commands are: ``check''
- (check that the master process is running) and ``exit'' (request
- the master to exit).
+ (check that the master process is running), ``forward'' (request
+ forwardings without command execution) and ``exit'' (request the
+ master to exit).
-o option
- Can be used to give options in the format used in the configura-
- tion file. This is useful for specifying options for which there
- is no separate command-line flag. For full details of the op-
- tions listed below, and their possible values, see ssh_config(5).
+ 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 command-line flag. For full details
+ of the options listed below, and their possible values, see
+ ssh_config(5).
AddressFamily
BatchMode
@@ -287,61 +288,64 @@ DESCRIPTION
Specifies that the given port on the remote (server) host is to
be forwarded to the given host and port on the local side. This
works by allocating a socket to listen to port on the remote
- side, and whenever a connection is made to this port, the connec-
- tion is forwarded over the secure channel, and a connection is
- made to host port hostport from the local machine.
+ side, and whenever a connection is made to this port, the
+ connection is forwarded over the secure channel, and a connection
+ is made to host port hostport from the local machine.
Port forwardings can also be specified in the configuration file.
Privileged ports can be forwarded only when logging in as root on
the remote machine. IPv6 addresses can be specified by enclosing
- the address in square braces or using an alternative syntax:
- [bind_address/]host/port/hostport.
+ the address in square braces.
By default, the listening socket on the server will be bound to
- the loopback interface only. This may be overridden by specify-
- ing a bind_address. An empty bind_address, or the address `*',
- indicates that the remote socket should listen on all interfaces.
- Specifying a remote bind_address will only succeed if the serv-
- er's GatewayPorts option is enabled (see sshd_config(5)).
+ the loopback interface only. This may be overridden by
+ specifying a bind_address. An empty bind_address, or the address
+ `*', indicates that the remote socket should listen on all
+ interfaces. Specifying a remote bind_address will only succeed
+ if the server's GatewayPorts option is enabled (see
+ sshd_config(5)).
If the port argument is `0', the listen port will be dynamically
allocated on the server and reported to the client at run time.
+ When used together with -O forward the allocated port will be
+ printed to the standard output.
-S ctl_path
- Specifies the location of a control socket for connection sharing
- or the string ``none'' to disable connection sharing. Refer to
- the description of ControlPath and ControlMaster in ssh_config(5)
- for details.
+ Specifies the location of a control socket for connection
+ sharing, or the string ``none'' to disable connection sharing.
+ Refer to the description of ControlPath and ControlMaster in
+ ssh_config(5) for details.
-s May be used to request invocation of a subsystem on the remote
- system. Subsystems are a feature of the SSH2 protocol which fa-
- cilitate the use of SSH as a secure transport for other applica-
- tions (eg. sftp(1)). The subsystem is specified as the remote
- command.
+ system. Subsystems are a feature of the SSH2 protocol which
+ facilitate the use of SSH as a secure transport for other
+ applications (eg. sftp(1)). The subsystem is specified as the
+ remote command.
-T Disable pseudo-tty allocation.
- -t Force pseudo-tty allocation. This can be used to execute arbi-
- trary screen-based programs on a remote machine, which can be
+ -t Force pseudo-tty allocation. This can be used to execute
+ arbitrary screen-based programs on a remote machine, which can be
very useful, e.g. when implementing menu services. Multiple -t
options force tty allocation, even if ssh has no local tty.
-V Display the version number and exit.
-v Verbose mode. Causes ssh to print debugging messages about its
- progress. This is helpful in debugging connection, authentica-
- tion, and configuration problems. Multiple -v options increase
- the verbosity. The maximum is 3.
+ progress. This is helpful in debugging connection,
+ authentication, and configuration problems. Multiple -v options
+ increase the verbosity. The maximum is 3.
-W host:port
- Requests that standard input and output on the client be forward-
- ed to host on port over the secure channel. Implies -N, -T,
- ExitOnForwardFailure and ClearAllForwardings and works with Pro-
- tocol version 2 only.
+ Requests that standard input and output on the client be
+ forwarded to host on port over the secure channel. Implies -N,
+ -T, ExitOnForwardFailure and ClearAllForwardings and works with
+ Protocol version 2 only.
-w local_tun[:remote_tun]
- Requests tunnel device forwarding with the specified tun(4) de-
- vices between the client (local_tun) and the server (remote_tun).
+ Requests tunnel device forwarding with the specified tun(4)
+ devices between the client (local_tun) and the server
+ (remote_tun).
The devices may be specified by numerical ID or the keyword
``any'', which uses the next available tunnel device. If
@@ -359,9 +363,9 @@ DESCRIPTION
through the forwarded connection. An attacker may then be able
to perform activities such as keystroke monitoring.
- For this reason, X11 forwarding is subjected to X11 SECURITY ex-
- tension restrictions by default. Please refer to the ssh -Y op-
- tion and the ForwardX11Trusted directive in ssh_config(5) for
+ For this reason, X11 forwarding is subjected to X11 SECURITY
+ extension restrictions by default. Please refer to the ssh -Y
+ option and the ForwardX11Trusted directive in ssh_config(5) for
more information.
-x Disables X11 forwarding.
@@ -369,12 +373,12 @@ DESCRIPTION
-Y Enables trusted X11 forwarding. Trusted X11 forwardings are not
subjected to the X11 SECURITY extension controls.
- -y Send log information using the syslog(3) system module. By de-
- fault this information is sent to stderr.
+ -y Send log information using the syslog(3) system module. By
+ default this information is sent to stderr.
- ssh may additionally obtain configuration data from a per-user configura-
- tion file and a system-wide configuration file. The file format and con-
- figuration options are described in ssh_config(5).
+ ssh may additionally obtain configuration data from a per-user
+ configuration file and a system-wide configuration file. The file format
+ and configuration options are described in ssh_config(5).
ssh exits with the exit status of the remote command or with 255 if an
error occurred.
@@ -385,15 +389,16 @@ AUTHENTICATION
in ssh_config(5) or the -1 and -2 options (see above). 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 integri-
- ty (hmac-md5, hmac-sha1, umac-64, hmac-ripemd160). Protocol 1 lacks a
- strong mechanism for ensuring the integrity of the connection.
+ is encrypted using AES, 3DES, Blowfish, CAST128, or Arcfour) and
+ integrity (hmac-md5, hmac-sha1, umac-64, hmac-ripemd160). Protocol 1
+ lacks a strong mechanism for ensuring the integrity of the connection.
- The methods available for authentication are: GSSAPI-based authentica-
- tion, host-based authentication, public key authentication, challenge-re-
- sponse authentication, and password authentication. Authentication meth-
- ods are tried in the order specified above, though protocol 2 has a con-
- figuration option to change the default order: PreferredAuthentications.
+ The methods available for authentication are: GSSAPI-based
+ authentication, host-based authentication, public key authentication,
+ challenge-response authentication, and password authentication.
+ Authentication methods are tried in the order specified above, though
+ protocol 2 has a configuration option to change the default order:
+ PreferredAuthentications.
Host-based authentication works as follows: If the machine the user logs
in from is listed in /etc/hosts.equiv or /etc/shosts.equiv on the remote
@@ -403,22 +408,22 @@ AUTHENTICATION
the name of the user on that machine, the user is considered for login.
Additionally, the server must be able to verify the client's host key
(see the description of /etc/ssh/ssh_known_hosts and ~/.ssh/known_hosts,
- below) for login to be permitted. This authentication method closes se-
- curity holes due to IP spoofing, DNS spoofing, and routing spoofing.
+ below) for login to be permitted. This authentication method closes
+ security holes due to IP spoofing, DNS spoofing, and routing spoofing.
[Note to the administrator: /etc/hosts.equiv, ~/.rhosts, and the
rlogin/rsh protocol in general, are inherently insecure and should be
disabled if security is desired.]
- Public key authentication works as follows: The scheme is based on pub-
- lic-key cryptography, using cryptosystems where encryption and decryption
- are done using separate keys, and it is unfeasible to derive the decryp-
- tion key from the encryption key. The idea is that each user creates a
- public/private key pair for authentication purposes. The server knows
- the public key, and only the user knows the private key. ssh implements
- public key authentication protocol automatically, using either the RSA or
- DSA algorithms. Protocol 1 is restricted to using only RSA keys, but
- protocol 2 may use either. The HISTORY section of ssl(8) contains a
- brief discussion of the two algorithms.
+ Public key authentication works as follows: The scheme is based on
+ public-key cryptography, using cryptosystems where encryption and
+ decryption are done using separate keys, and it is unfeasible to derive
+ the decryption key from the encryption key. The idea is that each user
+ creates a public/private key pair for authentication purposes. The
+ server knows the public key, and only the user knows the private key.
+ ssh implements public key authentication protocol automatically, using
+ either the RSA or DSA algorithms. Protocol 1 is restricted to using only
+ RSA keys, but protocol 2 may use either. The HISTORY section of ssl(8)
+ contains a brief discussion of the two algorithms.
The file ~/.ssh/authorized_keys lists the public keys that are permitted
for logging in. When the user logs in, the ssh program tells the server
@@ -430,48 +435,49 @@ AUTHENTICATION
the private key in ~/.ssh/identity (protocol 1), ~/.ssh/id_dsa (protocol
2 DSA), or ~/.ssh/id_rsa (protocol 2 RSA) and stores the public key in
~/.ssh/identity.pub (protocol 1), ~/.ssh/id_dsa.pub (protocol 2 DSA), or
- ~/.ssh/id_rsa.pub (protocol 2 RSA) in the user's home directory. The us-
- er should then copy the public key to ~/.ssh/authorized_keys in his/her
- home directory on the remote machine. The authorized_keys file corre-
- sponds to the conventional ~/.rhosts file, and has one key per line,
- though the lines can be very long. After this, the user can log in with-
- out giving the password.
-
- A variation on public key authentication is available in the form of cer-
- tificate authentication: instead of a set of public/private keys, signed
- certificates are used. This has the advantage that a single trusted cer-
- tification authority can be used in place of many public/private keys.
- See the CERTIFICATES section of ssh-keygen(1) for more information.
+ ~/.ssh/id_rsa.pub (protocol 2 RSA) in the user's home directory. The
+ user should then copy the public key to ~/.ssh/authorized_keys in his/her
+ home directory on the remote machine. The authorized_keys file
+ corresponds to the conventional ~/.rhosts file, and has one key per line,
+ though the lines can be very long. After this, the user can log in
+ without giving the password.
+
+ A variation on public key authentication is available in the form of
+ certificate authentication: instead of a set of public/private keys,
+ signed certificates are used. This has the advantage that a single
+ trusted certification authority can be used in place of many
+ public/private keys. See the CERTIFICATES section of ssh-keygen(1) for
+ more information.
The most convenient way to use public key or certificate authentication
- may be with an authentication agent. See ssh-agent(1) for more informa-
- tion.
+ may be with an authentication agent. See ssh-agent(1) for more
+ information.
Challenge-response authentication works as follows: The server sends an
- arbitrary "challenge" text, and prompts for a response. Protocol 2 al-
- lows multiple challenges and responses; protocol 1 is restricted to just
- one challenge/response. Examples of challenge-response authentication
- include BSD Authentication (see login.conf(5)) and PAM (some non-OpenBSD
- systems).
+ arbitrary "challenge" text, and prompts for a response. Protocol 2
+ allows multiple challenges and responses; protocol 1 is restricted to
+ just one challenge/response. Examples of challenge-response
+ authentication include BSD Authentication (see login.conf(5)) and PAM
+ (some non-OpenBSD systems).
Finally, if other authentication methods fail, ssh prompts the user for a
password. The password is sent to the remote host for checking; however,
since all communications are encrypted, the password cannot be seen by
someone listening on the network.
- ssh automatically maintains and checks a database containing identifica-
- tion for all hosts it has ever been used with. Host keys are stored in
- ~/.ssh/known_hosts in the user's home directory. Additionally, the file
- /etc/ssh/ssh_known_hosts is automatically checked for known hosts. Any
- new hosts are automatically added to the user's file. If a host's iden-
- tification ever changes, ssh warns about this and disables password au-
- thentication to prevent server spoofing or man-in-the-middle attacks,
- which could otherwise be used to circumvent the encryption. The
+ ssh automatically maintains and checks a database containing
+ identification for all hosts it has ever been used with. Host keys are
+ stored in ~/.ssh/known_hosts in the user's home directory. Additionally,
+ the file /etc/ssh/ssh_known_hosts is automatically checked for known
+ hosts. Any new hosts are automatically added to the user's file. If a
+ host's identification ever changes, ssh warns about this and disables
+ password authentication to prevent server spoofing or man-in-the-middle
+ attacks, which could otherwise be used to circumvent the encryption. The
StrictHostKeyChecking option can be used to control logins to machines
whose host key is not known or has changed.
- When the user's identity has been accepted by the server, the server ei-
- ther executes the given command, or logs into the machine and gives the
+ When the user's identity has been accepted by the server, the server
+ either executes the given command, or logs into the machine and gives the
user a normal shell on the remote machine. All communication with the
remote command or shell will be automatically encrypted.
@@ -487,14 +493,14 @@ AUTHENTICATION
exits and all X11 and TCP connections have been closed.
ESCAPE CHARACTERS
- When a pseudo-terminal has been requested, ssh supports a number of func-
- tions through the use of an escape character.
+ When a pseudo-terminal has been requested, ssh supports a number of
+ functions through the use of an escape character.
A single tilde character can be sent as ~~ or by following the tilde by a
character other than those described below. The escape character must
- always follow a newline to be interpreted as special. The escape charac-
- ter can be changed in configuration files using the EscapeChar configura-
- tion directive or on the command line by the -e option.
+ always follow a newline to be interpreted as special. The escape
+ character can be changed in configuration files using the EscapeChar
+ configuration directive or on the command line by the -e option.
The supported escapes (assuming the default `~') are:
@@ -531,8 +537,8 @@ TCP FORWARDING
In the example below, we look at encrypting communication between an IRC
client and server, even though the IRC server does not directly support
encrypted communications. This works as follows: the user connects to
- the remote host using ssh, specifying a port to be used to forward con-
- nections to the remote server. After that it is possible to start the
+ the remote host using ssh, specifying a port to be used to forward
+ connections to the remote server. After that it is possible to start the
service which is to be encrypted on the client machine, connecting to the
same local port, and ssh will encrypt and forward the connection.
@@ -543,11 +549,11 @@ TCP FORWARDING
$ irc -c '#users' -p 1234 pinky 127.0.0.1
This tunnels a connection to IRC server ``server.example.com'', joining
- channel ``#users'', nickname ``pinky'', using port 1234. It doesn't mat-
- ter which port is used, as long as it's greater than 1023 (remember, only
- root can open sockets on privileged ports) and doesn't conflict with any
- ports already in use. The connection is forwarded to port 6667 on the
- remote server, since that's the standard port for IRC services.
+ channel ``#users'', nickname ``pinky'', using port 1234. It doesn't
+ matter which port is used, as long as it's greater than 1023 (remember,
+ only root can open sockets on privileged ports) and doesn't conflict with
+ any ports already in use. The connection is forwarded to port 6667 on
+ the remote server, since that's the standard port for IRC services.
The -f option backgrounds ssh and the remote command ``sleep 10'' is
specified to allow an amount of time (10 seconds, in the example) to
@@ -557,13 +563,13 @@ TCP FORWARDING
X11 FORWARDING
If the ForwardX11 variable is set to ``yes'' (or see the description of
the -X, -x, and -Y options above) and the user is using X11 (the DISPLAY
- environment variable is set), the connection to the X11 display is auto-
- matically forwarded to the remote side in such a way that any X11 pro-
- grams started from the shell (or command) will go through the encrypted
- channel, and the connection to the real X server will be made from the
- local machine. The user should not manually set DISPLAY. Forwarding of
- X11 connections can be configured on the command line or in configuration
- files.
+ environment variable is set), the connection to the X11 display is
+ automatically forwarded to the remote side in such a way that any X11
+ programs started from the shell (or command) will go through the
+ encrypted channel, and the connection to the real X server will be made
+ from the local machine. The user should not manually set DISPLAY.
+ Forwarding of X11 connections can be configured on the command line or in
+ configuration files.
The DISPLAY value set by ssh will point to the server machine, but with a
display number greater than zero. This is normal, and happens because
@@ -579,8 +585,8 @@ X11 FORWARDING
If the ForwardAgent variable is set to ``yes'' (or see the description of
the -A and -a options above) and the user is using an authentication
- agent, the connection to the agent is automatically forwarded to the re-
- mote side.
+ agent, the connection to the agent is automatically forwarded to the
+ remote side.
VERIFYING HOST KEYS
When connecting to a server for the first time, a fingerprint of the
@@ -597,8 +603,8 @@ VERIFYING HOST KEYS
``yes'', a small ASCII graphic gets displayed on every login to a server,
no matter if the session itself is interactive or not. By learning the
pattern a known server produces, a user can easily find out that the host
- key has changed when a completely different pattern is displayed. Be-
- cause these patterns are not unambiguous however, a pattern that looks
+ key has changed when a completely different pattern is displayed.
+ Because these patterns are not unambiguous however, a pattern that looks
similar to the pattern remembered only gives a good probability that the
host key is the same, not guaranteed proof.
@@ -634,15 +640,15 @@ VERIFYING HOST KEYS
SSH-BASED VIRTUAL PRIVATE NETWORKS
ssh contains support for Virtual Private Network (VPN) tunnelling using
- the tun(4) network pseudo-device, allowing two networks to be joined se-
- curely. The sshd_config(5) configuration option PermitTunnel controls
- whether the server supports this, and at what level (layer 2 or 3 traf-
- fic).
+ the tun(4) network pseudo-device, allowing two networks to be joined
+ securely. The sshd_config(5) configuration option PermitTunnel controls
+ whether the server supports this, and at what level (layer 2 or 3
+ traffic).
- The following example would connect client network 10.0.50.0/24 with re-
- mote network 10.0.99.0/24 using a point-to-point connection from 10.1.1.1
- to 10.1.1.2, provided that the SSH server running on the gateway to the
- remote network, at 192.168.1.15, allows it.
+ The following example would connect client network 10.0.50.0/24 with
+ remote network 10.0.99.0/24 using a point-to-point connection from
+ 10.1.1.1 to 10.1.1.2, provided that the SSH server running on the gateway
+ to the remote network, at 192.168.1.15, allows it.
On the client:
@@ -665,8 +671,8 @@ SSH-BASED VIRTUAL PRIVATE NETWORKS
tunnel="2",command="sh /etc/netstart tun2" ssh-rsa ... john
Since an SSH-based setup entails a fair amount of overhead, it may be
- more suited to temporary setups, such as for wireless VPNs. More perma-
- nent VPNs are better provided by tools such as ipsecctl(8) and
+ more suited to temporary setups, such as for wireless VPNs. More
+ permanent VPNs are better provided by tools such as ipsecctl(8) and
isakmpd(8).
ENVIRONMENT
@@ -685,13 +691,13 @@ ENVIRONMENT
HOME Set to the path of the user's home directory.
- LOGNAME Synonym for USER; set for compatibility with sys-
- tems that use this variable.
+ LOGNAME Synonym for USER; set for compatibility with
+ systems that use this variable.
MAIL Set to the path of the user's mailbox.
- PATH Set to the default PATH, as specified when compil-
- ing ssh.
+ PATH Set to the default PATH, as specified when
+ compiling ssh.
SSH_ASKPASS If ssh needs a passphrase, it will read the
passphrase from the current terminal if it was run
@@ -699,49 +705,50 @@ ENVIRONMENT
associated with it but DISPLAY and SSH_ASKPASS are
set, it will execute the program specified by
SSH_ASKPASS and open an X11 window to read the
- passphrase. This is particularly useful when call-
- ing ssh from a .xsession or related script. (Note
- that on some machines it may be necessary to redi-
- rect the input from /dev/null to make this work.)
+ passphrase. This is particularly useful when
+ calling ssh from a .xsession or related script.
+ (Note that on some machines it may be necessary to
+ redirect the input from /dev/null to make this
+ work.)
SSH_AUTH_SOCK Identifies the path of a UNIX-domain socket used to
communicate with the agent.
- SSH_CONNECTION Identifies the client and server ends of the con-
- nection. The variable contains four space-separat-
- ed values: client IP address, client port number,
- server IP address, and server port number.
+ SSH_CONNECTION Identifies the client and server ends of the
+ connection. The variable contains four space-
+ separated values: client IP address, client port
+ number, server IP address, and server port number.
SSH_ORIGINAL_COMMAND This variable contains the original command line if
a forced command is executed. It can be used to
extract the original arguments.
- SSH_TTY This is set to the name of the tty (path to the de-
- vice) associated with the current shell or command.
- If the current session has no tty, this variable is
- not set.
+ SSH_TTY This is set to the name of the tty (path to the
+ device) associated with the current shell or
+ command. If the current session has no tty, this
+ variable is not set.
TZ This variable is set to indicate the present time
zone if it was set when the daemon was started
- (i.e. the daemon passes the value on to new connec-
- tions).
+ (i.e. the daemon passes the value on to new
+ connections).
USER Set to the name of the user logging in.
Additionally, ssh reads ~/.ssh/environment, and adds lines of the format
- ``VARNAME=value'' to the environment if the file exists and users are al-
- lowed to change their environment. For more information, see the
+ ``VARNAME=value'' to the environment if the file exists and users are
+ allowed to change their environment. For more information, see the
PermitUserEnvironment option in sshd_config(5).
FILES
~/.rhosts
This file is used for host-based authentication (see above). On
- some machines this file may need to be world-readable if the us-
- er's home directory is on an NFS partition, because sshd(8) reads
- it as root. Additionally, this file must be owned by the user,
- and must not have write permissions for anyone else. The recom-
- mended permission for most machines is read/write for the user,
- and not accessible by others.
+ some machines this file may need to be world-readable if the
+ user's home directory is on an NFS partition, because sshd(8)
+ reads it as root. Additionally, this file must be owned by the
+ user, and must not have write permissions for anyone else. The
+ recommended permission for most machines is read/write for the
+ user, and not accessible by others.
~/.shosts
This file is used in exactly the same way as .rhosts, but allows
@@ -749,18 +756,18 @@ FILES
rlogin/rsh.
~/.ssh/
- This directory is the default location for all user-specific con-
- figuration and authentication information. There is no general
- requirement to keep the entire contents of this directory secret,
- but the recommended permissions are read/write/execute for the
- user, and not accessible by others.
+ This directory is the default location for all user-specific
+ configuration and authentication information. There is no
+ general requirement to keep the entire contents of this directory
+ secret, but the recommended permissions are read/write/execute
+ for the user, and not accessible by others.
~/.ssh/authorized_keys
Lists the public keys (RSA/DSA) that can be used for logging in
as this user. The format of this file is described in the
sshd(8) manual page. This file is not highly sensitive, but the
- recommended permissions are read/write for the user, and not ac-
- cessible by others.
+ recommended permissions are read/write for the user, and not
+ accessible by others.
~/.ssh/config
This is the per-user configuration file. The file format and
@@ -776,11 +783,12 @@ FILES
~/.ssh/id_dsa
~/.ssh/id_rsa
Contains the private key for authentication. These files contain
- sensitive data and should be readable by the user but not acces-
- sible by others (read/write/execute). ssh will simply ignore a
- private key file if it is accessible by others. It is possible
- to specify a passphrase when generating the key which will be
- used to encrypt the sensitive part of this file using 3DES.
+ sensitive data and should be readable by the user but not
+ accessible by others (read/write/execute). ssh will simply
+ ignore a private key file if it is accessible by others. It is
+ possible to specify a passphrase when generating the key which
+ will be used to encrypt the sensitive part of this file using
+ 3DES.
~/.ssh/identity.pub
~/.ssh/id_dsa.pub
@@ -804,8 +812,8 @@ FILES
should only be writable by root.
/etc/shosts.equiv
- This file is used in exactly the same way as hosts.equiv, but al-
- lows host-based authentication without permitting login with
+ This file is used in exactly the same way as hosts.equiv, but
+ allows host-based authentication without permitting login with
rlogin/rsh.
/etc/ssh/ssh_config
@@ -817,11 +825,11 @@ FILES
/etc/ssh/ssh_host_rsa_key
These three files contain the private parts of the host keys and
are used for host-based authentication. If protocol version 1 is
- used, ssh must be setuid root, since the host key is readable on-
- ly by root. For protocol version 2, ssh uses ssh-keysign(8) to
- access the host keys, eliminating the requirement that ssh be se-
- tuid root when host-based authentication is used. By default ssh
- is not setuid root.
+ used, ssh must be setuid root, since the host key is readable
+ only by root. For protocol version 2, ssh uses ssh-keysign(8) to
+ access the host keys, eliminating the requirement that ssh be
+ setuid root when host-based authentication is used. By default
+ ssh is not setuid root.
/etc/ssh/ssh_known_hosts
Systemwide list of known host keys. This file should be prepared
@@ -866,7 +874,7 @@ SEE ALSO
The Secure Shell (SSH) Public Key File Format, RFC 4716, 2006.
- A. Perrig and D. Song, Hash Visualization: a New Technique to improve
+ A. Perrig, D. Song, Hash Visualization: a New Technique to improve
Real-World Security, 1999, International Workshop on Cryptographic
Techniques and E-Commerce (CrypTEC '99).
@@ -877,4 +885,4 @@ AUTHORS
created OpenSSH. Markus Friedl contributed the support for SSH protocol
versions 1.5 and 2.0.
-OpenBSD 4.7 March 26, 2010 14
+OpenBSD 4.8 August 4, 2010 OpenBSD 4.8
diff --git a/ssh.1 b/ssh.1
index c03771a3eba3..02d28a00b935 100644
--- a/ssh.1
+++ b/ssh.1
@@ -34,8 +34,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: ssh.1,v 1.303 2010/03/26 00:26:58 djm Exp $
-.Dd $Mdocdate: March 26 2010 $
+.\" $OpenBSD: ssh.1,v 1.308 2010/08/04 05:37:01 djm Exp $
+.Dd $Mdocdate: August 4 2010 $
.Dt SSH 1
.Os
.Sh NAME
@@ -43,46 +43,28 @@
.Nd OpenSSH SSH client (remote login program)
.Sh SYNOPSIS
.Nm ssh
+.Bk -words
.Op Fl 1246AaCfgKkMNnqsTtVvXxYy
.Op Fl b Ar bind_address
.Op Fl c Ar cipher_spec
-.Oo Fl D\ \&
-.Sm off
-.Oo Ar bind_address : Oc
-.Ar port
-.Sm on
-.Oc
+.Op Fl D Oo Ar bind_address : Oc Ns Ar port
.Op Fl e Ar escape_char
.Op Fl F Ar configfile
.Op Fl I Ar pkcs11
-.Bk -words
.Op Fl i Ar identity_file
-.Ek
-.Oo Fl L\ \&
-.Sm off
-.Oo Ar bind_address : Oc
-.Ar port : host : hostport
-.Sm on
-.Oc
-.Bk -words
+.Op Fl L Oo Ar bind_address : Oc Ns Ar port : Ns Ar host : Ns Ar hostport
.Op Fl l Ar login_name
-.Ek
.Op Fl m Ar mac_spec
.Op Fl O Ar ctl_cmd
.Op Fl o Ar option
.Op Fl p Ar port
-.Oo Fl R\ \&
-.Sm off
-.Oo Ar bind_address : Oc
-.Ar port : host : hostport
-.Sm on
-.Oc
+.Op Fl R Oo Ar bind_address : Oc Ns Ar port : Ns Ar host : Ns Ar hostport
.Op Fl S Ar ctl_path
.Op Fl W Ar host : Ns Ar port
-.Oo Fl w Ar local_tun Ns
-.Op : Ns Ar remote_tun Oc
+.Op Fl w Ar local_tun Ns Op : Ns Ar remote_tun
.Oo Ar user Ns @ Oc Ns Ar hostname
.Op Ar command
+.Ek
.Sh DESCRIPTION
.Nm
(SSH client) is a program for logging into a remote machine and for
@@ -194,7 +176,9 @@ is a comma-separated list of ciphers
listed in order of preference.
See the
.Cm Ciphers
-keyword for more information.
+keyword in
+.Xr ssh_config 5
+for more information.
.It Fl D Xo
.Sm off
.Oo Ar bind_address : Oc
@@ -218,14 +202,7 @@ will act as a SOCKS server.
Only root can forward privileged ports.
Dynamic port forwardings can also be specified in the configuration file.
.Pp
-IPv6 addresses can be specified with an alternative syntax:
-.Sm off
-.Xo
-.Op Ar bind_address No /
-.Ar port
-.Xc
-.Sm on
-or by enclosing the address in square brackets.
+IPv6 addresses can be specified by enclosing the address in square brackets.
Only the superuser can forward privileged ports.
By default, the local port is bound in accordance with the
.Cm GatewayPorts
@@ -336,15 +313,7 @@ port
.Ar hostport
from the remote machine.
Port forwardings can also be specified in the configuration file.
-IPv6 addresses can be specified with an alternative syntax:
-.Sm off
-.Xo
-.Op Ar bind_address No /
-.Ar port No / Ar host No /
-.Ar hostport
-.Xc
-.Sm on
-or by enclosing the address in square brackets.
+IPv6 addresses can be specified by enclosing the address in square brackets.
Only the superuser can forward privileged ports.
By default, the local port is bound in accordance with the
.Cm GatewayPorts
@@ -421,7 +390,9 @@ option is specified, the
argument is interpreted and passed to the master process.
Valid commands are:
.Dq check
-(check that the master process is running) and
+(check that the master process is running),
+.Dq forward
+(request forwardings without command execution) and
.Dq exit
(request the master to exit).
.It Fl o Ar option
@@ -525,15 +496,7 @@ from the local machine.
Port forwardings can also be specified in the configuration file.
Privileged ports can be forwarded only when
logging in as root on the remote machine.
-IPv6 addresses can be specified by enclosing the address in square braces or
-using an alternative syntax:
-.Sm off
-.Xo
-.Op Ar bind_address No /
-.Ar host No / Ar port No /
-.Ar hostport
-.Xc .
-.Sm on
+IPv6 addresses can be specified by enclosing the address in square braces.
.Pp
By default, the listening socket on the server will be bound to the loopback
interface only.
@@ -557,8 +520,11 @@ argument is
.Ql 0 ,
the listen port will be dynamically allocated on the server and reported
to the client at run time.
+When used together with
+.Ic -O forward
+the allocated port will be printed to the standard output.
.It Fl S Ar ctl_path
-Specifies the location of a control socket for connection sharing
+Specifies the location of a control socket for connection sharing,
or the string
.Dq none
to disable connection sharing.
diff --git a/ssh.c b/ssh.c
index b9553d3e12e3..4419f7642e60 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.335 2010/02/26 20:29:54 djm Exp $ */
+/* $OpenBSD: ssh.c,v 1.346 2010/08/12 21:49:44 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -79,6 +79,7 @@
#include "ssh.h"
#include "ssh1.h"
#include "ssh2.h"
+#include "canohost.h"
#include "compat.h"
#include "cipher.h"
#include "packet.h"
@@ -127,6 +128,15 @@ int no_shell_flag = 0;
int stdin_null_flag = 0;
/*
+ * Flag indicating that the current process should be backgrounded and
+ * a new slave launched in the foreground for ControlPersist.
+ */
+int need_controlpersist_detach = 0;
+
+/* Copies of flags for ControlPersist foreground slave */
+int ostdin_null_flag, ono_shell_flag, ono_tty_flag, otty_flag;
+
+/*
* Flag indicating that ssh should fork after authentication. This is useful
* so that the passphrase can be entered manually, and then ssh goes to the
* background.
@@ -228,6 +238,12 @@ main(int ac, char **av)
init_rng();
/*
+ * Discard other fds that are hanging around. These can cause problem
+ * with backgrounded ssh processes started by ControlPersist.
+ */
+ closefrom(STDERR_FILENO + 1);
+
+ /*
* Save the original real uid. It will be needed later (uid-swapping
* may clobber the real uid).
*/
@@ -327,6 +343,8 @@ main(int ac, char **av)
fatal("Multiplexing command already specified");
if (strcmp(optarg, "check") == 0)
muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK;
+ else if (strcmp(optarg, "forward") == 0)
+ muxclient_command = SSHMUX_COMMAND_FORWARD;
else if (strcmp(optarg, "exit") == 0)
muxclient_command = SSHMUX_COMMAND_TERMINATE;
else
@@ -620,7 +638,7 @@ main(int ac, char **av)
tty_flag = 1;
/* Force no tty */
- if (no_tty_flag)
+ if (no_tty_flag || 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) {
@@ -676,6 +694,11 @@ main(int ac, char **av)
options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
}
+ if (options.hostname != NULL) {
+ host = percent_expand(options.hostname,
+ "h", host, (char *)NULL);
+ }
+
if (options.local_command != NULL) {
char thishost[NI_MAXHOST];
@@ -685,16 +708,12 @@ main(int ac, char **av)
debug3("expanding LocalCommand: %s", options.local_command);
cp = options.local_command;
options.local_command = percent_expand(cp, "d", pw->pw_dir,
- "h", options.hostname? options.hostname : host,
- "l", thishost, "n", host, "r", options.user, "p", buf,
- "u", pw->pw_name, (char *)NULL);
+ "h", host, "l", thishost, "n", host, "r", options.user,
+ "p", buf, "u", pw->pw_name, (char *)NULL);
debug3("expanded LocalCommand: %s", options.local_command);
xfree(cp);
}
- if (options.hostname != NULL)
- host = options.hostname;
-
/* force lowercase for hostkey matching */
if (options.host_key_alias != NULL) {
for (p = options.host_key_alias; *p; p++)
@@ -761,26 +780,34 @@ main(int ac, char **av)
sensitive_data.external_keysign = 0;
if (options.rhosts_rsa_authentication ||
options.hostbased_authentication) {
- sensitive_data.nkeys = 3;
+ sensitive_data.nkeys = 5;
sensitive_data.keys = xcalloc(sensitive_data.nkeys,
sizeof(Key));
PRIV_START;
sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
_PATH_HOST_KEY_FILE, "", NULL, NULL);
- sensitive_data.keys[1] = key_load_private_type(KEY_DSA,
+ sensitive_data.keys[1] = key_load_private_cert(KEY_DSA,
+ _PATH_HOST_DSA_KEY_FILE, "", NULL);
+ sensitive_data.keys[2] = key_load_private_cert(KEY_RSA,
+ _PATH_HOST_RSA_KEY_FILE, "", NULL);
+ sensitive_data.keys[3] = key_load_private_type(KEY_DSA,
_PATH_HOST_DSA_KEY_FILE, "", NULL, NULL);
- sensitive_data.keys[2] = key_load_private_type(KEY_RSA,
+ sensitive_data.keys[4] = key_load_private_type(KEY_RSA,
_PATH_HOST_RSA_KEY_FILE, "", NULL, NULL);
PRIV_END;
if (options.hostbased_authentication == 1 &&
sensitive_data.keys[0] == NULL &&
- sensitive_data.keys[1] == NULL &&
- sensitive_data.keys[2] == NULL) {
- sensitive_data.keys[1] = key_load_public(
+ sensitive_data.keys[3] == NULL &&
+ sensitive_data.keys[4] == NULL) {
+ sensitive_data.keys[1] = key_load_cert(
+ _PATH_HOST_DSA_KEY_FILE);
+ sensitive_data.keys[2] = key_load_cert(
+ _PATH_HOST_RSA_KEY_FILE);
+ sensitive_data.keys[3] = key_load_public(
_PATH_HOST_DSA_KEY_FILE, NULL);
- sensitive_data.keys[2] = key_load_public(
+ sensitive_data.keys[4] = key_load_public(
_PATH_HOST_RSA_KEY_FILE, NULL);
sensitive_data.external_keysign = 1;
}
@@ -827,6 +854,13 @@ main(int ac, char **av)
ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr,
pw, timeout_ms);
+ if (packet_connection_is_on_socket()) {
+ verbose("Authenticated to %s ([%s]:%d).", host,
+ get_remote_ipaddr(), get_remote_port());
+ } else {
+ verbose("Authenticated to %s (via proxy).", host);
+ }
+
/* We no longer need the private host keys. Clear them now. */
if (sensitive_data.nkeys != 0) {
for (i = 0; i < sensitive_data.nkeys; i++) {
@@ -866,6 +900,61 @@ main(int ac, char **av)
return exit_status;
}
+static void
+control_persist_detach(void)
+{
+ pid_t pid;
+ int devnull;
+
+ debug("%s: backgrounding master process", __func__);
+
+ /*
+ * master (current process) into the background, and make the
+ * foreground process a client of the backgrounded master.
+ */
+ switch ((pid = fork())) {
+ case -1:
+ fatal("%s: fork: %s", __func__, strerror(errno));
+ case 0:
+ /* Child: master process continues mainloop */
+ break;
+ default:
+ /* 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;
+ tty_flag = otty_flag;
+ close(muxserver_sock);
+ muxserver_sock = -1;
+ muxclient(options.control_path);
+ /* muxclient() doesn't return on success. */
+ fatal("Failed to connect to new control master");
+ }
+ if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
+ error("%s: open(\"/dev/null\"): %s", __func__,
+ strerror(errno));
+ } else {
+ if (dup2(devnull, STDIN_FILENO) == -1 ||
+ dup2(devnull, STDOUT_FILENO) == -1)
+ error("%s: dup2: %s", __func__, strerror(errno));
+ if (devnull > STDERR_FILENO)
+ close(devnull);
+ }
+}
+
+/* Do fork() after authentication. Used by "ssh -f" */
+static void
+fork_postauth(void)
+{
+ if (need_controlpersist_detach)
+ control_persist_detach();
+ debug("forking to background");
+ fork_after_authentication_flag = 0;
+ if (daemon(1, 1) < 0)
+ fatal("daemon() failed: %.200s", strerror(errno));
+}
+
/* Callback for remote forward global requests */
static void
ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
@@ -877,9 +966,10 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
rfwd->listen_port, rfwd->connect_host, rfwd->connect_port);
if (type == SSH2_MSG_REQUEST_SUCCESS && rfwd->listen_port == 0) {
+ rfwd->allocated_port = packet_get_int();
logit("Allocated port %u for remote forward to %s:%d",
- packet_get_int(),
- rfwd->connect_host, rfwd->connect_port);
+ rfwd->allocated_port,
+ rfwd->connect_host, rfwd->connect_port);
}
if (type == SSH2_MSG_REQUEST_FAILURE) {
@@ -892,12 +982,8 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
}
if (++remote_forward_confirms_received == options.num_remote_forwards) {
debug("All remote forwarding requests processed");
- if (fork_after_authentication_flag) {
- fork_after_authentication_flag = 0;
- if (daemon(1, 1) < 0)
- fatal("daemon() failed: %.200s",
- strerror(errno));
- }
+ if (fork_after_authentication_flag)
+ fork_postauth();
}
}
@@ -1093,7 +1179,9 @@ ssh_session(void)
char *proto, *data;
/* Get reasonable local authentication information. */
client_x11_get_proto(display, options.xauth_location,
- options.forward_x11_trusted, &proto, &data);
+ options.forward_x11_trusted,
+ options.forward_x11_timeout,
+ &proto, &data);
/* Request forwarding with authentication spoofing. */
debug("Requesting X11 forwarding with authentication "
"spoofing.");
@@ -1139,12 +1227,13 @@ ssh_session(void)
* If requested and we are not interested in replies to remote
* forwarding requests, then let ssh continue in the background.
*/
- if (fork_after_authentication_flag &&
- (!options.exit_on_forward_failure ||
- options.num_remote_forwards == 0)) {
- fork_after_authentication_flag = 0;
- if (daemon(1, 1) < 0)
- fatal("daemon() failed: %.200s", strerror(errno));
+ if (fork_after_authentication_flag) {
+ if (options.exit_on_forward_failure &&
+ options.num_remote_forwards > 0) {
+ debug("deferring postauth fork until remote forward "
+ "confirmation received");
+ } else
+ fork_postauth();
}
/*
@@ -1175,18 +1264,22 @@ ssh_session(void)
/* request pty/x11/agent/tcpfwd/shell for channel */
static void
-ssh_session2_setup(int id, void *arg)
+ssh_session2_setup(int id, int success, void *arg)
{
extern char **environ;
const char *display;
int interactive = tty_flag;
+ if (!success)
+ return; /* No need for error message, channels code sens one */
+
display = getenv("DISPLAY");
if (options.forward_x11 && display != NULL) {
char *proto, *data;
/* Get reasonable local authentication information. */
client_x11_get_proto(display, options.xauth_location,
- options.forward_x11_trusted, &proto, &data);
+ options.forward_x11_trusted,
+ options.forward_x11_timeout, &proto, &data);
/* Request forwarding with authentication spoofing. */
debug("Requesting X11 forwarding with authentication "
"spoofing.");
@@ -1263,6 +1356,31 @@ ssh_session2(void)
/* XXX should be pre-session */
ssh_init_forwarding();
+ /* Start listening for multiplex clients */
+ muxserver_listen();
+
+ /*
+ * If we are in control persist mode, then prepare to background
+ * ourselves and have a foreground client attach as a control
+ * slave. NB. we must save copies of the flags that we override for
+ * the backgrounding, since we defer attachment of the slave until
+ * after the connection is fully established (in particular,
+ * async rfwd replies have been received for ExitOnForwardFailure).
+ */
+ 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;
+ 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;
+ fork_after_authentication_flag = 1;
+ }
+
if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
id = ssh_session2_open();
@@ -1281,14 +1399,17 @@ ssh_session2(void)
options.permit_local_command)
ssh_local_cmd(options.local_command);
- /* Start listening for multiplex clients */
- muxserver_listen();
-
- /* If requested, let ssh continue in the background. */
+ /*
+ * If requested and we are not interested in replies to remote
+ * forwarding requests, then let ssh continue in the background.
+ */
if (fork_after_authentication_flag) {
- fork_after_authentication_flag = 0;
- if (daemon(1, 1) < 0)
- fatal("daemon() failed: %.200s", strerror(errno));
+ if (options.exit_on_forward_failure &&
+ options.num_remote_forwards > 0) {
+ debug("deferring postauth fork until remote forward "
+ "confirmation received");
+ } else
+ fork_postauth();
}
if (options.use_roaming)
diff --git a/ssh.h b/ssh.h
index 186cfff9642f..c94633bdce42 100644
--- a/ssh.h
+++ b/ssh.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.h,v 1.78 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: ssh.h,v 1.79 2010/06/25 07:14:46 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -18,9 +18,6 @@
/* Default port number. */
#define SSH_DEFAULT_PORT 22
-/* Maximum number of TCP/IP ports forwarded per direction. */
-#define SSH_MAX_FORWARDS_PER_DIRECTION 100
-
/*
* Maximum number of RSA authentication identity files that can be specified
* in configuration files or on the command line.
diff --git a/ssh_config.0 b/ssh_config.0
index 1a2c64ce1523..6c19de7653bb 100644
--- a/ssh_config.0
+++ b/ssh_config.0
@@ -8,21 +8,21 @@ SYNOPSIS
/etc/ssh/ssh_config
DESCRIPTION
- ssh(1) obtains configuration data from the following sources in the fol-
- lowing order:
+ ssh(1) obtains configuration data from the following sources in the
+ following order:
1. command-line options
2. user's configuration file (~/.ssh/config)
3. system-wide configuration file (/etc/ssh/ssh_config)
- For each parameter, the first obtained value will be used. The configu-
- ration files contain sections separated by ``Host'' specifications, and
- that section is only applied for hosts that match one of the patterns
- given in the specification. The matched host name is the one given on
- the command line.
+ For each parameter, the first obtained value will be used. The
+ configuration files contain sections separated by ``Host''
+ specifications, and that section is only applied for hosts that match one
+ of the patterns given in the specification. The matched host name is the
+ one given on the command line.
- Since the first obtained value for each parameter is used, more host-spe-
- cific declarations should be given near the beginning of the file, and
+ Since the first obtained value for each parameter is used, more host-
+ specific declarations should be given near the beginning of the file, and
general defaults at the end.
The configuration file has the following format:
@@ -30,29 +30,29 @@ DESCRIPTION
Empty lines and lines starting with `#' are comments. Otherwise a line
is of the format ``keyword arguments''. Configuration options may be
separated by whitespace or optional whitespace and exactly one `='; the
- latter format is useful to avoid the need to quote whitespace when speci-
- fying configuration options using the ssh, scp, and sftp -o option. Ar-
- guments may optionally be enclosed in double quotes (") in order to rep-
- resent arguments containing spaces.
-
- The possible keywords and their meanings are as follows (note that key-
- words are case-insensitive and arguments are case-sensitive):
-
- Host Restricts the following declarations (up to the next Host key-
- word) to be only for those hosts that match one of the patterns
- given after the keyword. If more than one pattern is provided,
- they should be separated by whitespace. A single `*' as a pat-
- tern can be used to provide global defaults for all hosts. The
- host is the hostname argument given on the command line (i.e. the
- name is not converted to a canonicalized host name before match-
- ing).
+ latter format is useful to avoid the need to quote whitespace when
+ specifying configuration options using the ssh, scp, and sftp -o option.
+ Arguments may optionally be enclosed in double quotes (") in order to
+ represent arguments containing spaces.
+
+ The possible keywords and their meanings are as follows (note that
+ keywords are case-insensitive and arguments are case-sensitive):
+
+ Host Restricts the following declarations (up to the next Host
+ keyword) to be only for those hosts that match one of the
+ patterns given after the keyword. If more than one pattern is
+ provided, they should be separated by whitespace. A single `*'
+ as a pattern can be used to provide global defaults for all
+ hosts. The host is the hostname argument given on the command
+ line (i.e. the name is not converted to a canonicalized host name
+ before matching).
See PATTERNS for more information on patterns.
AddressFamily
- Specifies which address family to use when connecting. Valid ar-
- guments are ``any'', ``inet'' (use IPv4 only), or ``inet6'' (use
- IPv6 only).
+ Specifies which address family to use when connecting. Valid
+ arguments are ``any'', ``inet'' (use IPv4 only), or ``inet6''
+ (use IPv6 only).
BatchMode
If set to ``yes'', passphrase/password querying will be disabled.
@@ -61,8 +61,8 @@ DESCRIPTION
``yes'' or ``no''. The default is ``no''.
BindAddress
- Use the specified address on the local machine as the source ad-
- dress of the connection. Only useful on systems with more than
+ Use the specified address on the local machine as the source
+ address of the connection. Only useful on systems with more than
one address. Note that this option does not work if
UsePrivilegedPort is set to ``yes''.
@@ -78,20 +78,21 @@ DESCRIPTION
is set to ``no'', the check will not be executed. The default is
``yes''.
- Cipher Specifies the cipher to use for encrypting the session in proto-
- col version 1. Currently, ``blowfish'', ``3des'', and ``des''
- are supported. des is only supported in the ssh(1) client for
- interoperability with legacy protocol 1 implementations that do
- not support the 3des cipher. Its use is strongly discouraged due
- to cryptographic weaknesses. The default is ``3des''.
+ Cipher Specifies the cipher to use for encrypting the session in
+ protocol version 1. Currently, ``blowfish'', ``3des'', and
+ ``des'' are supported. des is only supported in the ssh(1)
+ client for interoperability with legacy protocol 1
+ implementations that do not support the 3des cipher. Its use is
+ strongly discouraged due to cryptographic weaknesses. The
+ default is ``3des''.
Ciphers
Specifies the ciphers allowed for protocol version 2 in order of
- preference. Multiple ciphers must be comma-separated. The sup-
- ported ciphers are ``3des-cbc'', ``aes128-cbc'', ``aes192-cbc'',
- ``aes256-cbc'', ``aes128-ctr'', ``aes192-ctr'', ``aes256-ctr'',
- ``arcfour128'', ``arcfour256'', ``arcfour'', ``blowfish-cbc'',
- and ``cast128-cbc''. The default is:
+ preference. Multiple ciphers must be comma-separated. The
+ supported ciphers are ``3des-cbc'', ``aes128-cbc'',
+ ``aes192-cbc'', ``aes256-cbc'', ``aes128-ctr'', ``aes192-ctr'',
+ ``aes256-ctr'', ``arcfour128'', ``arcfour256'', ``arcfour'',
+ ``blowfish-cbc'', and ``cast128-cbc''. The default is:
aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,
aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,
@@ -101,9 +102,10 @@ DESCRIPTION
Specifies that all local, remote, and dynamic port forwardings
specified in the configuration files or on the command line be
cleared. This option is primarily useful when used from the
- ssh(1) command line to clear port forwardings set in configura-
- tion files, and is automatically set by scp(1) and sftp(1). The
- argument must be ``yes'' or ``no''. The default is ``no''.
+ ssh(1) command line to clear port forwardings set in
+ configuration files, and is automatically set by scp(1) and
+ sftp(1). The argument must be ``yes'' or ``no''. The default is
+ ``no''.
Compression
Specifies whether to use compression. The argument must be
@@ -117,37 +119,37 @@ DESCRIPTION
option applies to protocol version 1 only.
ConnectionAttempts
- Specifies the number of tries (one per second) to make before ex-
- iting. The argument must be an integer. This may be useful in
+ Specifies the number of tries (one per second) to make before
+ exiting. The argument must be an integer. This may be useful in
scripts if the connection sometimes fails. The default is 1.
ConnectTimeout
Specifies the timeout (in seconds) used when connecting to the
SSH server, instead of using the default system TCP timeout.
- This value is used only when the target is down or really un-
- reachable, not when it refuses the connection.
+ This value is used only when the target is down or really
+ unreachable, not when it refuses the connection.
ControlMaster
Enables the sharing of multiple sessions over a single network
- connection. When set to ``yes'', ssh(1) will listen for connec-
- tions on a control socket specified using the ControlPath argu-
- ment. Additional sessions can connect to this socket using the
- same ControlPath with ControlMaster set to ``no'' (the default).
- These sessions will try to reuse the master instance's network
- connection rather than initiating new ones, but will fall back to
- connecting normally if the control socket does not exist, or is
- not listening.
-
- Setting this to ``ask'' will cause ssh to listen for control con-
- nections, but require confirmation using the SSH_ASKPASS program
- before they are accepted (see ssh-add(1) for details). If the
- ControlPath cannot be opened, ssh will continue without connect-
- ing to a master instance.
-
- X11 and ssh-agent(1) forwarding is supported over these multi-
- plexed connections, however the display and agent forwarded will
- be the one belonging to the master connection i.e. it is not pos-
- sible to forward multiple displays or agents.
+ connection. When set to ``yes'', ssh(1) will listen for
+ connections on a control socket specified using the ControlPath
+ argument. Additional sessions can connect to this socket using
+ the same ControlPath with ControlMaster set to ``no'' (the
+ default). These sessions will try to reuse the master instance's
+ network connection rather than initiating new ones, but will fall
+ back to connecting normally if the control socket does not exist,
+ or is not listening.
+
+ Setting this to ``ask'' will cause ssh to listen for control
+ connections, but require confirmation using the SSH_ASKPASS
+ program before they are accepted (see ssh-add(1) for details).
+ If the ControlPath cannot be opened, ssh will continue without
+ connecting to a master instance.
+
+ X11 and ssh-agent(1) forwarding is supported over these
+ multiplexed connections, however the display and agent forwarded
+ will be the one belonging to the master connection i.e. it is not
+ possible to forward multiple displays or agents.
Two additional options allow for opportunistic multiplexing: try
to use a master connection but fall back to creating a new one if
@@ -156,14 +158,30 @@ DESCRIPTION
option.
ControlPath
- Specify the path to the control socket used for connection shar-
- ing as described in the ControlMaster section above or the string
- ``none'' to disable connection sharing. In the path, `%l' will
- be substituted by the local host name, `%h' will be substituted
- by the target host name, `%p' the port, and `%r' by the remote
- login username. It is recommended that any ControlPath used for
- opportunistic connection sharing include at least %h, %p, and %r.
- This ensures that shared connections are uniquely identified.
+ Specify the path to the control socket used for connection
+ sharing as described in the ControlMaster section above or the
+ string ``none'' to disable connection sharing. In the path, `%l'
+ will be substituted by the local host name, `%h' will be
+ substituted by the target host name, `%p' the port, and `%r' by
+ the remote login username. It is recommended that any
+ ControlPath used for opportunistic connection sharing include at
+ least %h, %p, and %r. This ensures that shared connections are
+ uniquely identified.
+
+ ControlPersist
+ When used in conjunction with ControlMaster, specifies that the
+ master connection should remain open in the background (waiting
+ for future client connections) after the initial client
+ connection has been closed. If set to ``no'', then the master
+ connection will not be placed into the background, and will close
+ as soon as the initial client connection is closed. If set to
+ ``yes'', then the master connection will remain in the background
+ indefinitely (until killed or closed via a mechanism such as the
+ ssh(1) ``-O exit'' option). If set to a time in seconds, or a
+ time in any of the formats documented in sshd_config(5), then the
+ backgrounded master connection will automatically terminate after
+ it has remained idle (with no client connections) for the
+ specified time.
DynamicForward
Specifies that a TCP port on the local machine be forwarded over
@@ -171,14 +189,13 @@ DESCRIPTION
determine where to connect to from the remote machine.
The argument must be [bind_address:]port. IPv6 addresses can be
- specified by enclosing addresses in square brackets or by using
- an alternative syntax: [bind_address/]port. By default, the lo-
- cal port is bound in accordance with the GatewayPorts setting.
- However, an explicit bind_address may be used to bind the connec-
- tion to a specific address. The bind_address of ``localhost''
- indicates that the listening port be bound for local use only,
- while an empty address or `*' indicates that the port should be
- available from all interfaces.
+ specified by enclosing addresses in square brackets. By default,
+ the local port is bound in accordance with the GatewayPorts
+ setting. However, an explicit bind_address may be used to bind
+ the connection to a specific address. The bind_address of
+ ``localhost'' indicates that the listening port be bound for
+ local use only, while an empty address or `*' indicates that the
+ port should be available from all interfaces.
Currently the SOCKS4 and SOCKS5 protocols are supported, and
ssh(1) will act as a SOCKS server. Multiple forwardings may be
@@ -196,9 +213,9 @@ DESCRIPTION
EscapeChar
Sets the escape character (default: `~'). The escape character
can also be set on the command line. The argument should be a
- single character, `^' followed by a letter, or ``none'' to dis-
- able the escape character entirely (making the connection trans-
- parent for binary data).
+ single character, `^' followed by a letter, or ``none'' to
+ disable the escape character entirely (making the connection
+ transparent for binary data).
ExitOnForwardFailure
Specifies whether ssh(1) should terminate the connection if it
@@ -220,26 +237,34 @@ DESCRIPTION
the agent.
ForwardX11
- Specifies whether X11 connections will be automatically redirect-
- ed over the secure channel and DISPLAY set. The argument must be
- ``yes'' or ``no''. The default is ``no''.
+ Specifies whether X11 connections will be automatically
+ redirected over the secure channel and DISPLAY set. The argument
+ must be ``yes'' or ``no''. The default is ``no''.
X11 forwarding should be enabled with caution. Users with the
ability to bypass file permissions on the remote host (for the
- user's X11 authorization database) can access the local X11 dis-
- play through the forwarded connection. An attacker may then be
- able to perform activities such as keystroke monitoring if the
+ user's X11 authorization database) can access the local X11
+ display through the forwarded connection. An attacker may then
+ be able to perform activities such as keystroke monitoring if the
ForwardX11Trusted option is also enabled.
+ ForwardX11Timeout
+ Specify a timeout for untrusted X11 forwarding using the format
+ described in the TIME FORMATS section of sshd_config(5). X11
+ connections received by ssh(1) after this time will be refused.
+ The default is to disable untrusted X11 forwarding after twenty
+ minutes has elapsed.
+
ForwardX11Trusted
If this option is set to ``yes'', remote X11 clients will have
full access to the original X11 display.
- If this option is set to ``no'', remote X11 clients will be con-
- sidered untrusted and prevented from stealing or tampering with
- data belonging to trusted X11 clients. Furthermore, the xauth(1)
- token used for the session will be set to expire after 20 min-
- utes. Remote clients will be refused access after this time.
+ If this option is set to ``no'', remote X11 clients will be
+ considered untrusted and prevented from stealing or tampering
+ with data belonging to trusted X11 clients. Furthermore, the
+ xauth(1) token used for the session will be set to expire after
+ 20 minutes. Remote clients will be refused access after this
+ time.
The default is ``no''.
@@ -250,11 +275,11 @@ DESCRIPTION
Specifies whether remote hosts are allowed to connect to local
forwarded ports. By default, ssh(1) binds local port forwardings
to the loopback address. This prevents other remote hosts from
- connecting to forwarded ports. GatewayPorts can be used to spec-
- ify that ssh should bind local port forwardings to the wildcard
- address, thus allowing remote hosts to connect to forwarded
- ports. The argument must be ``yes'' or ``no''. The default is
- ``no''.
+ connecting to forwarded ports. GatewayPorts can be used to
+ specify that ssh should bind local port forwardings to the
+ wildcard address, thus allowing remote hosts to connect to
+ forwarded ports. The argument must be ``yes'' or ``no''. The
+ default is ``no''.
GlobalKnownHostsFile
Specifies a file to use for the global host key database instead
@@ -267,23 +292,23 @@ DESCRIPTION
GSSAPIDelegateCredentials
Forward (delegate) credentials to the server. The default is
- ``no''. Note that this option applies to protocol version 2 on-
- ly.
+ ``no''. Note that this option applies to protocol version 2
+ only.
HashKnownHosts
Indicates that ssh(1) should hash host names and addresses when
they are added to ~/.ssh/known_hosts. These hashed names may be
- used normally by ssh(1) and sshd(8), but they do not reveal iden-
- tifying information should the file's contents be disclosed. The
- default is ``no''. Note that existing names and addresses in
+ used normally by ssh(1) and sshd(8), but they do not reveal
+ identifying information should the file's contents be disclosed.
+ The default is ``no''. Note that existing names and addresses in
known hosts files will not be converted automatically, but may be
manually hashed using ssh-keygen(1).
HostbasedAuthentication
Specifies whether to try rhosts based authentication with public
key authentication. The argument must be ``yes'' or ``no''. The
- default is ``no''. This option applies to protocol version 2 on-
- ly and is similar to RhostsRSAAuthentication.
+ default is ``no''. This option applies to protocol version 2
+ only and is similar to RhostsRSAAuthentication.
HostKeyAlgorithms
Specifies the protocol version 2 host key algorithms that the
@@ -293,15 +318,18 @@ DESCRIPTION
HostKeyAlias
Specifies an alias that should be used instead of the real host
name when looking up or saving the host key in the host key
- database files. This option is useful for tunneling SSH connec-
- tions or for multiple servers running on a single host.
+ database files. This option is useful for tunneling SSH
+ connections or for multiple servers running on a single host.
HostName
Specifies the real host name to log into. This can be used to
- specify nicknames or abbreviations for hosts. The default is the
- name given on the command line. Numeric IP addresses are also
- permitted (both on the command line and in HostName specifica-
- tions).
+ specify nicknames or abbreviations for hosts. If the hostname
+ contains the character sequence `%h', then this will be replaced
+ with the host name specified on the commandline (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 HostName
+ specifications).
IdentitiesOnly
Specifies that ssh(1) should only use the authentication identity
@@ -314,90 +342,91 @@ DESCRIPTION
IdentityFile
Specifies a file from which the user's RSA or DSA authentication
identity is read. The default is ~/.ssh/identity for protocol
- version 1, and ~/.ssh/id_rsa and ~/.ssh/id_dsa for protocol ver-
- sion 2. Additionally, any identities represented by the authen-
- tication agent will be used for authentication. ssh(1) will try
- to load certificate information from the filename obtained by ap-
- pending -cert.pub to the path of a specified IdentityFile.
+ version 1, and ~/.ssh/id_rsa and ~/.ssh/id_dsa for protocol
+ version 2. Additionally, any identities represented by the
+ authentication agent will be used for authentication. ssh(1)
+ will try to load certificate information from the filename
+ obtained by appending -cert.pub to the path of a specified
+ IdentityFile.
The file name may use the tilde syntax to refer to a user's home
directory or one of the following escape characters: `%d' (local
user's home directory), `%u' (local user name), `%l' (local host
name), `%h' (remote host name) or `%r' (remote user name).
- It is possible to have multiple identity files specified in con-
- figuration files; all these identities will be tried in sequence.
+ It is possible to have multiple identity files specified in
+ configuration files; all these identities will be tried in
+ sequence.
KbdInteractiveAuthentication
Specifies whether to use keyboard-interactive authentication.
- The argument to this keyword must be ``yes'' or ``no''. The de-
- fault is ``yes''.
+ The argument to this keyword must be ``yes'' or ``no''. The
+ default is ``yes''.
KbdInteractiveDevices
- Specifies the list of methods to use in keyboard-interactive au-
- thentication. Multiple method names must be comma-separated.
+ Specifies the list of methods to use in keyboard-interactive
+ authentication. Multiple method names must be comma-separated.
The default is to use the server specified list. The methods
available vary depending on what the server supports. For an
OpenSSH server, it may be zero or more of: ``bsdauth'', ``pam'',
and ``skey''.
LocalCommand
- Specifies a command to execute on the local machine after suc-
- cessfully connecting to the server. The command string extends
- to the end of the line, and is executed with the user's shell.
- The following escape character substitutions will be performed:
- `%d' (local user's home directory), `%h' (remote host name), `%l'
- (local host name), `%n' (host name as provided on the command
- line), `%p' (remote port), `%r' (remote user name) or `%u' (local
- user name).
+ Specifies a command to execute on the local machine after
+ successfully connecting to the server. The command string
+ extends to the end of the line, and is executed with the user's
+ shell. The following escape character substitutions will be
+ performed: `%d' (local user's home directory), `%h' (remote host
+ name), `%l' (local host name), `%n' (host name as provided on the
+ command line), `%p' (remote port), `%r' (remote user name) or
+ `%u' (local user name).
The command is run synchronously and does not have access to the
session of the ssh(1) that spawned it. It should not be used for
interactive commands.
- This directive is ignored unless PermitLocalCommand has been en-
- abled.
+ This directive is ignored unless PermitLocalCommand has been
+ enabled.
LocalForward
Specifies that a TCP port on the local machine be forwarded over
the secure channel to the specified host and port from the remote
machine. The first argument must be [bind_address:]port and the
second argument must be host:hostport. IPv6 addresses can be
- specified by enclosing addresses in square brackets or by using
- an alternative syntax: [bind_address/]port and host/hostport.
- Multiple forwardings may be specified, and additional forwardings
- can be given on the command line. Only the superuser can forward
- privileged ports. By default, the local port is bound in accor-
- dance with the GatewayPorts setting. However, an explicit
- bind_address may be used to bind the connection to a specific ad-
- dress. The bind_address of ``localhost'' indicates that the lis-
- tening port be bound for local use only, while an empty address
- or `*' indicates that the port should be available from all in-
- terfaces.
+ specified by enclosing addresses in square brackets. Multiple
+ forwardings may be specified, and additional forwardings can be
+ given on the command line. Only the superuser can forward
+ privileged ports. By default, the local port is bound in
+ accordance with the GatewayPorts setting. However, an explicit
+ bind_address may be used to bind the connection to a specific
+ address. The bind_address of ``localhost'' indicates that the
+ listening port be bound for local use only, while an empty
+ address or `*' indicates that the port should be available from
+ all interfaces.
LogLevel
Gives the verbosity level that is used when logging messages from
- ssh(1). The possible values are: QUIET, FATAL, ERROR, INFO, VER-
- BOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3. The default is INFO.
+ ssh(1). The possible values are: QUIET, FATAL, ERROR, INFO,
+ VERBOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3. The default is INFO.
DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify
higher levels of verbose output.
- MACs Specifies the MAC (message authentication code) algorithms in or-
- der of preference. The MAC algorithm is used in protocol version
- 2 for data integrity protection. Multiple algorithms must be
- comma-separated. The default is:
+ MACs Specifies the MAC (message authentication code) algorithms in
+ order of preference. The MAC algorithm is used in protocol
+ version 2 for data integrity protection. Multiple algorithms
+ must be comma-separated. The default is:
hmac-md5,hmac-sha1,umac-64@openssh.com,
hmac-ripemd160,hmac-sha1-96,hmac-md5-96
NoHostAuthenticationForLocalhost
This option can be used if the home directory is shared across
- machines. In this case localhost will refer to a different ma-
- chine on each of the machines and the user will get many warnings
- about changed host keys. However, this option disables host au-
- thentication for localhost. The argument to this keyword must be
- ``yes'' or ``no''. The default is to check the host key for lo-
- calhost.
+ machines. In this case localhost will refer to a different
+ machine on each of the machines and the user will get many
+ warnings about changed host keys. However, this option disables
+ host authentication for localhost. The argument to this keyword
+ must be ``yes'' or ``no''. The default is to check the host key
+ for localhost.
NumberOfPasswordPrompts
Specifies the number of password prompts before giving up. The
@@ -409,43 +438,47 @@ DESCRIPTION
``yes''.
PermitLocalCommand
- Allow local command execution via the LocalCommand option or us-
- ing the !command escape sequence in ssh(1). The argument must be
- ``yes'' or ``no''. The default is ``no''.
+ Allow local command execution via the LocalCommand option or
+ using the !command escape sequence in ssh(1). The argument must
+ be ``yes'' or ``no''. The default is ``no''.
PKCS11Provider
Specifies which PKCS#11 provider to use. The argument to this
- keyword is the PKCS#11 shared libary ssh(1) should use to commu-
- nicate with a PKCS#11 token providing the user's private RSA key.
+ keyword is the PKCS#11 shared libary ssh(1) should use to
+ communicate with a PKCS#11 token providing the user's private RSA
+ key.
- Port Specifies the port number to connect on the remote host. The de-
- fault is 22.
+ Port Specifies the port number to connect on the remote host. The
+ default is 22.
PreferredAuthentications
- Specifies the order in which the client should try protocol 2 au-
- thentication methods. This allows a client to prefer one method
- (e.g. keyboard-interactive) over another method (e.g. password)
- The default for this option is: ``gssapi-with-
- mic,hostbased,publickey,keyboard-interactive,password''.
+ Specifies the order in which the client should try protocol 2
+ authentication methods. This allows a client to prefer one
+ method (e.g. keyboard-interactive) over another method (e.g.
+ password). The default is:
+
+ gssapi-with-mic,hostbased,publickey,
+ keyboard-interactive,password
Protocol
Specifies the protocol versions ssh(1) should support in order of
- preference. The possible values are `1' and `2'. Multiple ver-
- sions must be comma-separated. When this option is set to
- ``2,1'' ssh will try version 2 and fall back to version 1 if ver-
- sion 2 is not available. The default is `2'.
+ preference. The possible values are `1' and `2'. Multiple
+ versions must be comma-separated. When this option is set to
+ ``2,1'' ssh will try version 2 and fall back to version 1 if
+ version 2 is not available. The default is `2'.
ProxyCommand
- Specifies the command to use to connect to the server. The com-
- mand string extends to the end of the line, and is executed with
- the user's shell. In the command string, `%h' will be substitut-
- ed by the host name to connect and `%p' by the port. The command
- can be basically anything, and should read from its standard in-
- put and write to its standard output. It should eventually con-
- nect an sshd(8) server running on some machine, or execute sshd
- -i somewhere. Host key management will be done using the Host-
- Name of the host being connected (defaulting to the name typed by
- the user). Setting the command to ``none'' disables this option
+ Specifies the command to use to connect to the server. The
+ command string extends to the end of the line, and is executed
+ with the user's shell. In the command string, any occurrence of
+ `%h' will be substituted by the host name to connect, `%p' by the
+ port, and `%r' by the remote user name. The command can be
+ basically anything, and should read from its standard input and
+ write to its standard output. It should eventually connect an
+ sshd(8) server running on some machine, or execute sshd -i
+ somewhere. Host key management will be done using the HostName
+ of the host being connected (defaulting to the name typed by the
+ user). Setting the command to ``none'' disables this option
entirely. Note that CheckHostIP is not available for connects
with a proxy command.
@@ -461,32 +494,32 @@ DESCRIPTION
``yes''. This option applies to protocol version 2 only.
RekeyLimit
- Specifies the maximum amount of data that may be transmitted be-
- fore the session key is renegotiated. The argument is the number
- of bytes, with an optional suffix of `K', `M', or `G' to indicate
- Kilobytes, Megabytes, or Gigabytes, respectively. The default is
- between `1G' and `4G', depending on the cipher. This option ap-
- plies to protocol version 2 only.
+ Specifies the maximum amount of data that may be transmitted
+ before the session key is renegotiated. The argument is the
+ number of bytes, with an optional suffix of `K', `M', or `G' to
+ indicate Kilobytes, Megabytes, or Gigabytes, respectively. The
+ default is between `1G' and `4G', depending on the cipher. This
+ option applies to protocol version 2 only.
RemoteForward
Specifies that a TCP port on the remote machine be forwarded over
the secure channel to the specified host and port from the local
machine. The first argument must be [bind_address:]port and the
second argument must be host:hostport. IPv6 addresses can be
- specified by enclosing addresses in square brackets or by using
- an alternative syntax: [bind_address/]port and host/hostport.
- Multiple forwardings may be specified, and additional forwardings
- can be given on the command line. Privileged ports can be for-
- warded only when logging in as root on the remote machine.
+ specified by enclosing addresses in square brackets. Multiple
+ forwardings may be specified, and additional forwardings can be
+ given on the command line. Privileged ports can be forwarded
+ only when logging in as root on the remote machine.
If the port argument is `0', the listen port will be dynamically
allocated on the server and reported to the client at run time.
If the bind_address is not specified, the default is to only bind
to loopback addresses. If the bind_address is `*' or an empty
- string, then the forwarding is requested to listen on all inter-
- faces. Specifying a remote bind_address will only succeed if the
- server's GatewayPorts option is enabled (see sshd_config(5)).
+ string, then the forwarding is requested to listen on all
+ interfaces. Specifying a remote bind_address will only succeed
+ if the server's GatewayPorts option is enabled (see
+ sshd_config(5)).
RhostsRSAAuthentication
Specifies whether to try rhosts based authentication with RSA
@@ -497,9 +530,9 @@ DESCRIPTION
RSAAuthentication
Specifies whether to try RSA authentication. The argument to
this keyword must be ``yes'' or ``no''. RSA authentication will
- only be attempted if the identity file exists, or an authentica-
- tion agent is running. The default is ``yes''. Note that this
- option applies to protocol version 1 only.
+ only be attempted if the identity file exists, or an
+ authentication agent is running. The default is ``yes''. Note
+ that this option applies to protocol version 1 only.
SendEnv
Specifies what variables from the local environ(7) should be sent
@@ -507,25 +540,25 @@ DESCRIPTION
for protocol 2. The server must also support it, and the server
must be configured to accept these environment variables. Refer
to AcceptEnv in sshd_config(5) for how to configure the server.
- Variables are specified by name, which may contain wildcard char-
- acters. Multiple environment variables may be separated by
- whitespace or spread across multiple SendEnv directives. The de-
- fault is not to send any environment variables.
+ Variables are specified by name, which may contain wildcard
+ characters. Multiple environment variables may be separated by
+ whitespace or spread across multiple SendEnv directives. The
+ default is not to send any environment variables.
See PATTERNS for more information on patterns.
ServerAliveCountMax
Sets the number of server alive messages (see below) which may be
sent without ssh(1) receiving any messages back from the server.
- If this threshold is reached while server alive messages are be-
- ing sent, ssh will disconnect from the server, terminating the
+ If this threshold is reached while server alive messages are
+ being sent, ssh will disconnect from the server, terminating the
session. It is important to note that the use of server alive
messages is very different from TCPKeepAlive (below). The server
- alive messages are sent through the encrypted channel and there-
- fore will not be spoofable. The TCP keepalive option enabled by
- TCPKeepAlive is spoofable. The server alive mechanism is valu-
- able when the client or server depend on knowing when a connec-
- tion has become inactive.
+ alive messages are sent through the encrypted channel and
+ therefore will not be spoofable. The TCP keepalive option
+ enabled by TCPKeepAlive is spoofable. The server alive mechanism
+ is valuable when the client or server depend on knowing when a
+ connection has become inactive.
The default value is 3. If, for example, ServerAliveInterval
(see below) is set to 15 and ServerAliveCountMax is left at the
@@ -542,27 +575,27 @@ DESCRIPTION
StrictHostKeyChecking
If this flag is set to ``yes'', ssh(1) will never automatically
- add host keys to the ~/.ssh/known_hosts file, and refuses to con-
- nect to hosts whose host key has changed. This provides maximum
- protection against trojan horse attacks, though it can be annoy-
- ing when the /etc/ssh/ssh_known_hosts file is poorly maintained
- or when connections to new hosts are frequently made. This op-
- tion forces the user to manually add all new hosts. If this flag
- is set to ``no'', ssh will automatically add new host keys to the
- user known hosts files. If this flag is set to ``ask'', new host
- keys will be added to the user known host files only after the
- user has confirmed that is what they really want to do, and ssh
- will refuse to connect to hosts whose host key has changed. The
- host keys of known hosts will be verified automatically in all
- cases. The argument must be ``yes'', ``no'', or ``ask''. The
- default is ``ask''.
+ add host keys to the ~/.ssh/known_hosts file, and refuses to
+ connect to hosts whose host key has changed. This provides
+ maximum protection against trojan horse attacks, though it can be
+ annoying when the /etc/ssh/ssh_known_hosts file is poorly
+ maintained or when connections to new hosts are frequently made.
+ This option forces the user to manually add all new hosts. If
+ this flag is set to ``no'', ssh will automatically add new host
+ keys to the user known hosts files. If this flag is set to
+ ``ask'', new host keys will be added to the user known host files
+ only after the user has confirmed that is what they really want
+ to do, and ssh will refuse to connect to hosts whose host key has
+ changed. The host keys of known hosts will be verified
+ automatically in all cases. The argument must be ``yes'',
+ ``no'', or ``ask''. The default is ``ask''.
TCPKeepAlive
Specifies whether the system should send TCP keepalive messages
to the other side. If they are sent, death of the connection or
crash of one of the machines will be properly noticed. However,
- this means that connections will die if the route is down tem-
- porarily, and some people find it annoying.
+ this means that connections will die if the route is down
+ temporarily, and some people find it annoying.
The default is ``yes'' (to send TCP keepalive messages), and the
client will notice if the network goes down or the remote host
@@ -571,32 +604,32 @@ DESCRIPTION
To disable TCP keepalive messages, the value should be set to
``no''.
- Tunnel Request tun(4) device forwarding between the client and the serv-
- er. The argument must be ``yes'', ``point-to-point'' (layer 3),
- ``ethernet'' (layer 2), or ``no''. Specifying ``yes'' requests
- the default tunnel mode, which is ``point-to-point''. The de-
- fault is ``no''.
+ Tunnel Request tun(4) device forwarding between the client and the
+ server. The argument must be ``yes'', ``point-to-point'' (layer
+ 3), ``ethernet'' (layer 2), or ``no''. Specifying ``yes''
+ requests the default tunnel mode, which is ``point-to-point''.
+ The default is ``no''.
TunnelDevice
Specifies the tun(4) devices to open on the client (local_tun)
and the server (remote_tun).
- The argument must be local_tun[:remote_tun]. The devices may be
+ The argument must be local_tun [:remote_tun]. The devices may be
specified by numerical ID or the keyword ``any'', which uses the
next available tunnel device. If remote_tun is not specified, it
defaults to ``any''. The default is ``any:any''.
UsePrivilegedPort
- Specifies whether to use a privileged port for outgoing connec-
- tions. The argument must be ``yes'' or ``no''. The default is
- ``no''. If set to ``yes'', ssh(1) must be setuid root. Note
- that this option must be set to ``yes'' for
+ Specifies whether to use a privileged port for outgoing
+ connections. The argument must be ``yes'' or ``no''. The
+ default is ``no''. If set to ``yes'', ssh(1) must be setuid
+ root. Note that this option must be set to ``yes'' for
RhostsRSAAuthentication with older servers.
- User Specifies the user to log in as. This can be useful when a dif-
- ferent user name is used on different machines. This saves the
- trouble of having to remember to give the user name on the com-
- mand line.
+ User Specifies the user to log in as. 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.
UserKnownHostsFile
Specifies a file to use for the user host key database instead of
@@ -620,9 +653,9 @@ DESCRIPTION
If this flag is set to ``yes'', an ASCII art representation of
the remote host key fingerprint is printed in addition to the hex
fingerprint string at login and for unknown host keys. If this
- flag is set to ``no'', no fingerprint strings are printed at lo-
- gin and only the hex fingerprint string will be printed for un-
- known host keys. The default is ``no''.
+ flag is set to ``no'', no fingerprint strings are printed at
+ login and only the hex fingerprint string will be printed for
+ unknown host keys. The default is ``no''.
XAuthLocation
Specifies the full pathname of the xauth(1) program. The default
@@ -631,9 +664,9 @@ DESCRIPTION
PATTERNS
A pattern consists of zero or more non-whitespace characters, `*' (a
wildcard that matches zero or more characters), or `?' (a wildcard that
- matches exactly one character). For example, to specify a set of decla-
- rations for any host in the ``.co.uk'' set of domains, the following pat-
- tern could be used:
+ matches exactly one character). For example, to specify a set of
+ declarations for any host in the ``.co.uk'' set of domains, the following
+ pattern could be used:
Host *.co.uk
@@ -645,17 +678,18 @@ PATTERNS
A pattern-list is a comma-separated list of patterns. Patterns within
pattern-lists may be negated by preceding them with an exclamation mark
(`!'). For example, to allow a key to be used from anywhere within an
- organisation except from the ``dialup'' pool, the following entry (in au-
- thorized_keys) could be used:
+ organisation except from the ``dialup'' pool, the following entry (in
+ authorized_keys) could be used:
from="!*.dialup.example.com,*.example.com"
FILES
~/.ssh/config
This is the per-user configuration file. The format of this file
- is described above. This file is used by the SSH client. Be-
- cause of the potential for abuse, this file must have strict per-
- missions: read/write for the user, and not accessible by others.
+ is described above. This file is used by the SSH client.
+ Because of the potential for abuse, this file must have strict
+ permissions: read/write for the user, and not accessible by
+ others.
/etc/ssh/ssh_config
Systemwide configuration file. This file provides defaults for
@@ -669,8 +703,8 @@ SEE ALSO
AUTHORS
OpenSSH is a derivative of the original and free ssh 1.2.12 release by
Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo
- de Raadt and Dug Song removed many bugs, re-added newer features and cre-
- ated OpenSSH. Markus Friedl contributed the support for SSH protocol
+ de Raadt and Dug Song removed many bugs, re-added newer features and
+ created OpenSSH. Markus Friedl contributed the support for SSH protocol
versions 1.5 and 2.0.
-OpenBSD 4.7 March 26, 2010 11
+OpenBSD 4.8 August 4, 2010 OpenBSD 4.8
diff --git a/ssh_config.5 b/ssh_config.5
index 410853560401..ddb806ec00e7 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -34,8 +34,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: ssh_config.5,v 1.130 2010/03/26 01:06:13 dtucker Exp $
-.Dd $Mdocdate: March 26 2010 $
+.\" $OpenBSD: ssh_config.5,v 1.138 2010/08/04 05:37:01 djm Exp $
+.Dd $Mdocdate: August 4 2010 $
.Dt SSH_CONFIG 5
.Os
.Sh NAME
@@ -319,6 +319,28 @@ It is recommended that any
used for opportunistic connection sharing include
at least %h, %p, and %r.
This ensures that shared connections are uniquely identified.
+.It Cm ControlPersist
+When used in conjunction with
+.Cm ControlMaster ,
+specifies that the master connection should remain open
+in the background (waiting for future client connections)
+after the initial client connection has been closed.
+If set to
+.Dq no ,
+then the master connection will not be placed into the background,
+and will close as soon as the initial client connection is closed.
+If set to
+.Dq yes ,
+then the master connection will remain in the background indefinitely
+(until killed or closed via a mechanism such as the
+.Xr ssh 1
+.Dq Fl O No exit
+option).
+If set to a time in seconds, or a time in any of the formats documented in
+.Xr sshd_config 5 ,
+then the backgrounded master connection will automatically terminate
+after it has remained idle (with no client connections) for the
+specified time.
.It Cm DynamicForward
Specifies that a TCP port on the local machine be forwarded
over the secure channel, and the application
@@ -329,9 +351,7 @@ The argument must be
.Sm off
.Oo Ar bind_address : Oc Ar port .
.Sm on
-IPv6 addresses can be specified by enclosing addresses in square brackets or
-by using an alternative syntax:
-.Oo Ar bind_address Ns / Oc Ns Ar port .
+IPv6 addresses can be specified by enclosing addresses in square brackets.
By default, the local port is bound in accordance with the
.Cm GatewayPorts
setting.
@@ -432,6 +452,17 @@ An attacker may then be able to perform activities such as keystroke monitoring
if the
.Cm ForwardX11Trusted
option is also enabled.
+.It Cm ForwardX11Timeout
+Specify a timeout for untrusted X11 forwarding
+using the format described in the
+.Sx TIME FORMATS
+section of
+.Xr sshd_config 5 .
+X11 connections received by
+.Xr ssh 1
+after this time will be refused.
+The default is to disable untrusted X11 forwarding after twenty minutes has
+elapsed.
.It Cm ForwardX11Trusted
If this option is set to
.Dq yes ,
@@ -526,6 +557,10 @@ or for multiple servers running on a single host.
.It Cm HostName
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
+(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
.Cm HostName
@@ -641,11 +676,7 @@ The first argument must be
.Sm on
and the second argument must be
.Ar host : Ns Ar hostport .
-IPv6 addresses can be specified by enclosing addresses in square brackets or
-by using an alternative syntax:
-.Oo Ar bind_address Ns / Oc Ns Ar port
-and
-.Ar host Ns / Ns Ar hostport .
+IPv6 addresses can be specified by enclosing addresses in square brackets.
Multiple forwardings may be specified, and additional forwardings can be
given on the command line.
Only the superuser can forward privileged ports.
@@ -732,10 +763,12 @@ authentication methods.
This allows a client to prefer one method (e.g.\&
.Cm keyboard-interactive )
over another method (e.g.\&
-.Cm password )
-The default for this option is:
-.Do gssapi-with-mic,hostbased,publickey,keyboard-interactive,password
-.Dc .
+.Cm password ) .
+The default is:
+.Bd -literal -offset indent
+gssapi-with-mic,hostbased,publickey,
+keyboard-interactive,password
+.Ed
.It Cm Protocol
Specifies the protocol versions
.Xr ssh 1
@@ -757,12 +790,14 @@ Specifies the command to use to connect to the server.
The command
string extends to the end of the line, and is executed with
the user's shell.
-In the command string,
+In the command string, any occurrence of
.Ql %h
will be substituted by the host name to
-connect and
+connect,
.Ql %p
-by the port.
+by the port, and
+.Ql %r
+by the remote user name.
The command can be basically anything,
and should read from its standard input and write to its standard output.
It should eventually connect an
@@ -821,11 +856,7 @@ The first argument must be
.Sm on
and the second argument must be
.Ar host : Ns Ar hostport .
-IPv6 addresses can be specified by enclosing addresses in square brackets
-or by using an alternative syntax:
-.Oo Ar bind_address Ns / Oc Ns Ar port
-and
-.Ar host Ns / Ns Ar hostport .
+IPv6 addresses can be specified by enclosing addresses in square brackets.
Multiple forwardings may be specified, and additional
forwardings can be given on the command line.
Privileged ports can be forwarded only when
diff --git a/sshconnect.c b/sshconnect.c
index 9de52224d34c..f55beffe40fc 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.c,v 1.220 2010/03/04 10:36:03 djm Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.224 2010/04/16 21:14:27 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -101,8 +101,8 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
* (e.g. Solaris)
*/
xasprintf(&tmp, "exec %s", proxy_command);
- command_string = percent_expand(tmp, "h", host,
- "p", strport, (char *)NULL);
+ command_string = percent_expand(tmp, "h", host, "p", strport,
+ "r", options.user, (char *)NULL);
xfree(tmp);
/* Create pipes for communicating with the proxy. */
@@ -586,9 +586,9 @@ check_host_cert(const char *host, const Key *host_key)
error("%s", reason);
return 0;
}
- if (buffer_len(&host_key->cert->constraints) != 0) {
- error("Certificate for %s contains unsupported constraint(s)",
- host);
+ if (buffer_len(&host_key->cert->critical) != 0) {
+ error("Certificate for %s contains unsupported "
+ "critical options(s)", host);
return 0;
}
return 1;
@@ -739,7 +739,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
debug("Host '%.200s' is known and matches the %s host %s.",
host, type, want_cert ? "certificate" : "key");
debug("Found %s in %s:%d",
- want_cert ? "certificate" : "key", host_file, host_line);
+ want_cert ? "CA key" : "key", host_file, host_line);
if (want_cert && !check_host_cert(hostname, host_key))
goto fail;
if (options.check_host_ip && ip_status == HOST_NEW) {
diff --git a/sshconnect2.c b/sshconnect2.c
index 2a5943e7e26d..4c379ae5988c 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect2.c,v 1.180 2010/02/26 20:29:54 djm Exp $ */
+/* $OpenBSD: sshconnect2.c,v 1.183 2010/04/26 22:28:24 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -195,7 +195,7 @@ struct Authctxt {
const char *host;
const char *service;
Authmethod *method;
- int success;
+ sig_atomic_t success;
char *authlist;
/* pubkey */
Idlist keys;
@@ -1140,8 +1140,11 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
u_int skip = 0;
int ret = -1;
int have_sig = 1;
+ char *fp;
- debug3("sign_and_send_pubkey");
+ fp = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX);
+ debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp);
+ xfree(fp);
if (key_to_blob(id->key, &blob, &bloblen) == 0) {
/* we cannot handle this key */
@@ -1398,7 +1401,8 @@ userauth_pubkey(Authctxt *authctxt)
* private key instead
*/
if (id->key && id->key->type != KEY_RSA1) {
- debug("Offering public key: %s", id->filename);
+ debug("Offering %s public key: %s", key_type(id->key),
+ id->filename);
sent = send_pubkey_test(authctxt, id);
} else if (id->key == NULL) {
debug("Trying private key: %s", id->filename);
diff --git a/sshd.0 b/sshd.0
index 30bf6dedeea0..a5d40c4d83bc 100644
--- a/sshd.0
+++ b/sshd.0
@@ -10,19 +10,19 @@ SYNOPSIS
DESCRIPTION
sshd (OpenSSH Daemon) is the daemon program for ssh(1). Together these
- programs replace rlogin(1) and rsh(1), and provide secure encrypted com-
- munications between two untrusted hosts over an insecure network.
+ programs replace rlogin(1) and rsh(1), and provide secure encrypted
+ communications between two untrusted hosts over an insecure network.
sshd listens for connections from clients. It is normally started at
boot from /etc/rc. It forks a new daemon for each incoming connection.
- The forked daemons handle key exchange, encryption, authentication, com-
- mand execution, and data exchange.
+ The forked daemons handle key exchange, encryption, authentication,
+ command execution, and data exchange.
sshd can be configured using command-line options or a configuration file
- (by default sshd_config(5)); command-line options override values speci-
- fied in the configuration file. sshd rereads its configuration file when
- it receives a hangup signal, SIGHUP, by executing itself with the name
- and options it was started with, e.g. /usr/sbin/sshd.
+ (by default sshd_config(5)); command-line options override values
+ specified in the configuration file. sshd rereads its configuration file
+ when it receives a hangup signal, SIGHUP, by executing itself with the
+ name and options it was started with, e.g. /usr/sbin/sshd.
The options are as follows:
@@ -38,87 +38,89 @@ DESCRIPTION
Specify the connection parameters to use for the -T extended test
mode. If provided, any Match directives in the configuration
file that would apply to the specified user, host, and address
- will be set before the configuration is written to standard out-
- put. The connection parameters are supplied as keyword=value
+ will be set before the configuration is written to standard
+ output. The connection parameters are supplied as keyword=value
pairs. The keywords are ``user'', ``host'', and ``addr''. All
- are required and may be supplied in any order, either with multi-
- ple -C options or as a comma-separated list.
+ are required and may be supplied in any order, either with
+ multiple -C options or as a comma-separated list.
-c host_certificate_file
Specifies a path to a certificate file to identify sshd during
key exchange. The certificate file must match a host key file
- specified using the -h option or the HostKey configuration direc-
- tive.
+ specified using the -h option or the HostKey configuration
+ directive.
-D When this option is specified, sshd will not detach and does not
become a daemon. This allows easy monitoring of sshd.
-d Debug mode. The server sends verbose debug output to standard
- error, and does not put itself in the background. The server al-
- so will not fork and will only process one connection. This op-
- tion is only intended for debugging for the server. Multiple -d
- options increase the debugging level. Maximum is 3.
+ error, and does not put itself in the background. The server
+ also will not fork and will only process one connection. This
+ option is only intended for debugging for the server. Multiple
+ -d options increase the debugging level. Maximum is 3.
-e When this option is specified, sshd will send the output to the
standard error instead of the system log.
-f config_file
Specifies the name of the configuration file. The default is
- /etc/ssh/sshd_config. sshd refuses to start if there is no con-
- figuration file.
+ /etc/ssh/sshd_config. sshd refuses to start if there is no
+ configuration file.
-g login_grace_time
- Gives the grace time for clients to authenticate themselves (de-
- fault 120 seconds). If the client fails to authenticate the user
- within this many seconds, the server disconnects and exits. A
- value of zero indicates no limit.
+ Gives the grace time for clients to authenticate themselves
+ (default 120 seconds). If the client fails to authenticate the
+ user within this many seconds, the server disconnects and exits.
+ A value of zero indicates no limit.
-h host_key_file
Specifies a file from which a host key is read. This option must
be given if sshd is not run as root (as the normal host key files
are normally not readable by anyone but root). The default is
/etc/ssh/ssh_host_key for protocol version 1, and
- /etc/ssh/ssh_host_rsa_key and /etc/ssh/ssh_host_dsa_key for pro-
- tocol version 2. It is possible to have multiple host key files
- for the different protocol versions and host key algorithms.
+ /etc/ssh/ssh_host_rsa_key and /etc/ssh/ssh_host_dsa_key for
+ protocol version 2. It is possible to have multiple host key
+ files for the different protocol versions and host key
+ algorithms.
-i Specifies that sshd is being run from inetd(8). sshd is normally
not run from inetd because it needs to generate the server key
before it can respond to the client, and this may take tens of
- seconds. Clients would have to wait too long if the key was re-
- generated every time. However, with small key sizes (e.g. 512)
+ seconds. Clients would have to wait too long if the key was
+ regenerated every time. However, with small key sizes (e.g. 512)
using sshd from inetd may be feasible.
-k key_gen_time
Specifies how often the ephemeral protocol version 1 server key
- is regenerated (default 3600 seconds, or one hour). The motiva-
- tion for regenerating the key fairly often is that the key is not
- stored anywhere, and after about an hour it becomes impossible to
- recover the key for decrypting intercepted communications even if
- the machine is cracked into or physically seized. A value of ze-
- ro indicates that the key will never be regenerated.
+ is regenerated (default 3600 seconds, or one hour). The
+ motivation for regenerating the key fairly often is that the key
+ is not stored anywhere, and after about an hour it becomes
+ impossible to recover the key for decrypting intercepted
+ communications even if the machine is cracked into or physically
+ seized. A value of zero indicates that the key will never be
+ regenerated.
-o option
- Can be used to give options in the format used in the configura-
- tion file. This is useful for specifying options for which there
- is no separate command-line flag. For full details of the op-
- tions, and their values, see sshd_config(5).
+ 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 command-line flag. For full details
+ of the options, and their values, see sshd_config(5).
-p port
Specifies the port on which the server listens for connections
- (default 22). Multiple port options are permitted. Ports speci-
- fied in the configuration file with the Port option are ignored
- when a command-line port is specified. Ports specified using the
- ListenAddress option override command-line ports.
+ (default 22). Multiple port options are permitted. Ports
+ specified in the configuration file with the Port option are
+ ignored when a command-line port is specified. Ports specified
+ using the ListenAddress option override command-line ports.
- -q Quiet mode. Nothing is sent to the system log. Normally the be-
- ginning, authentication, and termination of each connection is
+ -q Quiet mode. Nothing is sent to the system log. Normally the
+ beginning, authentication, and termination of each connection is
logged.
-T Extended test mode. Check the validity of the configuration
file, output the effective configuration to stdout and then exit.
- Optionally, Match rules may be applied by specifying the connec-
- tion parameters using one or more -C options.
+ Optionally, Match rules may be applied by specifying the
+ connection parameters using one or more -C options.
-t Test mode. Only check the validity of the configuration file and
sanity of the keys. This is useful for updating sshd reliably as
@@ -127,76 +129,76 @@ DESCRIPTION
-u len This option is used to specify the size of the field in the utmp
structure that holds the remote host name. If the resolved host
name is longer than len, the dotted decimal value will be used
- instead. This allows hosts with very long host names that over-
- flow this field to still be uniquely identified. Specifying -u0
- indicates that only dotted decimal addresses should be put into
- the utmp file. -u0 may also be used to prevent sshd from making
- DNS requests unless the authentication mechanism or configuration
- requires it. Authentication mechanisms that may require DNS in-
- clude RhostsRSAAuthentication, HostbasedAuthentication, and using
- a from="pattern-list" option in a key file. Configuration op-
- tions that require DNS include using a USER@HOST pattern in
- AllowUsers or DenyUsers.
+ instead. This allows hosts with very long host names that
+ overflow this field to still be uniquely identified. Specifying
+ -u0 indicates that only dotted decimal addresses should be put
+ into the utmp file. -u0 may also be used to prevent sshd from
+ making DNS requests unless the authentication mechanism or
+ configuration requires it. Authentication mechanisms that may
+ require DNS include RhostsRSAAuthentication,
+ HostbasedAuthentication, and using a from="pattern-list" option
+ in a key file. Configuration options that require DNS include
+ using a USER@HOST pattern in AllowUsers or DenyUsers.
AUTHENTICATION
The OpenSSH SSH daemon supports SSH protocols 1 and 2. The default is to
use protocol 2 only, though this can be changed via the Protocol option
in sshd_config(5). Protocol 2 supports both RSA and DSA keys; protocol 1
- only supports RSA keys. For both protocols, each host has a host-specif-
- ic key, normally 2048 bits, used to identify the host.
+ only supports RSA keys. For both protocols, each host has a host-
+ specific key, normally 2048 bits, used to identify the host.
Forward security for protocol 1 is provided through an additional server
key, normally 768 bits, generated when the server starts. This key is
normally regenerated every hour if it has been used, and is never stored
on disk. Whenever a client connects, the daemon responds with its public
host and server keys. The client compares the RSA host key against its
- own database to verify that it has not changed. The client then gener-
- ates a 256-bit random number. It encrypts this random number using both
- the host key and the server key, and sends the encrypted number to the
- server. Both sides then use this random number as a session key which is
- used to encrypt all further communications in the session. The rest of
- the session is encrypted using a conventional cipher, currently Blowfish
- or 3DES, with 3DES being used by default. The client selects the encryp-
- tion algorithm to use from those offered by the server.
+ own database to verify that it has not changed. The client then
+ generates a 256-bit random number. It encrypts this random number using
+ both the host key and the server key, and sends the encrypted number to
+ the server. Both sides then use this random number as a session key
+ which is used to encrypt all further communications in the session. The
+ rest of the session is encrypted using a conventional cipher, currently
+ Blowfish or 3DES, with 3DES being used by default. The client selects
+ the encryption algorithm to use from those offered by the server.
For protocol 2, forward security is provided through a Diffie-Hellman key
agreement. This key agreement results in a shared session key. The rest
of the session is encrypted using a symmetric cipher, currently 128-bit
AES, Blowfish, 3DES, CAST128, Arcfour, 192-bit AES, or 256-bit AES. The
client selects the encryption algorithm to use from those offered by the
- server. Additionally, session integrity is provided through a crypto-
- graphic message authentication code (hmac-md5, hmac-sha1, umac-64 or
- hmac-ripemd160).
+ server. Additionally, session integrity is provided through a
+ cryptographic message authentication code (hmac-md5, hmac-sha1, umac-64
+ or hmac-ripemd160).
Finally, the server and the client enter an authentication dialog. The
- client tries to authenticate itself using host-based authentication, pub-
- lic key authentication, challenge-response authentication, or password
+ client tries to authenticate itself using host-based authentication,
+ public key authentication, challenge-response authentication, or password
authentication.
Regardless of the authentication type, the account is checked to ensure
that it is accessible. An account is not accessible if it is locked,
- listed in DenyUsers or its group is listed in DenyGroups . The defini-
- tion of a locked account is system dependant. Some platforms have their
- own account database (eg AIX) and some modify the passwd field ( `*LK*'
- on Solaris and UnixWare, `*' on HP-UX, containing `Nologin' on Tru64, a
- leading `*LOCKED*' on FreeBSD and a leading `!' on most Linuxes). If
- there is a requirement to disable password authentication for the account
- while allowing still public-key, then the passwd field should be set to
- something other than these values (eg `NP' or `*NP*' ).
+ listed in DenyUsers or its group is listed in DenyGroups . The
+ definition of a locked account is system dependant. Some platforms have
+ their own account database (eg AIX) and some modify the passwd field (
+ `*LK*' on Solaris and UnixWare, `*' on HP-UX, containing `Nologin' on
+ Tru64, a leading `*LOCKED*' on FreeBSD and a leading `!' on most
+ Linuxes). If there is a requirement to disable password authentication
+ for the account while allowing still public-key, then the passwd field
+ should be set to something other than these values (eg `NP' or `*NP*' ).
If the client successfully authenticates itself, a dialog for preparing
the session is entered. At this time the client may request things like
- allocating a pseudo-tty, forwarding X11 connections, forwarding TCP con-
- nections, or forwarding the authentication agent connection over the se-
- cure channel.
+ allocating a pseudo-tty, forwarding X11 connections, forwarding TCP
+ connections, or forwarding the authentication agent connection over the
+ secure channel.
After this, the client either requests a shell or execution of a command.
The sides then enter session mode. In this mode, either side may send
data at any time, and such data is forwarded to/from the shell or command
on the server side, and the user terminal in the client side.
- When the user program terminates and all forwarded X11 and other connec-
- tions have been closed, the server sends command exit status to the
+ When the user program terminates and all forwarded X11 and other
+ connections have been closed, the server sends command exit status to the
client, and both sides exit.
LOGIN PROCESS
@@ -230,11 +232,12 @@ LOGIN PROCESS
SSHRC
If the file ~/.ssh/rc exists, sh(1) runs it after reading the environment
- files but before starting the user's shell or command. It must not pro-
- duce any output on stdout; stderr must be used instead. If X11 forward-
- ing is in use, it will receive the "proto cookie" pair in its standard
- input (and DISPLAY in its environment). The script must call xauth(1)
- because sshd will not run xauth automatically to add X11 cookies.
+ files but before starting the user's shell or command. It must not
+ produce any output on stdout; stderr must be used instead. If X11
+ forwarding is in use, it will receive the "proto cookie" pair in its
+ standard input (and DISPLAY in its environment). The script must call
+ xauth(1) because sshd will not run xauth automatically to add X11
+ cookies.
The primary purpose of this file is to run any initialization routines
which may be needed before the user's home directory becomes accessible;
@@ -263,33 +266,33 @@ AUTHORIZED_KEYS FILE FORMAT
~/.ssh/authorized_keys. Each line of the file contains one key (empty
lines and lines starting with a `#' are ignored as comments). Protocol 1
public keys consist of the following space-separated fields: options,
- bits, exponent, modulus, comment. Protocol 2 public key consist of: op-
- tions, keytype, base64-encoded key, comment. The options field is op-
- tional; its presence is determined by whether the line starts with a num-
- ber or not (the options field never starts with a number). The bits, ex-
- ponent, modulus, and comment fields give the RSA key for protocol version
- 1; the comment field is not used for anything (but may be convenient for
- the user to identify the key). For protocol version 2 the keytype is
- ``ssh-dss'' or ``ssh-rsa''.
-
- Note that lines in this file are usually several hundred bytes long (be-
- cause of the size of the public key encoding) up to a limit of 8 kilo-
- bytes, which permits DSA keys up to 8 kilobits and RSA keys up to 16
+ bits, exponent, modulus, comment. Protocol 2 public key consist of:
+ options, keytype, base64-encoded key, comment. The options field is
+ optional; its presence is determined by whether the line starts with a
+ number or not (the options field never starts with a number). The bits,
+ exponent, modulus, and comment fields give the RSA key for protocol
+ version 1; the comment field is not used for anything (but may be
+ convenient for the user to identify the key). For protocol version 2 the
+ keytype is ``ssh-dss'' or ``ssh-rsa''.
+
+ Note that lines in this file are usually several hundred bytes long
+ (because of the size of the public key encoding) up to a limit of 8
+ kilobytes, which permits DSA keys up to 8 kilobits and RSA keys up to 16
kilobits. You don't want to type them in; instead, copy the
identity.pub, id_dsa.pub, or the id_rsa.pub file and edit it.
sshd enforces a minimum RSA key modulus size for protocol 1 and protocol
2 keys of 768 bits.
- The options (if present) consist of comma-separated option specifica-
- tions. No spaces are permitted, except within double quotes. The fol-
- lowing option specifications are supported (note that option keywords are
- case-insensitive):
+ The options (if present) consist of comma-separated option
+ specifications. No spaces are permitted, except within double quotes.
+ The following option specifications are supported (note that option
+ keywords are case-insensitive):
cert-authority
Specifies that the listed key is a certification authority (CA)
- that is trusted to validate signed certificates for user authen-
- tication.
+ that is trusted to validate signed certificates for user
+ authentication.
Certificates may encode access restrictions similar to these key
options. If both certificate restrictions and key options are
@@ -299,19 +302,19 @@ AUTHORIZED_KEYS FILE FORMAT
Specifies that the command is executed whenever this key is used
for authentication. The command supplied by the user (if any) is
ignored. The command is run on a pty if the client requests a
- pty; otherwise it is run without a tty. If an 8-bit clean chan-
- nel is required, one must not request a pty or should specify no-
- pty. A quote may be included in the command by quoting it with a
- backslash. This option might be useful to restrict certain pub-
- lic keys to perform just a specific operation. An example might
- be a key that permits remote backups but nothing else. Note that
- the client may specify TCP and/or X11 forwarding unless they are
- explicitly prohibited. The command originally supplied by the
- client is available in the SSH_ORIGINAL_COMMAND environment vari-
- able. Note that this option applies to shell, command or subsys-
- tem execution. Also note that this command may be superseded by
- either a sshd_config(5) ForceCommand directive or a command em-
- bedded in a certificate.
+ pty; otherwise it is run without a tty. If an 8-bit clean
+ channel is required, one must not request a pty or should specify
+ no-pty. A quote may be included in the command by quoting it
+ with a backslash. This option might be useful to restrict
+ certain public keys to perform just a specific operation. An
+ example might be a key that permits remote backups but nothing
+ else. Note that the client may specify TCP and/or X11 forwarding
+ unless they are explicitly prohibited. The command originally
+ supplied by the client is available in the SSH_ORIGINAL_COMMAND
+ environment variable. Note that this option applies to shell,
+ command or subsystem execution. Also note that this command may
+ be superseded by either a sshd_config(5) ForceCommand directive
+ or a command embedded in a certificate.
environment="NAME=value"
Specifies that the string is to be added to the environment when
@@ -327,9 +330,9 @@ AUTHORIZED_KEYS FILE FORMAT
present in the comma-separated list of patterns. See PATTERNS in
ssh_config(5) for more information on patterns.
- In addition to the wildcard matching that may be applied to host-
- names or addresses, a from stanza may match IP addresses using
- CIDR address/masklen notation.
+ In addition to the wildcard matching that may be applied to
+ hostnames or addresses, a from stanza may match IP addresses
+ using CIDR address/masklen notation.
The purpose of this option is to optionally increase security:
public key authentication by itself does not trust the network or
@@ -358,17 +361,25 @@ AUTHORIZED_KEYS FILE FORMAT
Any X11 forward requests by the client will return an error.
permitopen="host:port"
- Limit local ``ssh -L'' port forwarding such that it may only con-
- nect to the specified host and port. IPv6 addresses can be spec-
- ified with an alternative syntax: host/port. Multiple permitopen
- options may be applied separated by commas. No pattern matching
- is performed on the specified hostnames, they must be literal do-
- mains or addresses.
+ Limit local ``ssh -L'' port forwarding such that it may only
+ connect to the specified host and port. IPv6 addresses can be
+ specified by enclosing the address in square brackets. Multiple
+ permitopen options may be applied separated by commas. No
+ pattern matching is performed on the specified hostnames, they
+ must be literal domains or addresses.
+
+ principals="principals"
+ On a cert-authority line, specifies allowed principals for
+ certificate authentication as a comma-separated list. At least
+ one name from the list must appear in the certificate's list of
+ principals for the certificate to be accepted. This option is
+ ignored for keys that are not marked as trusted certificate
+ signers using the cert-authority option.
tunnel="n"
Force a tun(4) device on the server. Without this option, the
- next available device will be used if the client requests a tun-
- nel.
+ next available device will be used if the client requests a
+ tunnel.
An example authorized_keys file:
@@ -386,13 +397,13 @@ AUTHORIZED_KEYS FILE FORMAT
SSH_KNOWN_HOSTS FILE FORMAT
The /etc/ssh/ssh_known_hosts and ~/.ssh/known_hosts files contain host
public keys for all known hosts. The global file should be prepared by
- the administrator (optional), and the per-user file is maintained auto-
- matically: whenever the user connects from an unknown host, its key is
- added to the per-user file.
+ the administrator (optional), and the per-user file is maintained
+ automatically: whenever the user connects from an unknown host, its key
+ is added to the per-user file.
- Each line in these files contains the following fields: markers (option-
- al), hostnames, bits, exponent, modulus, comment. The fields are sepa-
- rated by spaces.
+ Each line in these files contains the following fields: markers
+ (optional), hostnames, bits, exponent, modulus, comment. The fields are
+ separated by spaces.
The marker is optional, but if it is present then it must be one of
``@cert-authority'', to indicate that the line contains a certification
@@ -400,20 +411,20 @@ SSH_KNOWN_HOSTS FILE FORMAT
on the line is revoked and must not ever be accepted. Only one marker
should be used on a key line.
- Hostnames is a comma-separated list of patterns (`*' and `?' act as wild-
- cards); each pattern in turn is matched against the canonical host name
- (when authenticating a client) or against the user-supplied name (when
- authenticating a server). A pattern may also be preceded by `!' to indi-
- cate negation: if the host name matches a negated pattern, it is not ac-
- cepted (by that line) even if it matched another pattern on the line. A
- hostname or address may optionally be enclosed within `[' and `]' brack-
- ets then followed by `:' and a non-standard port number.
+ Hostnames is a comma-separated list of patterns (`*' and `?' act as
+ wildcards); each pattern in turn is matched against the canonical host
+ name (when authenticating a client) or against the user-supplied name
+ (when authenticating a server). A pattern may also be preceded by `!' to
+ indicate negation: if the host name matches a negated pattern, it is not
+ accepted (by that line) even if it matched another pattern on the line.
+ A hostname or address may optionally be enclosed within `[' and `]'
+ brackets then followed by `:' and a non-standard port number.
Alternately, hostnames may be stored in a hashed form which hides host
names and addresses should the file's contents be disclosed. Hashed
- hostnames start with a `|' character. Only one hashed hostname may ap-
- pear on a single line and none of the above negation or wildcard opera-
- tors may be applied.
+ hostnames start with a `|' character. Only one hashed hostname may
+ appear on a single line and none of the above negation or wildcard
+ operators may be applied.
Bits, exponent, and modulus are taken directly from the RSA host key;
they can be obtained, for example, from /etc/ssh/ssh_host_key.pub. The
@@ -431,23 +442,24 @@ SSH_KNOWN_HOSTS FILE FORMAT
The known hosts file also provides a facility to mark keys as revoked,
for example when it is known that the associated private key has been
stolen. Revoked keys are specified by including the ``@revoked'' marker
- at the beginning of the key line, and are never accepted for authentica-
- tion or as certification authorities, but instead will produce a warning
- from ssh(1) when they are encountered.
+ at the beginning of the key line, and are never accepted for
+ authentication or as certification authorities, but instead will produce
+ a warning from ssh(1) when they are encountered.
- It is permissible (but not recommended) to have several lines or differ-
- ent host keys for the same names. This will inevitably happen when short
- forms of host names from different domains are put in the file. It is
- possible that the files contain conflicting information; authentication
- is accepted if valid information can be found from either file.
+ It is permissible (but not recommended) to have several lines or
+ different host keys for the same names. This will inevitably happen when
+ short forms of host names from different domains are put in the file. It
+ is possible that the files contain conflicting information;
+ authentication is accepted if valid information can be found from either
+ file.
Note that the lines in these files are typically hundreds of characters
long, and you definitely don't want to type in the host keys by hand.
Rather, generate them by a script, ssh-keyscan(1) or by taking
/etc/ssh/ssh_host_key.pub and adding the host names at the front.
ssh-keygen(1) also offers some basic automated editing for
- ~/.ssh/known_hosts including removing hosts matching a host name and con-
- verting all host names to their hashed representations.
+ ~/.ssh/known_hosts including removing hosts matching a host name and
+ converting all host names to their hashed representations.
An example ssh_known_hosts file:
@@ -465,18 +477,19 @@ SSH_KNOWN_HOSTS FILE FORMAT
FILES
~/.hushlogin
This file is used to suppress printing the last login time and
- /etc/motd, if PrintLastLog and PrintMotd, respectively, are en-
- abled. It does not suppress printing of the banner specified by
- Banner.
+ /etc/motd, if PrintLastLog and PrintMotd, respectively, are
+ enabled. It does not suppress printing of the banner specified
+ by Banner.
~/.rhosts
This file is used for host-based authentication (see ssh(1) for
more information). On some machines this file may need to be
- world-readable if the user's home directory is on an NFS parti-
- tion, because sshd reads it as root. Additionally, this file
- must be owned by the user, and must not have write permissions
- for anyone else. The recommended permission for most machines is
- read/write for the user, and not accessible by others.
+ world-readable if the user's home directory is on an NFS
+ partition, because sshd reads it as root. Additionally, this
+ file must be owned by the user, and must not have write
+ permissions for anyone else. The recommended permission for most
+ machines is read/write for the user, and not accessible by
+ others.
~/.shosts
This file is used in exactly the same way as .rhosts, but allows
@@ -484,11 +497,11 @@ FILES
rlogin/rsh.
~/.ssh/
- This directory is the default location for all user-specific con-
- figuration and authentication information. There is no general
- requirement to keep the entire contents of this directory secret,
- but the recommended permissions are read/write/execute for the
- user, and not accessible by others.
+ This directory is the default location for all user-specific
+ configuration and authentication information. There is no
+ general requirement to keep the entire contents of this directory
+ secret, but the recommended permissions are read/write/execute
+ for the user, and not accessible by others.
~/.ssh/authorized_keys
Lists the public keys (RSA/DSA) that can be used for logging in
@@ -499,8 +512,8 @@ FILES
If this file, the ~/.ssh directory, or the user's home directory
are writable by other users, then the file could be modified or
- replaced by unauthorized users. In this case, sshd will not al-
- low it to be used unless the StrictModes option has been set to
+ replaced by unauthorized users. In this case, sshd will not
+ allow it to be used unless the StrictModes option has been set to
``no''.
~/.ssh/environment
@@ -525,8 +538,8 @@ FILES
/etc/hosts.allow
/etc/hosts.deny
- Access controls that should be enforced by tcp-wrappers are de-
- fined here. Further details are described in hosts_access(5).
+ Access controls that should be enforced by tcp-wrappers are
+ defined here. Further details are described in hosts_access(5).
/etc/hosts.equiv
This file is for host-based authentication (see ssh(1)). It
@@ -546,8 +559,8 @@ FILES
world-readable.
/etc/shosts.equiv
- This file is used in exactly the same way as hosts.equiv, but al-
- lows host-based authentication without permitting login with
+ This file is used in exactly the same way as hosts.equiv, but
+ allows host-based authentication without permitting login with
rlogin/rsh.
/etc/ssh/ssh_host_key
@@ -571,13 +584,13 @@ FILES
/etc/ssh/ssh_known_hosts
Systemwide list of known host keys. This file should be prepared
by the system administrator to contain the public host keys of
- all machines in the organization. The format of this file is de-
- scribed above. This file should be writable only by root/the
+ all machines in the organization. The format of this file is
+ described above. This file should be writable only by root/the
owner and should be world-readable.
/etc/ssh/sshd_config
- Contains configuration data for sshd. The file format and con-
- figuration options are described in sshd_config(5).
+ Contains configuration data for sshd. The file format and
+ configuration options are described in sshd_config(5).
/etc/ssh/sshrc
Similar to ~/.ssh/rc, it can be used to specify machine-specific
@@ -594,8 +607,8 @@ FILES
Contains the process ID of the sshd listening for connections (if
there are several daemons running concurrently for different
ports, this contains the process ID of the one started last).
- The content of this file is not sensitive; it can be world-read-
- able.
+ The content of this file is not sensitive; it can be world-
+ readable.
SEE ALSO
scp(1), sftp(1), ssh(1), ssh-add(1), ssh-agent(1), ssh-keygen(1),
@@ -605,13 +618,13 @@ SEE ALSO
AUTHORS
OpenSSH is a derivative of the original and free ssh 1.2.12 release by
Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo
- de Raadt and Dug Song removed many bugs, re-added newer features and cre-
- ated OpenSSH. Markus Friedl contributed the support for SSH protocol
+ de Raadt and Dug Song removed many bugs, re-added newer features and
+ created OpenSSH. Markus Friedl contributed the support for SSH protocol
versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support
for privilege separation.
CAVEATS
- System security is not improved unless rshd, rlogind, and rexecd are dis-
- abled (thus completely disabling rlogin and rsh into the machine).
+ System security is not improved unless rshd, rlogind, and rexecd are
+ disabled (thus completely disabling rlogin and rsh into the machine).
-OpenBSD 4.7 March 5, 2010 10
+OpenBSD 4.8 August 4, 2010 OpenBSD 4.8
diff --git a/sshd.8 b/sshd.8
index 5f19660056b9..d3685b92b35d 100644
--- a/sshd.8
+++ b/sshd.8
@@ -34,8 +34,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: sshd.8,v 1.255 2010/03/05 06:50:35 jmc Exp $
-.Dd $Mdocdate: March 5 2010 $
+.\" $OpenBSD: sshd.8,v 1.257 2010/08/04 05:37:01 djm Exp $
+.Dd $Mdocdate: August 4 2010 $
.Dt SSHD 8
.Os
.Sh NAME
@@ -595,13 +595,23 @@ Limit local
.Li ``ssh -L''
port forwarding such that it may only connect to the specified host and
port.
-IPv6 addresses can be specified with an alternative syntax:
-.Ar host Ns / Ns Ar port .
+IPv6 addresses can be specified by enclosing the address in square brackets.
Multiple
.Cm permitopen
options may be applied separated by commas.
No pattern matching is performed on the specified hostnames,
they must be literal domains or addresses.
+.It Cm principals="principals"
+On a
+.Cm cert-authority
+line, specifies allowed principals for certificate authentication as a
+comma-separated list.
+At least one name from the list must appear in the certificate's
+list of principals for the certificate to be accepted.
+This option is ignored for keys that are not marked as trusted certificate
+signers using the
+.Cm cert-authority
+option.
.It Cm tunnel="n"
Force a
.Xr tun 4
diff --git a/sshd.c b/sshd.c
index bc0d2753fcf3..a7d3ee5c4164 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.374 2010/03/07 11:57:13 dtucker Exp $ */
+/* $OpenBSD: sshd.c,v 1.375 2010/04/16 01:47:26 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -744,6 +744,8 @@ list_hostkey_types(void)
if (key == NULL)
continue;
switch (key->type) {
+ case KEY_RSA_CERT_V00:
+ case KEY_DSA_CERT_V00:
case KEY_RSA_CERT:
case KEY_DSA_CERT:
if (buffer_len(&b) > 0)
@@ -767,10 +769,17 @@ get_hostkey_by_type(int type, int need_private)
Key *key;
for (i = 0; i < options.num_host_key_files; i++) {
- if (type == KEY_RSA_CERT || type == KEY_DSA_CERT)
+ switch (type) {
+ case KEY_RSA_CERT_V00:
+ case KEY_DSA_CERT_V00:
+ case KEY_RSA_CERT:
+ case KEY_DSA_CERT:
key = sensitive_data.host_certificates[i];
- else
+ break;
+ default:
key = sensitive_data.host_keys[i];
+ break;
+ }
if (key != NULL && key->type == type)
return need_private ?
sensitive_data.host_keys[i] : key;
diff --git a/sshd_config.0 b/sshd_config.0
index 94935c07f5f9..a49953851662 100644
--- a/sshd_config.0
+++ b/sshd_config.0
@@ -8,21 +8,21 @@ SYNOPSIS
DESCRIPTION
sshd(8) reads configuration data from /etc/ssh/sshd_config (or the file
- specified with -f on the command line). The file contains keyword-argu-
- ment pairs, one per line. Lines starting with `#' and empty lines are
- interpreted as comments. Arguments may optionally be enclosed in double
- quotes (") in order to represent arguments containing spaces.
+ specified with -f on the command line). The file contains keyword-
+ argument pairs, one per line. Lines starting with `#' and empty lines
+ are interpreted as comments. Arguments may optionally be enclosed in
+ double quotes (") in order to represent arguments containing spaces.
- The possible keywords and their meanings are as follows (note that key-
- words are case-insensitive and arguments are case-sensitive):
+ The possible keywords and their meanings are as follows (note that
+ keywords are case-insensitive and arguments are case-sensitive):
AcceptEnv
Specifies what environment variables sent by the client will be
copied into the session's environ(7). See SendEnv in
- ssh_config(5) for how to configure the client. Note that envi-
- ronment passing is only supported for protocol 2. Variables are
- specified by name, which may contain the wildcard characters `*'
- and `?'. Multiple environment variables may be separated by
+ ssh_config(5) for how to configure the client. Note that
+ environment passing is only supported for protocol 2. Variables
+ are specified by name, which may contain the wildcard characters
+ `*' and `?'. Multiple environment variables may be separated by
whitespace or spread across multiple AcceptEnv directives. Be
warned that some environment variables could be used to bypass
restricted user environments. For this reason, care should be
@@ -35,10 +35,10 @@ DESCRIPTION
(use IPv6 only). The default is ``any''.
AllowAgentForwarding
- Specifies whether ssh-agent(1) forwarding is permitted. The de-
- fault is ``yes''. Note that disabling agent forwarding does not
- improve security unless users are also denied shell access, as
- they can always install their own forwarders.
+ Specifies whether ssh-agent(1) forwarding is permitted. The
+ default is ``yes''. Note that disabling agent forwarding does
+ not improve security unless users are also denied shell access,
+ as they can always install their own forwarders.
AllowGroups
This keyword can be followed by a list of group name patterns,
@@ -54,17 +54,17 @@ DESCRIPTION
AllowTcpForwarding
Specifies whether TCP forwarding is permitted. The default is
- ``yes''. Note that disabling TCP forwarding does not improve se-
- curity unless users are also denied shell access, as they can al-
- ways install their own forwarders.
+ ``yes''. Note that disabling TCP forwarding does not improve
+ security unless users are also denied shell access, as they can
+ always install their own forwarders.
AllowUsers
This keyword can be followed by a list of user name patterns,
- separated by spaces. If specified, login is allowed only for us-
- er names that match one of the patterns. Only user names are
+ separated by spaces. If specified, login is allowed only for
+ user names that match one of the patterns. Only user names are
valid; a numerical user ID is not recognized. By default, login
- is allowed for all users. If the pattern takes the form US-
- ER@HOST then USER and HOST are separately checked, restricting
+ is allowed for all users. If the pattern takes the form
+ USER@HOST then USER and HOST are separately checked, restricting
logins to particular users from particular hosts. The allow/deny
directives are processed in the following order: DenyUsers,
AllowUsers, DenyGroups, and finally AllowGroups.
@@ -73,14 +73,42 @@ DESCRIPTION
AuthorizedKeysFile
Specifies the file that contains the public keys that can be used
- for user authentication. AuthorizedKeysFile may contain tokens
- of the form %T which are substituted during connection setup.
- The following tokens are defined: %% is replaced by a literal
- '%', %h is replaced by the home directory of the user being au-
- thenticated, and %u is replaced by the username of that user.
- After expansion, AuthorizedKeysFile is taken to be an absolute
- path or one relative to the user's home directory. The default
- is ``.ssh/authorized_keys''.
+ for user authentication. The format is described in the
+ AUTHORIZED_KEYS FILE FORMAT section of sshd(8).
+ AuthorizedKeysFile may contain tokens of the form %T which are
+ substituted during connection setup. The following tokens are
+ defined: %% is replaced by a literal '%', %h is replaced by the
+ home directory of the user being authenticated, and %u is
+ replaced by the username of that user. After expansion,
+ AuthorizedKeysFile is taken to be an absolute path or one
+ relative to the user's home directory. The default is
+ ``.ssh/authorized_keys''.
+
+ AuthorizedPrincipalsFile
+ Specifies a file that lists principal names that are accepted for
+ certificate authentication. When using certificates signed by a
+ key listed in TrustedUserCAKeys, this file lists names, one of
+ which must appear in the certificate for it to be accepted for
+ authentication. Names are listed one per line preceded by key
+ options (as described in AUTHORIZED_KEYS FILE FORMAT in sshd(8)).
+ Empty lines and comments starting with `#' are ignored.
+
+ AuthorizedPrincipalsFile may contain tokens of the form %T which
+ are substituted during connection setup. The following tokens
+ are defined: %% is replaced by a literal '%', %h is replaced by
+ the home directory of the user being authenticated, and %u is
+ replaced by the username of that user. After expansion,
+ AuthorizedPrincipalsFile is taken to be an absolute path or one
+ relative to the user's home directory.
+
+ The default is not to use a principals file - in this case, the
+ username of the user must appear in a certificate's principals
+ list for it to be accepted. Note that AuthorizedPrincipalsFile
+ is only used when authentication proceeds using a CA listed in
+ TrustedUserCAKeys and is not consulted for certification
+ authorities trusted via ~/.ssh/authorized_keys, though the
+ principals= key option offers a similar facility (see sshd(8) for
+ details).
Banner The contents of the specified file are sent to the remote user
before authentication is allowed. If the argument is ``none''
@@ -93,27 +121,27 @@ DESCRIPTION
login.conf(5)) The default is ``yes''.
ChrootDirectory
- Specifies the pathname of a directory to chroot(2) to after au-
- thentication. All components of the pathname must be root-owned
- directories that are not writable by any other user or group.
- After the chroot, sshd(8) changes the working directory to the
- user's home directory.
+ Specifies the pathname of a directory to chroot(2) to after
+ authentication. All components of the pathname must be root-
+ owned directories that are not writable by any other user or
+ group. After the chroot, sshd(8) changes the working directory
+ to the user's home directory.
The pathname may contain the following tokens that are expanded
at runtime once the connecting user has been authenticated: %% is
replaced by a literal '%', %h is replaced by the home directory
- of the user being authenticated, and %u is replaced by the user-
- name of that user.
-
- The ChrootDirectory must contain the necessary files and directo-
- ries to support the user's session. For an interactive session
- this requires at least a shell, typically sh(1), and basic /dev
- nodes such as null(4), zero(4), stdin(4), stdout(4), stderr(4),
- arandom(4) and tty(4) devices. For file transfer sessions using
- ``sftp'', no additional configuration of the environment is nec-
- essary if the in-process sftp server is used, though sessions
- which use logging do require /dev/log inside the chroot directory
- (see sftp-server(8) for details).
+ of the user being authenticated, and %u is replaced by the
+ username of that user.
+
+ The ChrootDirectory must contain the necessary files and
+ directories to support the user's session. For an interactive
+ session this requires at least a shell, typically sh(1), and
+ basic /dev nodes such as null(4), zero(4), stdin(4), stdout(4),
+ stderr(4), arandom(4) and tty(4) devices. For file transfer
+ sessions using ``sftp'', no additional configuration of the
+ environment is necessary if the in-process sftp server is used,
+ though sessions which use logging do require /dev/log inside the
+ chroot directory (see sftp-server(8) for details).
The default is not to chroot(2).
@@ -132,28 +160,28 @@ DESCRIPTION
ClientAliveCountMax
Sets the number of client alive messages (see below) which may be
sent without sshd(8) receiving any messages back from the client.
- If this threshold is reached while client alive messages are be-
- ing sent, sshd will disconnect the client, terminating the ses-
- sion. It is important to note that the use of client alive mes-
- sages is very different from TCPKeepAlive (below). The client
- alive messages are sent through the encrypted channel and there-
- fore will not be spoofable. The TCP keepalive option enabled by
- TCPKeepAlive is spoofable. The client alive mechanism is valu-
- able when the client or server depend on knowing when a connec-
- tion has become inactive.
+ If this threshold is reached while client alive messages are
+ being sent, sshd will disconnect the client, terminating the
+ session. It is important to note that the use of client alive
+ messages is very different from TCPKeepAlive (below). The client
+ alive messages are sent through the encrypted channel and
+ therefore will not be spoofable. The TCP keepalive option
+ enabled by TCPKeepAlive is spoofable. The client alive mechanism
+ is valuable when the client or server depend on knowing when a
+ connection has become inactive.
The default value is 3. If ClientAliveInterval (see below) is
- set to 15, and ClientAliveCountMax is left at the default, unre-
- sponsive SSH clients will be disconnected after approximately 45
- seconds. This option applies to protocol version 2 only.
+ set to 15, and ClientAliveCountMax is left at the default,
+ unresponsive SSH clients will be disconnected after approximately
+ 45 seconds. This option applies to protocol version 2 only.
ClientAliveInterval
Sets a timeout interval in seconds after which if no data has
been received from the client, sshd(8) will send a message
through the encrypted channel to request a response from the
client. The default is 0, indicating that these messages will
- not be sent to the client. This option applies to protocol ver-
- sion 2 only.
+ not be sent to the client. This option applies to protocol
+ version 2 only.
Compression
Specifies whether compression is allowed, or delayed until the
@@ -164,9 +192,9 @@ DESCRIPTION
This keyword can be followed by a list of group name patterns,
separated by spaces. Login is disallowed for users whose primary
group or supplementary group list matches one of the patterns.
- Only group names are valid; a numerical group ID is not recog-
- nized. By default, login is allowed for all groups. The al-
- low/deny directives are processed in the following order:
+ Only group names are valid; a numerical group ID is not
+ recognized. By default, login is allowed for all groups. The
+ allow/deny directives are processed in the following order:
DenyUsers, AllowUsers, DenyGroups, and finally AllowGroups.
See PATTERNS in ssh_config(5) for more information on patterns.
@@ -174,20 +202,20 @@ DESCRIPTION
DenyUsers
This keyword can be followed by a list of user name patterns,
separated by spaces. Login is disallowed for user names that
- match one of the patterns. Only user names are valid; a numeri-
- cal user ID is not recognized. By default, login is allowed for
- all users. If the pattern takes the form USER@HOST then USER and
- HOST are separately checked, restricting logins to particular
- users from particular hosts. The allow/deny directives are pro-
- cessed in the following order: DenyUsers, AllowUsers, DenyGroups,
- and finally AllowGroups.
+ match one of the patterns. Only user names are valid; a
+ numerical user ID is not recognized. By default, login is
+ allowed for all users. If the pattern takes the form USER@HOST
+ then USER and HOST are separately checked, restricting logins to
+ particular users from particular hosts. The allow/deny
+ directives are processed in the following order: DenyUsers,
+ AllowUsers, DenyGroups, and finally AllowGroups.
See PATTERNS in ssh_config(5) for more information on patterns.
ForceCommand
Forces the execution of the command specified by ForceCommand,
- ignoring any command supplied by the client and ~/.ssh/rc if pre-
- sent. The command is invoked by using the user's login shell
+ ignoring any command supplied by the client and ~/.ssh/rc if
+ present. The command is invoked by using the user's login shell
with the -c option. This applies to shell, command, or subsystem
execution. It is most useful inside a Match block. The command
originally supplied by the client is available in the
@@ -202,10 +230,10 @@ DESCRIPTION
forwardings to the loopback address. This prevents other remote
hosts from connecting to forwarded ports. GatewayPorts can be
used to specify that sshd should allow remote port forwardings to
- bind to non-loopback addresses, thus allowing other hosts to con-
- nect. The argument may be ``no'' to force remote port forward-
- ings to be available to the local host only, ``yes'' to force re-
- mote port forwardings to bind to the wildcard address, or
+ bind to non-loopback addresses, thus allowing other hosts to
+ connect. The argument may be ``no'' to force remote port
+ forwardings to be available to the local host only, ``yes'' to
+ force remote port forwardings to bind to the wildcard address, or
``clientspecified'' to allow the client to select the address to
which the forwarding is bound. The default is ``no''.
@@ -220,15 +248,15 @@ DESCRIPTION
applies to protocol version 2 only.
HostbasedAuthentication
- Specifies whether rhosts or /etc/hosts.equiv authentication to-
- gether with successful public key client host authentication is
+ Specifies whether rhosts or /etc/hosts.equiv authentication
+ together with successful public key client host authentication is
allowed (host-based authentication). This option is similar to
RhostsRSAAuthentication and applies to protocol version 2 only.
The default is ``no''.
HostbasedUsesNameFromPacketOnly
- Specifies whether or not the server will attempt to perform a re-
- verse name lookup when matching the name in the ~/.shosts,
+ Specifies whether or not the server will attempt to perform a
+ reverse name lookup when matching the name in the ~/.shosts,
~/.rhosts, and /etc/hosts.equiv files during
HostbasedAuthentication. A setting of ``yes'' means that sshd(8)
uses the name supplied by the client rather than attempting to
@@ -236,17 +264,17 @@ DESCRIPTION
``no''.
HostCertificate
- Specifies a file containing a public host certificate. The cer-
- tificate's public key must match a private host key already spec-
- ified by HostKey. The default behaviour of sshd(8) is not to
+ Specifies a file containing a public host certificate. The
+ certificate's public key must match a private host key already
+ specified by HostKey. The default behaviour of sshd(8) is not to
load any certificates.
HostKey
Specifies a file containing a private host key used by SSH. The
default is /etc/ssh/ssh_host_key for protocol version 1, and
- /etc/ssh/ssh_host_rsa_key and /etc/ssh/ssh_host_dsa_key for pro-
- tocol version 2. Note that sshd(8) will refuse to use a file if
- it is group/world-accessible. It is possible to have multiple
+ /etc/ssh/ssh_host_rsa_key and /etc/ssh/ssh_host_dsa_key for
+ protocol version 2. Note that sshd(8) will refuse to use a file
+ if it is group/world-accessible. It is possible to have multiple
host key files. ``rsa1'' keys are used for version 1 and ``dsa''
or ``rsa'' are used for version 2 of the SSH protocol.
@@ -254,8 +282,8 @@ DESCRIPTION
Specifies that .rhosts and .shosts files will not be used in
RhostsRSAAuthentication or HostbasedAuthentication.
- /etc/hosts.equiv and /etc/shosts.equiv are still used. The de-
- fault is ``yes''.
+ /etc/hosts.equiv and /etc/shosts.equiv are still used. The
+ default is ``yes''.
IgnoreUserKnownHosts
Specifies whether sshd(8) should ignore the user's
@@ -275,9 +303,9 @@ DESCRIPTION
The default is ``no''.
KerberosOrLocalPasswd
- If password authentication through Kerberos fails then the pass-
- word will be validated via any additional local mechanism such as
- /etc/passwd. The default is ``yes''.
+ If password authentication through Kerberos fails then the
+ password will be validated via any additional local mechanism
+ such as /etc/passwd. The default is ``yes''.
KerberosTicketCleanup
Specifies whether to automatically destroy the user's ticket
@@ -286,17 +314,17 @@ DESCRIPTION
KeyRegenerationInterval
In protocol version 1, the ephemeral server key is automatically
regenerated after this many seconds (if it has been used). The
- purpose of regeneration is to prevent decrypting captured ses-
- sions by later breaking into the machine and stealing the keys.
- The key is never stored anywhere. If the value is 0, the key is
- never regenerated. The default is 3600 (seconds).
+ purpose of regeneration is to prevent decrypting captured
+ sessions by later breaking into the machine and stealing the
+ keys. The key is never stored anywhere. If the value is 0, the
+ key is never regenerated. The default is 3600 (seconds).
ListenAddress
- Specifies the local addresses sshd(8) should listen on. The fol-
- lowing forms may be used:
+ Specifies the local addresses sshd(8) should listen on. The
+ following forms may be used:
- ListenAddress host|IPv4_addr|IPv6_addr
- ListenAddress host|IPv4_addr:port
+ ListenAddress host | IPv4_addr | IPv6_addr
+ ListenAddress host | IPv4_addr:port
ListenAddress [host|IPv6_addr]:port
If port is not specified, sshd will listen on the address and all
@@ -306,9 +334,9 @@ DESCRIPTION
port qualified addresses.
LoginGraceTime
- The server disconnects after this time if the user has not suc-
- cessfully logged in. If the value is 0, there is no time limit.
- The default is 120 seconds.
+ The server disconnects after this time if the user has not
+ successfully logged in. If the value is 0, there is no time
+ limit. The default is 120 seconds.
LogLevel
Gives the verbosity level that is used when logging messages from
@@ -318,18 +346,18 @@ DESCRIPTION
higher levels of debugging output. Logging with a DEBUG level
violates the privacy of users and is not recommended.
- MACs Specifies the available MAC (message authentication code) algo-
- rithms. The MAC algorithm is used in protocol version 2 for data
- integrity protection. Multiple algorithms must be comma-separat-
- ed. The default is:
+ MACs Specifies the available MAC (message authentication code)
+ algorithms. The MAC algorithm is used in protocol version 2 for
+ data integrity protection. Multiple algorithms must be comma-
+ separated. The default is:
hmac-md5,hmac-sha1,umac-64@openssh.com,
hmac-ripemd160,hmac-sha1-96,hmac-md5-96
Match Introduces a conditional block. If all of the criteria on the
Match line are satisfied, the keywords on the following lines
- override those set in the global section of the config file, un-
- til either another Match line or the end of the file.
+ override those set in the global section of the config file,
+ until either another Match line or the end of the file.
The arguments to Match are one or more criteria-pattern pairs.
The available criteria are User, Group, Host, and Address. The
@@ -337,8 +365,8 @@ DESCRIPTION
lists and may use the wildcard and negation operators described
in the PATTERNS section of ssh_config(5).
- The patterns in an Address criteria may additionally contain ad-
- dresses to match in CIDR address/masklen format, e.g.
+ The patterns in an Address criteria may additionally contain
+ addresses to match in CIDR address/masklen format, e.g.
``192.0.2.0/24'' or ``3ffe:ffff::/32''. Note that the mask
length provided must be consistent with the address - it is an
error to specify a mask length that is too long for the address
@@ -347,13 +375,15 @@ DESCRIPTION
Only a subset of keywords may be used on the lines following a
Match keyword. Available keywords are AllowAgentForwarding,
- AllowTcpForwarding, Banner, ChrootDirectory, ForceCommand,
- GatewayPorts, GSSAPIAuthentication, HostbasedAuthentication,
- KbdInteractiveAuthentication, KerberosAuthentication,
- MaxAuthTries, MaxSessions, PasswordAuthentication,
- PermitEmptyPasswords, PermitOpen, PermitRootLogin,
- PubkeyAuthentication, RhostsRSAAuthentication, RSAAuthentication,
- X11DisplayOffset, X11Forwarding and X11UseLocalHost.
+ AllowTcpForwarding, AuthorizedKeysFile, AuthorizedPrincipalsFile,
+ Banner, ChrootDirectory, ForceCommand, GatewayPorts,
+ GSSAPIAuthentication, HostbasedAuthentication,
+ HostbasedUsesNameFromPacketOnly, KbdInteractiveAuthentication,
+ KerberosAuthentication, MaxAuthTries, MaxSessions,
+ PasswordAuthentication, PermitEmptyPasswords, PermitOpen,
+ PermitRootLogin, PermitTunnel, PubkeyAuthentication,
+ RhostsRSAAuthentication, RSAAuthentication, X11DisplayOffset,
+ X11Forwarding and X11UseLocalHost.
MaxAuthTries
Specifies the maximum number of authentication attempts permitted
@@ -361,26 +391,26 @@ DESCRIPTION
value, additional failures are logged. The default is 6.
MaxSessions
- Specifies the maximum number of open sessions permitted per net-
- work connection. The default is 10.
+ Specifies the maximum number of open sessions permitted per
+ network connection. The default is 10.
MaxStartups
- Specifies the maximum number of concurrent unauthenticated con-
- nections to the SSH daemon. Additional connections will be
- dropped until authentication succeeds or the LoginGraceTime ex-
- pires for a connection. The default is 10.
+ Specifies the maximum number of concurrent unauthenticated
+ connections to the SSH daemon. Additional connections will be
+ dropped until authentication succeeds or the LoginGraceTime
+ expires for a connection. The default is 10.
Alternatively, random early drop can be enabled by specifying the
three colon separated values ``start:rate:full'' (e.g.
"10:30:60"). sshd(8) will refuse connection attempts with a
probability of ``rate/100'' (30%) if there are currently
- ``start'' (10) unauthenticated connections. The probability in-
- creases linearly and all connection attempts are refused if the
+ ``start'' (10) unauthenticated connections. The probability
+ increases linearly and all connection attempts are refused if the
number of unauthenticated connections reaches ``full'' (60).
PasswordAuthentication
- Specifies whether password authentication is allowed. The de-
- fault is ``yes''.
+ Specifies whether password authentication is allowed. The
+ default is ``yes''.
PermitEmptyPasswords
When password authentication is allowed, it specifies whether the
@@ -388,17 +418,17 @@ DESCRIPTION
default is ``no''.
PermitOpen
- Specifies the destinations to which TCP port forwarding is per-
- mitted. The forwarding specification must be one of the follow-
- ing forms:
+ Specifies the destinations to which TCP port forwarding is
+ permitted. The forwarding specification must be one of the
+ following forms:
PermitOpen host:port
PermitOpen IPv4_addr:port
- PermitOpen [IPv6_addr]:port
+ PermitOpen [ IPv6_addr ]:port
Multiple forwards may be specified by separating them with
- whitespace. An argument of ``any'' can be used to remove all re-
- strictions and permit any forwarding requests. By default all
+ whitespace. An argument of ``any'' can be used to remove all
+ restrictions and permit any forwarding requests. By default all
port forwarding requests are permitted.
PermitRootLogin
@@ -406,8 +436,8 @@ DESCRIPTION
must be ``yes'', ``without-password'', ``forced-commands-only'',
or ``no''. The default is ``yes''.
- If this option is set to ``without-password'', password authenti-
- cation is disabled for root.
+ If this option is set to ``without-password'', password
+ authentication is disabled for root.
If this option is set to ``forced-commands-only'', root login
with public key authentication will be allowed, but only if the
@@ -418,21 +448,21 @@ DESCRIPTION
If this option is set to ``no'', root is not allowed to log in.
PermitTunnel
- Specifies whether tun(4) device forwarding is allowed. The argu-
- ment must be ``yes'', ``point-to-point'' (layer 3), ``ethernet''
- (layer 2), or ``no''. Specifying ``yes'' permits both ``point-
- to-point'' and ``ethernet''. The default is ``no''.
+ Specifies whether tun(4) device forwarding is allowed. The
+ argument must be ``yes'', ``point-to-point'' (layer 3),
+ ``ethernet'' (layer 2), or ``no''. Specifying ``yes'' permits
+ both ``point-to-point'' and ``ethernet''. The default is ``no''.
PermitUserEnvironment
Specifies whether ~/.ssh/environment and environment= options in
~/.ssh/authorized_keys are processed by sshd(8). The default is
- ``no''. Enabling environment processing may enable users to by-
- pass access restrictions in some configurations using mechanisms
- such as LD_PRELOAD.
+ ``no''. Enabling environment processing may enable users to
+ bypass access restrictions in some configurations using
+ mechanisms such as LD_PRELOAD.
PidFile
- Specifies the file that contains the process ID of the SSH dae-
- mon. The default is /var/run/sshd.pid.
+ Specifies the file that contains the process ID of the SSH
+ daemon. The default is /var/run/sshd.pid.
Port Specifies the port number that sshd(8) listens on. The default
is 22. Multiple options of this type are permitted. See also
@@ -450,16 +480,16 @@ DESCRIPTION
Protocol
Specifies the protocol versions sshd(8) supports. The possible
- values are `1' and `2'. Multiple versions must be comma-separat-
- ed. The default is `2'. Note that the order of the protocol
- list does not indicate preference, because the client selects
- among multiple protocol versions offered by the server. Specify-
- ing ``2,1'' is identical to ``1,2''.
+ values are `1' and `2'. Multiple versions must be comma-
+ separated. The default is `2'. Note that the order of the
+ protocol list does not indicate preference, because the client
+ selects among multiple protocol versions offered by the server.
+ Specifying ``2,1'' is identical to ``1,2''.
PubkeyAuthentication
- Specifies whether public key authentication is allowed. The de-
- fault is ``yes''. Note that this option applies to protocol ver-
- sion 2 only.
+ Specifies whether public key authentication is allowed. The
+ default is ``yes''. Note that this option applies to protocol
+ version 2 only.
RevokedKeys
Specifies a list of revoked public keys. Keys listed in this
@@ -468,15 +498,15 @@ DESCRIPTION
refused for all users.
RhostsRSAAuthentication
- Specifies whether rhosts or /etc/hosts.equiv authentication to-
- gether with successful RSA host authentication is allowed. The
- default is ``no''. This option applies to protocol version 1 on-
- ly.
+ Specifies whether rhosts or /etc/hosts.equiv authentication
+ together with successful RSA host authentication is allowed. The
+ default is ``no''. This option applies to protocol version 1
+ only.
RSAAuthentication
- Specifies whether pure RSA authentication is allowed. The de-
- fault is ``yes''. This option applies to protocol version 1 on-
- ly.
+ Specifies whether pure RSA authentication is allowed. The
+ default is ``yes''. This option applies to protocol version 1
+ only.
ServerKeyBits
Defines the number of bits in the ephemeral protocol version 1
@@ -502,24 +532,24 @@ DESCRIPTION
``sftp'' server. This may simplify configurations using
ChrootDirectory to force a different filesystem root on clients.
- By default no subsystems are defined. Note that this option ap-
- plies to protocol version 2 only.
+ By default no subsystems are defined. Note that this option
+ applies to protocol version 2 only.
SyslogFacility
Gives the facility code that is used when logging messages from
sshd(8). The possible values are: DAEMON, USER, AUTH, LOCAL0,
- LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The de-
- fault is AUTH.
+ LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The
+ default is AUTH.
TCPKeepAlive
Specifies whether the system should send TCP keepalive messages
to the other side. If they are sent, death of the connection or
crash of one of the machines will be properly noticed. However,
- this means that connections will die if the route is down tem-
- porarily, and some people find it annoying. On the other hand,
- if TCP keepalives are not sent, sessions may hang indefinitely on
- the server, leaving ``ghost'' users and consuming server re-
- sources.
+ this means that connections will die if the route is down
+ temporarily, and some people find it annoying. On the other
+ hand, if TCP keepalives are not sent, sessions may hang
+ indefinitely on the server, leaving ``ghost'' users and consuming
+ server resources.
The default is ``yes'' (to send TCP keepalive messages), and the
server will notice if the network goes down or the client host
@@ -529,34 +559,34 @@ DESCRIPTION
``no''.
TrustedUserCAKeys
- Specifies a file containing public keys of certificate authori-
- ties that are trusted to sign user certificates for authentica-
- tion. Keys are listed one per line; empty lines and comments
- starting with `#' are allowed. If a certificate is presented for
- authentication and has its signing CA key listed in this file,
- then it may be used for authentication for any user listed in the
- certificate's principals list. Note that certificates that lack
- a list of principals will not be permitted for authentication us-
- ing TrustedUserCAKeys. For more details on certificates, see the
- CERTIFICATES section in ssh-keygen(1).
+ Specifies a file containing public keys of certificate
+ authorities that are trusted to sign user certificates for
+ authentication. Keys are listed one per line; empty lines and
+ comments starting with `#' are allowed. If a certificate is
+ presented for authentication and has its signing CA key listed in
+ this file, then it may be used for authentication for any user
+ listed in the certificate's principals list. Note that
+ certificates that lack a list of principals will not be permitted
+ for authentication using TrustedUserCAKeys. For more details on
+ certificates, see the CERTIFICATES section in ssh-keygen(1).
UseDNS Specifies whether sshd(8) should look up the remote host name and
check that the resolved host name for the remote IP address maps
back to the very same IP address. The default is ``yes''.
UseLogin
- Specifies whether login(1) is used for interactive login ses-
- sions. The default is ``no''. Note that login(1) is never used
- for remote command execution. Note also, that if this is en-
- abled, X11Forwarding will be disabled because login(1) does not
+ Specifies whether login(1) is used for interactive login
+ sessions. The default is ``no''. Note that login(1) is never
+ used for remote command execution. Note also, that if this is
+ enabled, X11Forwarding will be disabled because login(1) does not
know how to handle xauth(1) cookies. If UsePrivilegeSeparation
is specified, it will be disabled after authentication.
UsePAM Enables the Pluggable Authentication Module interface. If set to
``yes'' this will enable PAM authentication using
- ChallengeResponseAuthentication and PasswordAuthentication in ad-
- dition to PAM account and session module processing for all au-
- thentication types.
+ ChallengeResponseAuthentication and PasswordAuthentication in
+ addition to PAM account and session module processing for all
+ authentication types.
Because PAM challenge-response authentication usually serves an
equivalent role to password authentication, you should disable
@@ -566,12 +596,12 @@ DESCRIPTION
non-root user. The default is ``no''.
UsePrivilegeSeparation
- Specifies whether sshd(8) separates privileges by creating an un-
- privileged child process to deal with incoming network traffic.
+ Specifies whether sshd(8) separates privileges by creating an
+ unprivileged child process to deal with incoming network traffic.
After successful authentication, another process will be created
that has the privilege of the authenticated user. The goal of
- privilege separation is to prevent privilege escalation by con-
- taining any corruption within the unprivileged processes. The
+ privilege separation is to prevent privilege escalation by
+ containing any corruption within the unprivileged processes. The
default is ``yes''.
X11DisplayOffset
@@ -586,15 +616,16 @@ DESCRIPTION
When X11 forwarding is enabled, there may be additional exposure
to the server and to client displays if the sshd(8) proxy display
is configured to listen on the wildcard address (see
- X11UseLocalhost below), though this is not the default. Addi-
- tionally, the authentication spoofing and authentication data
- verification and substitution occur on the client side. The se-
- curity risk of using X11 forwarding is that the client's X11 dis-
- play server may be exposed to attack when the SSH client requests
- forwarding (see the warnings for ForwardX11 in ssh_config(5)). A
- system administrator may have a stance in which they want to pro-
- tect clients that may expose themselves to attack by unwittingly
- requesting X11 forwarding, which can warrant a ``no'' setting.
+ X11UseLocalhost below), though this is not the default.
+ Additionally, the authentication spoofing and authentication data
+ verification and substitution occur on the client side. The
+ security risk of using X11 forwarding is that the client's X11
+ display server may be exposed to attack when the SSH client
+ requests forwarding (see the warnings for ForwardX11 in
+ ssh_config(5)). A system administrator may have a stance in
+ which they want to protect clients that may expose themselves to
+ attack by unwittingly requesting X11 forwarding, which can
+ warrant a ``no'' setting.
Note that disabling X11 forwarding does not prevent users from
forwarding X11 traffic, as users can always install their own
@@ -609,19 +640,19 @@ DESCRIPTION
``localhost''. This prevents remote hosts from connecting to the
proxy display. However, some older X11 clients may not function
with this configuration. X11UseLocalhost may be set to ``no'' to
- specify that the forwarding server should be bound to the wild-
- card address. The argument must be ``yes'' or ``no''. The de-
- fault is ``yes''.
+ specify that the forwarding server should be bound to the
+ wildcard address. The argument must be ``yes'' or ``no''. The
+ default is ``yes''.
XAuthLocation
Specifies the full pathname of the xauth(1) program. The default
is /usr/X11R6/bin/xauth.
TIME FORMATS
- sshd(8) command-line arguments and configuration file options that speci-
- fy time may be expressed using a sequence of the form: time[qualifier],
- where time is a positive integer value and qualifier is one of the fol-
- lowing:
+ sshd(8) command-line arguments and configuration file options that
+ specify time may be expressed using a sequence of the form: time
+ [qualifier], where time is a positive integer value and qualifier is one
+ of the following:
<none> seconds
s | S seconds
@@ -642,8 +673,8 @@ TIME FORMATS
FILES
/etc/ssh/sshd_config
Contains configuration data for sshd(8). This file should be
- writable by root only, but it is recommended (though not neces-
- sary) that it be world-readable.
+ writable by root only, but it is recommended (though not
+ necessary) that it be world-readable.
SEE ALSO
sshd(8)
@@ -651,9 +682,9 @@ SEE ALSO
AUTHORS
OpenSSH is a derivative of the original and free ssh 1.2.12 release by
Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo
- de Raadt and Dug Song removed many bugs, re-added newer features and cre-
- ated OpenSSH. Markus Friedl contributed the support for SSH protocol
+ de Raadt and Dug Song removed many bugs, re-added newer features and
+ created OpenSSH. Markus Friedl contributed the support for SSH protocol
versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support
for privilege separation.
-OpenBSD 4.7 March 4, 2010 10
+OpenBSD 4.8 June 30, 2010 OpenBSD 4.8
diff --git a/sshd_config.5 b/sshd_config.5
index 2f5410281184..596a728f80bd 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -34,8 +34,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: sshd_config.5,v 1.120 2010/03/04 23:17:25 djm Exp $
-.Dd $Mdocdate: March 4 2010 $
+.\" $OpenBSD: sshd_config.5,v 1.125 2010/06/30 07:28:34 jmc Exp $
+.Dd $Mdocdate: June 30 2010 $
.Dt SSHD_CONFIG 5
.Os
.Sh NAME
@@ -155,6 +155,10 @@ for more information on patterns.
.It Cm AuthorizedKeysFile
Specifies the file that contains the public keys that can be used
for user authentication.
+The format is described in the
+.Sx AUTHORIZED_KEYS FILE FORMAT
+section of
+.Xr sshd 8 .
.Cm AuthorizedKeysFile
may contain tokens of the form %T which are substituted during connection
setup.
@@ -167,6 +171,47 @@ is taken to be an absolute path or one relative to the user's home
directory.
The default is
.Dq .ssh/authorized_keys .
+.It Cm AuthorizedPrincipalsFile
+Specifies a file that lists principal names that are accepted for
+certificate authentication.
+When using certificates signed by a key listed in
+.Cm TrustedUserCAKeys ,
+this file lists names, one of which must appear in the certificate for it
+to be accepted for authentication.
+Names are listed one per line preceded by key options (as described
+in
+.Sx AUTHORIZED_KEYS FILE FORMAT
+in
+.Xr sshd 8 ) .
+Empty lines and comments starting with
+.Ql #
+are ignored.
+.Pp
+.Cm AuthorizedPrincipalsFile
+may contain tokens of the form %T which are substituted during connection
+setup.
+The following tokens are defined: %% is replaced by a literal '%',
+%h is replaced by the home directory of the user being authenticated, and
+%u is replaced by the username of that user.
+After expansion,
+.Cm AuthorizedPrincipalsFile
+is taken to be an absolute path or one relative to the user's home
+directory.
+.Pp
+The default is not to use a principals file \(en in this case, the username
+of the user must appear in a certificate's principals list for it to be
+accepted.
+Note that
+.Cm AuthorizedPrincipalsFile
+is only used when authentication proceeds using a CA listed in
+.Cm TrustedUserCAKeys
+and is not consulted for certification authorities trusted via
+.Pa ~/.ssh/authorized_keys ,
+though the
+.Cm principals=
+key option offers a similar facility (see
+.Xr sshd 8
+for details).
.It Cm Banner
The contents of the specified file are sent to the remote user before
authentication is allowed.
@@ -608,12 +653,15 @@ keyword.
Available keywords are
.Cm AllowAgentForwarding ,
.Cm AllowTcpForwarding ,
+.Cm AuthorizedKeysFile ,
+.Cm AuthorizedPrincipalsFile ,
.Cm Banner ,
.Cm ChrootDirectory ,
.Cm ForceCommand ,
.Cm GatewayPorts ,
.Cm GSSAPIAuthentication ,
.Cm HostbasedAuthentication ,
+.Cm HostbasedUsesNameFromPacketOnly ,
.Cm KbdInteractiveAuthentication ,
.Cm KerberosAuthentication ,
.Cm MaxAuthTries ,
@@ -622,6 +670,7 @@ Available keywords are
.Cm PermitEmptyPasswords ,
.Cm PermitOpen ,
.Cm PermitRootLogin ,
+.Cm PermitTunnel ,
.Cm PubkeyAuthentication ,
.Cm RhostsRSAAuthentication ,
.Cm RSAAuthentication ,
diff --git a/version.h b/version.h
index 5d2b0b741f02..67d78dcc3054 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
-/* $OpenBSD: version.h,v 1.58 2010/03/16 16:36:49 djm Exp $ */
+/* $OpenBSD: version.h,v 1.59 2010/08/08 16:26:42 djm Exp $ */
-#define SSH_VERSION "OpenSSH_5.5"
+#define SSH_VERSION "OpenSSH_5.6"
#define SSH_PORTABLE "p1"
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE