Upgrade to OpenSSH 5.6p1.
This commit is contained in:
commit
e2f6069c09
@ -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.
|
||||
|
@ -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.
|
||||
|
||||
permit-X11-forwarding empty Flag indicating that X11 forwarding
|
||||
should be permitted. X11 forwarding will
|
||||
be refused if this constraint 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.
|
||||
|
||||
permit-port-forwarding empty Flag indicating that port-forwarding
|
||||
should be allowed. If this constraint 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
|
||||
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
|
||||
If this option is not present then
|
||||
certificates may be presented from any
|
||||
source address.
|
||||
|
||||
$OpenBSD: PROTOCOL.certkeys,v 1.3 2010/03/03 22:50:40 djm Exp $
|
||||
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 option is absent.
|
||||
|
||||
permit-agent-forwarding empty Flag indicating that agent forwarding
|
||||
should be allowed. Agent forwarding
|
||||
must not be permitted unless this
|
||||
option is present.
|
||||
|
||||
permit-port-forwarding empty Flag indicating that port-forwarding
|
||||
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 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 option is not present.
|
||||
|
||||
$OpenBSD: PROTOCOL.certkeys,v 1.7 2010/08/04 05:40:39 djm Exp $
|
||||
|
@ -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 $
|
||||
|
@ -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 $
|
||||
|
@ -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 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
|
||||
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 (!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;
|
||||
}
|
||||
if (cert_forced_command != NULL) {
|
||||
error("Certificate has multiple "
|
||||
"force-command constraints");
|
||||
xfree(command);
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
*
|
||||
@ -144,7 +144,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",
|
||||
@ -367,6 +367,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,
|
||||
@ -378,7 +386,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) {
|
||||
@ -390,6 +398,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,
|
||||
@ -478,21 +488,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;
|
||||
}
|
||||
@ -502,8 +509,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;
|
||||
}
|
||||
@ -516,12 +523,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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 @@ userauth_pubkey(Authctxt *authctxt)
|
||||
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;
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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 *);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 *,
|
||||
|
@ -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);
|
||||
|
@ -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 *);
|
||||
|
@ -904,6 +904,9 @@
|
||||
/* Define to 1 if you have the `strnvis' function. */
|
||||
/* #undef HAVE_STRNVIS */
|
||||
|
||||
/* Define to 1 if you have the `strptime' function. */
|
||||
#define HAVE_STRPTIME 1
|
||||
|
||||
/* Define to 1 if you have the `strsep' function. */
|
||||
#define HAVE_STRSEP 1
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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__);
|
||||
|
@ -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," \
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
401
crypto/openssh/openbsd-compat/strptime.c
Normal file
401
crypto/openssh/openbsd-compat/strptime.c
Normal file
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
@ -113,8 +113,8 @@ __RCSID("$FreeBSD$");
|
||||
|
||||
typedef enum {
|
||||
oBadOption,
|
||||
oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
|
||||
oExitOnForwardFailure,
|
||||
oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
|
||||
oGatewayPorts, oExitOnForwardFailure,
|
||||
oPasswordAuthentication, oRSAAuthentication,
|
||||
oChallengeResponseAuthentication, oXAuthLocation,
|
||||
oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
|
||||
@ -131,7 +131,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,
|
||||
oVersionAddendum,
|
||||
@ -147,6 +148,7 @@ static struct {
|
||||
{ "forwardagent", oForwardAgent },
|
||||
{ "forwardx11", oForwardX11 },
|
||||
{ "forwardx11trusted", oForwardX11Trusted },
|
||||
{ "forwardx11timeout", oForwardX11Timeout },
|
||||
{ "exitonforwardfailure", oExitOnForwardFailure },
|
||||
{ "xauthlocation", oXAuthLocation },
|
||||
{ "gatewayports", oGatewayPorts },
|
||||
@ -228,6 +230,7 @@ static struct {
|
||||
{ "sendenv", oSendEnv },
|
||||
{ "controlpath", oControlPath },
|
||||
{ "controlmaster", oControlMaster },
|
||||
{ "controlpersist", oControlPersist },
|
||||
{ "hashknownhosts", oHashKnownHosts },
|
||||
{ "tunnel", oTunnel },
|
||||
{ "tunneldevice", oTunnelDevice },
|
||||
@ -272,8 +275,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;
|
||||
@ -291,15 +295,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
|
||||
@ -312,12 +318,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;
|
||||
}
|
||||
@ -420,6 +434,10 @@ process_config_line(Options *options, const char *host,
|
||||
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;
|
||||
@ -883,6 +901,30 @@ process_config_line(Options *options, const char *host,
|
||||
*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;
|
||||
@ -1031,6 +1073,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;
|
||||
@ -1071,7 +1114,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;
|
||||
@ -1088,6 +1133,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;
|
||||
@ -1115,6 +1162,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)
|
||||
@ -1221,6 +1270,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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
@ -133,6 +133,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
|
||||
@ -312,7 +313,7 @@ typedef enum {
|
||||
sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
|
||||
sUsePrivilegeSeparation, sAllowAgentForwarding,
|
||||
sZeroKnowledgePasswordAuthentication, sHostCertificate,
|
||||
sRevokedKeys, sTrustedUserCAKeys,
|
||||
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
|
||||
sVersionAddendum,
|
||||
sDeprecated, sUnsupported
|
||||
} ServerOpCodes;
|
||||
@ -348,7 +349,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 */
|
||||
@ -423,11 +424,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 },
|
||||
@ -435,6 +436,7 @@ static struct {
|
||||
{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
|
||||
{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
|
||||
{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
|
||||
{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
|
||||
{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
|
||||
{ NULL, sBadOption, 0 }
|
||||
};
|
||||
@ -1222,10 +1224,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.",
|
||||
@ -1451,6 +1457,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);
|
||||
@ -1458,6 +1465,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);
|
||||
@ -1472,6 +1480,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
|
||||
@ -1693,6 +1704,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));
|
||||
|
@ -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 *);
|
||||
|
@ -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
|
||||
@ -48,6 +48,7 @@ __RCSID("$FreeBSD$");
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#ifdef HAVE_PATHS_H
|
||||
#include <paths.h>
|
||||
@ -105,7 +106,7 @@ __RCSID("$FreeBSD$");
|
||||
/* 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 *);
|
||||
@ -448,6 +449,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));
|
||||
@ -460,7 +464,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]);
|
||||
@ -470,22 +475,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. */
|
||||
@ -596,11 +602,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]);
|
||||
@ -616,10 +619,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]. */
|
||||
@ -741,7 +742,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. */
|
||||
@ -1804,7 +1805,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));
|
||||
@ -2149,7 +2151,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) {
|
||||
@ -2331,7 +2334,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");
|
||||
@ -2343,7 +2347,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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
@ -501,6 +501,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)
|
||||
@ -521,6 +522,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)
|
||||
@ -541,6 +543,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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.\" -*- nroff -*-
|
||||
@ -38,15 +38,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 March 13, 2010
|
||||
.Dd 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
|
||||
@ -60,9 +60,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
|
||||
@ -111,8 +113,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
|
||||
@ -213,13 +216,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
|
||||
@ -270,13 +280,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
|
||||
@ -291,6 +302,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
|
||||
@ -300,13 +327,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.
|
||||
@ -356,7 +383,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
|
||||
@ -442,6 +469,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
|
||||
@ -502,7 +533,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.
|
||||
@ -528,7 +559,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.
|
||||
@ -542,11 +583,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
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
|
||||
for (j = 0; j < fopt_count; j++) {
|
||||
lb = Linebuf_alloc(argv[j], error);
|
||||
if (!lb)
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
|
@ -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 May 31, 2007
|
||||
.Dd 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 ,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -34,9 +34,9 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: ssh.1,v 1.303 2010/03/26 00:26:58 djm Exp $
|
||||
.\" $OpenBSD: ssh.1,v 1.308 2010/08/04 05:37:01 djm Exp $
|
||||
.\" $FreeBSD$
|
||||
.Dd March 26, 2010
|
||||
.Dd August 4 2010
|
||||
.Dt SSH 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -44,46 +44,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
|
||||
@ -195,7 +177,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
|
||||
@ -219,14 +203,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
|
||||
@ -337,15 +314,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
|
||||
@ -422,7 +391,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
|
||||
@ -527,15 +498,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.
|
||||
@ -559,8 +522,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.
|
||||
|
@ -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
|
||||
@ -80,6 +80,7 @@ __RCSID("$FreeBSD$");
|
||||
#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
|
||||
@ -228,6 +238,12 @@ main(int ac, char **av)
|
||||
__progname = ssh_get_progname(av[0]);
|
||||
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).
|
||||
@ -328,6 +344,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
|
||||
@ -621,7 +639,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) {
|
||||
@ -677,6 +695,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];
|
||||
|
||||
@ -686,16 +709,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;
|
||||
|
||||
/* Find canonic host name. */
|
||||
if (strchr(host, '.') == 0) {
|
||||
struct addrinfo hints;
|
||||
@ -779,26 +798,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;
|
||||
}
|
||||
@ -845,6 +872,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++) {
|
||||
@ -884,6 +918,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)
|
||||
@ -895,9 +984,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) {
|
||||
@ -910,12 +1000,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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1111,7 +1197,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.");
|
||||
@ -1157,12 +1245,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();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1193,18 +1282,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.");
|
||||
@ -1281,6 +1374,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();
|
||||
|
||||
@ -1299,14 +1417,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)
|
||||
|
@ -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.
|
||||
|
@ -46,4 +46,4 @@
|
||||
# PermitLocalCommand no
|
||||
# VisualHostKey no
|
||||
# ProxyCommand ssh -q -W %h:%p gateway.example.com
|
||||
# VersionAddendum FreeBSD-20100428
|
||||
# VersionAddendum FreeBSD-20101111
|
||||
|
@ -34,9 +34,9 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: ssh_config.5,v 1.130 2010/03/26 01:06:13 dtucker Exp $
|
||||
.\" $OpenBSD: ssh_config.5,v 1.138 2010/08/04 05:37:01 djm Exp $
|
||||
.\" $FreeBSD$
|
||||
.Dd March 26, 2010
|
||||
.Dd August 4, 2010
|
||||
.Dt SSH_CONFIG 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -320,6 +320,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
|
||||
@ -330,9 +352,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.
|
||||
@ -433,6 +453,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 ,
|
||||
@ -527,6 +558,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
|
||||
@ -642,11 +677,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.
|
||||
@ -733,10 +764,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
|
||||
@ -758,12 +791,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
|
||||
@ -822,11 +857,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
|
||||
@ -1083,7 +1114,7 @@ in
|
||||
Specifies a string to append to the regular version string to identify
|
||||
OS- or site-specific modifications.
|
||||
The default is
|
||||
.Dq FreeBSD-20100428 .
|
||||
.Dq FreeBSD-20101111 .
|
||||
.It Cm VisualHostKey
|
||||
If this flag is set to
|
||||
.Dq yes ,
|
||||
|
@ -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 $ */
|
||||
/* $FreeBSD$ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -102,8 +102,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. */
|
||||
@ -587,9 +587,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;
|
||||
@ -740,7 +740,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) {
|
||||
|
@ -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);
|
||||
|
@ -34,9 +34,9 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: sshd.8,v 1.255 2010/03/05 06:50:35 jmc Exp $
|
||||
.\" $OpenBSD: sshd.8,v 1.257 2010/08/04 05:37:01 djm Exp $
|
||||
.\" $FreeBSD$
|
||||
.Dd March 5, 2010
|
||||
.Dd August 4, 2010
|
||||
.Dt SSHD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -598,13 +598,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
|
||||
|
@ -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
|
||||
@ -755,6 +755,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)
|
||||
@ -778,10 +780,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;
|
||||
|
@ -14,7 +14,7 @@
|
||||
# Note that some of FreeBSD's defaults differ from OpenBSD's, and
|
||||
# FreeBSD has a few additional options.
|
||||
|
||||
#VersionAddendum FreeBSD-20100428
|
||||
#VersionAddendum FreeBSD-20101111
|
||||
|
||||
#Port 22
|
||||
#AddressFamily any
|
||||
|
@ -34,9 +34,9 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: sshd_config.5,v 1.120 2010/03/04 23:17:25 djm Exp $
|
||||
.\" $OpenBSD: sshd_config.5,v 1.125 2010/06/30 07:28:34 jmc Exp $
|
||||
.\" $FreeBSD$
|
||||
.Dd March 4, 2010
|
||||
.Dd June 30, 2010
|
||||
.Dt SSHD_CONFIG 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -156,6 +156,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.
|
||||
@ -168,6 +172,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.
|
||||
@ -609,12 +654,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 ,
|
||||
@ -623,6 +671,7 @@ Available keywords are
|
||||
.Cm PermitEmptyPasswords ,
|
||||
.Cm PermitOpen ,
|
||||
.Cm PermitRootLogin ,
|
||||
.Cm PermitTunnel ,
|
||||
.Cm PubkeyAuthentication ,
|
||||
.Cm RhostsRSAAuthentication ,
|
||||
.Cm RSAAuthentication ,
|
||||
@ -988,7 +1037,7 @@ The default is
|
||||
Specifies a string to append to the regular version string to identify
|
||||
OS- or site-specific modifications.
|
||||
The default is
|
||||
.Dq FreeBSD-20100428 .
|
||||
.Dq FreeBSD-20101111 .
|
||||
.It Cm X11DisplayOffset
|
||||
Specifies the first display number available for
|
||||
.Xr sshd 8 Ns 's
|
||||
|
@ -1,12 +1,12 @@
|
||||
/* $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 $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#ifndef SSH_VERSION
|
||||
|
||||
#define SSH_VERSION (ssh_version_get())
|
||||
#define SSH_RELEASE (ssh_version_get())
|
||||
#define SSH_VERSION_BASE "OpenSSH_5.5p1"
|
||||
#define SSH_VERSION_ADDENDUM "FreeBSD-20100428"
|
||||
#define SSH_VERSION_BASE "OpenSSH_5.6p1"
|
||||
#define SSH_VERSION_ADDENDUM "FreeBSD-20101111"
|
||||
|
||||
const char *ssh_version_get(void);
|
||||
void ssh_version_set_addendum(const char *);
|
||||
|
Loading…
Reference in New Issue
Block a user