Vendor import of OpenSSH 5.7p1
This commit is contained in:
parent
a074372f88
commit
e089765887
1
LICENCE
1
LICENCE
@ -206,6 +206,7 @@ OpenSSH contains no GPL code.
|
||||
Sun Microsystems
|
||||
The SCO Group
|
||||
Daniel Walsh
|
||||
Red Hat, Inc
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
51
Makefile.in
51
Makefile.in
@ -1,4 +1,4 @@
|
||||
# $Id: Makefile.in,v 1.310 2010/05/12 06:51:39 dtucker Exp $
|
||||
# $Id: Makefile.in,v 1.320 2011/01/17 10:15:29 dtucker Exp $
|
||||
|
||||
# uncomment if you run a non bourne compatable shell. Ie. csh
|
||||
#SHELL = @SH@
|
||||
@ -58,6 +58,7 @@ ENT=@ENT@
|
||||
XAUTH_PATH=@XAUTH_PATH@
|
||||
LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@
|
||||
EXEEXT=@EXEEXT@
|
||||
MANFMT=@MANFMT@
|
||||
|
||||
INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@
|
||||
INSTALL_SSH_RAND_HELPER=@INSTALL_SSH_RAND_HELPER@
|
||||
@ -71,26 +72,27 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
|
||||
log.o match.o md-sha256.o moduli.o nchan.o packet.o \
|
||||
readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \
|
||||
atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \
|
||||
monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \
|
||||
kexgex.o kexdhc.o kexgexc.o msg.o progressmeter.o dns.o \
|
||||
entropy.o gss-genr.o umac.o jpake.o schnorr.o \
|
||||
ssh-pkcs11.o
|
||||
monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \
|
||||
kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \
|
||||
msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o jpake.o \
|
||||
schnorr.o ssh-pkcs11.o
|
||||
|
||||
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
|
||||
sshconnect.o sshconnect1.o sshconnect2.o mux.o \
|
||||
roaming_common.o roaming_client.o
|
||||
|
||||
SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
|
||||
audit.o audit-bsm.o audit-linux.o platform.o \
|
||||
sshpty.o sshlogin.o servconf.o serverloop.o \
|
||||
auth.o auth1.o auth2.o auth-options.o session.o \
|
||||
auth-chall.o auth2-chall.o groupaccess.o \
|
||||
auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \
|
||||
auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-jpake.o \
|
||||
monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \
|
||||
monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \
|
||||
auth-krb5.o \
|
||||
auth2-gss.o gss-serv.o gss-serv-krb5.o \
|
||||
loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
|
||||
audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o \
|
||||
sftp-server.o sftp-common.o \
|
||||
roaming_common.o roaming_serv.o
|
||||
|
||||
MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out
|
||||
@ -108,6 +110,7 @@ PATHSUBS = \
|
||||
-e 's|/usr/libexec|$(libexecdir)|g' \
|
||||
-e 's|/etc/shosts.equiv|$(sysconfdir)/shosts.equiv|g' \
|
||||
-e 's|/etc/ssh/ssh_host_key|$(sysconfdir)/ssh_host_key|g' \
|
||||
-e 's|/etc/ssh/ssh_host_ecdsa_key|$(sysconfdir)/ssh_host_ecdsa_key|g' \
|
||||
-e 's|/etc/ssh/ssh_host_dsa_key|$(sysconfdir)/ssh_host_dsa_key|g' \
|
||||
-e 's|/etc/ssh/ssh_host_rsa_key|$(sysconfdir)/ssh_host_rsa_key|g' \
|
||||
-e 's|/var/run/sshd.pid|$(piddir)/sshd.pid|g' \
|
||||
@ -230,7 +233,7 @@ catman-do:
|
||||
@for f in $(MANPAGES_IN) ; do \
|
||||
base=`echo $$f | sed 's/\..*$$//'` ; \
|
||||
echo "$$f -> $$base.0" ; \
|
||||
nroff -mandoc $$f | cat -v | sed -e 's/.\^H//g' \
|
||||
$(MANFMT) $$f | cat -v | sed -e 's/.\^H//g' \
|
||||
>$$base.0 ; \
|
||||
done
|
||||
|
||||
@ -324,20 +327,27 @@ install-sysconf:
|
||||
|
||||
host-key: ssh-keygen$(EXEEXT)
|
||||
@if [ -z "$(DESTDIR)" ] ; then \
|
||||
if [ -f "$(DESTDIR)$(sysconfdir)/ssh_host_key" ] ; then \
|
||||
echo "$(DESTDIR)$(sysconfdir)/ssh_host_key already exists, skipping." ; \
|
||||
if [ -f "$(sysconfdir)/ssh_host_key" ] ; then \
|
||||
echo "$(sysconfdir)/ssh_host_key already exists, skipping." ; \
|
||||
else \
|
||||
./ssh-keygen -t rsa1 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" ; \
|
||||
./ssh-keygen -t rsa1 -f $(sysconfdir)/ssh_host_key -N "" ; \
|
||||
fi ; \
|
||||
if [ -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key ] ; then \
|
||||
echo "$(DESTDIR)$(sysconfdir)/ssh_host_dsa_key already exists, skipping." ; \
|
||||
if [ -f $(sysconfdir)/ssh_host_dsa_key ] ; then \
|
||||
echo "$(sysconfdir)/ssh_host_dsa_key already exists, skipping." ; \
|
||||
else \
|
||||
./ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" ; \
|
||||
./ssh-keygen -t dsa -f $(sysconfdir)/ssh_host_dsa_key -N "" ; \
|
||||
fi ; \
|
||||
if [ -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key ] ; then \
|
||||
echo "$(DESTDIR)$(sysconfdir)/ssh_host_rsa_key already exists, skipping." ; \
|
||||
if [ -f $(sysconfdir)/ssh_host_rsa_key ] ; then \
|
||||
echo "$(sysconfdir)/ssh_host_rsa_key already exists, skipping." ; \
|
||||
else \
|
||||
./ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N "" ; \
|
||||
./ssh-keygen -t rsa -f $(sysconfdir)/ssh_host_rsa_key -N "" ; \
|
||||
fi ; \
|
||||
if [ -z "@COMMENT_OUT_ECC@" ] ; then \
|
||||
if [ -f $(sysconfdir)/ssh_host_ecdsa_key ] ; then \
|
||||
echo "$(sysconfdir)/ssh_host_ecdsa_key already exists, skipping." ; \
|
||||
else \
|
||||
./ssh-keygen -t ecdsa -f $(sysconfdir)/ssh_host_ecdsa_key -N "" ; \
|
||||
fi ; \
|
||||
fi ; \
|
||||
fi ;
|
||||
|
||||
@ -345,6 +355,7 @@ host-key-force: ssh-keygen$(EXEEXT)
|
||||
./ssh-keygen -t rsa1 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N ""
|
||||
./ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N ""
|
||||
./ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N ""
|
||||
test -z "@COMMENT_OUT_ECC@" && ./ssh-keygen -t ecdsa -f $(DESTDIR)$(sysconfdir)/ssh_host_ecdsa_key -N ""
|
||||
|
||||
uninstallall: uninstall
|
||||
-rm -f $(DESTDIR)$(sysconfdir)/ssh_config
|
||||
@ -405,6 +416,8 @@ tests interop-tests: $(TARGETS)
|
||||
TEST_SSH_PUTTYGEN="puttygen"; \
|
||||
TEST_SSH_CONCH="conch"; \
|
||||
TEST_SSH_IPV6="@TEST_SSH_IPV6@" ; \
|
||||
TEST_SSH_ECC="@TEST_SSH_ECC@" ; \
|
||||
TEST_SSH_SHA256="@TEST_SSH_SHA256@" ; \
|
||||
cd $(srcdir)/regress || exit $$?; \
|
||||
$(MAKE) \
|
||||
.OBJDIR="$${BUILDDIR}/regress" \
|
||||
@ -425,7 +438,9 @@ tests interop-tests: $(TARGETS)
|
||||
TEST_SSH_PLINK="$${TEST_SSH_PLINK}" \
|
||||
TEST_SSH_PUTTYGEN="$${TEST_SSH_PUTTYGEN}" \
|
||||
TEST_SSH_CONCH="$${TEST_SSH_CONCH}" \
|
||||
TEST_SSH_IPV6="@TEST_SSH_IPV6@" \
|
||||
TEST_SSH_IPV6="$${TEST_SSH_IPV6}" \
|
||||
TEST_SSH_ECC="$${TEST_SSH_ECC}" \
|
||||
TEST_SSH_SHA256="$${TEST_SSH_SHA256}" \
|
||||
EXEEXT="$(EXEEXT)" \
|
||||
$@ && echo all tests passed
|
||||
|
||||
|
59
PROTOCOL
59
PROTOCOL
@ -12,7 +12,9 @@ are individually implemented as extensions described below.
|
||||
The protocol used by OpenSSH's ssh-agent is described in the file
|
||||
PROTOCOL.agent
|
||||
|
||||
1. transport: Protocol 2 MAC algorithm "umac-64@openssh.com"
|
||||
1. Transport protocol changes
|
||||
|
||||
1.1. transport: Protocol 2 MAC algorithm "umac-64@openssh.com"
|
||||
|
||||
This is a new transport-layer MAC method using the UMAC algorithm
|
||||
(rfc4418). This method is identical to the "umac-64" method documented
|
||||
@ -20,7 +22,7 @@ in:
|
||||
|
||||
http://www.openssh.com/txt/draft-miller-secsh-umac-01.txt
|
||||
|
||||
2. transport: Protocol 2 compression algorithm "zlib@openssh.com"
|
||||
1.2. transport: Protocol 2 compression algorithm "zlib@openssh.com"
|
||||
|
||||
This transport-layer compression method uses the zlib compression
|
||||
algorithm (identical to the "zlib" method in rfc4253), but delays the
|
||||
@ -31,14 +33,27 @@ The method is documented in:
|
||||
|
||||
http://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt
|
||||
|
||||
3. transport: New public key algorithms "ssh-rsa-cert-v00@openssh.com" and
|
||||
"ssh-dsa-cert-v00@openssh.com"
|
||||
1.3. transport: New public key algorithms "ssh-rsa-cert-v00@openssh.com",
|
||||
"ssh-dsa-cert-v00@openssh.com",
|
||||
"ecdsa-sha2-nistp256-cert-v01@openssh.com",
|
||||
"ecdsa-sha2-nistp384-cert-v01@openssh.com" and
|
||||
"ecdsa-sha2-nistp521-cert-v01@openssh.com"
|
||||
|
||||
OpenSSH introduces two new public key algorithms to support certificate
|
||||
OpenSSH introduces new public key algorithms to support certificate
|
||||
authentication for users and hostkeys. These methods are documented in
|
||||
the file PROTOCOL.certkeys
|
||||
|
||||
4. connection: Channel write close extension "eow@openssh.com"
|
||||
1.4. transport: Elliptic Curve cryptography
|
||||
|
||||
OpenSSH supports ECC key exchange and public key authentication as
|
||||
specified in RFC5656. Only the ecdsa-sha2-nistp256, ecdsa-sha2-nistp384
|
||||
and ecdsa-sha2-nistp521 curves over GF(p) are supported. Elliptic
|
||||
curve points encoded using point compression are NOT accepted or
|
||||
generated.
|
||||
|
||||
2. Connection protocol changes
|
||||
|
||||
2.1. connection: Channel write close extension "eow@openssh.com"
|
||||
|
||||
The SSH connection protocol (rfc4254) provides the SSH_MSG_CHANNEL_EOF
|
||||
message to allow an endpoint to signal its peer that it will send no
|
||||
@ -77,7 +92,7 @@ message is only sent to OpenSSH peers (identified by banner).
|
||||
Other SSH implementations may be whitelisted to receive this message
|
||||
upon request.
|
||||
|
||||
5. connection: disallow additional sessions extension
|
||||
2.2. connection: disallow additional sessions extension
|
||||
"no-more-sessions@openssh.com"
|
||||
|
||||
Most SSH connections will only ever request a single session, but a
|
||||
@ -105,7 +120,7 @@ of this message, the no-more-sessions request is only sent to OpenSSH
|
||||
servers (identified by banner). Other SSH implementations may be
|
||||
whitelisted to receive this message upon request.
|
||||
|
||||
6. connection: Tunnel forward extension "tun@openssh.com"
|
||||
2.3. connection: Tunnel forward extension "tun@openssh.com"
|
||||
|
||||
OpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com"
|
||||
channel type. This channel type supports forwarding of network packets
|
||||
@ -166,7 +181,9 @@ The contents of the "data" field for layer 2 packets is:
|
||||
The "frame" field contains an IEEE 802.3 Ethernet frame, including
|
||||
header.
|
||||
|
||||
7. sftp: Reversal of arguments to SSH_FXP_SYMLINK
|
||||
3. SFTP protocol changes
|
||||
|
||||
3.1. sftp: Reversal of arguments to SSH_FXP_SYMLINK
|
||||
|
||||
When OpenSSH's sftp-server was implemented, the order of the arguments
|
||||
to the SSH_FXP_SYMLINK method was inadvertently reversed. Unfortunately,
|
||||
@ -179,7 +196,7 @@ SSH_FXP_SYMLINK as follows:
|
||||
string targetpath
|
||||
string linkpath
|
||||
|
||||
8. sftp: Server extension announcement in SSH_FXP_VERSION
|
||||
3.2. sftp: Server extension announcement in SSH_FXP_VERSION
|
||||
|
||||
OpenSSH's sftp-server lists the extensions it supports using the
|
||||
standard extension announcement mechanism in the SSH_FXP_VERSION server
|
||||
@ -200,7 +217,7 @@ ever changed in an incompatible way. The server MAY advertise the same
|
||||
extension with multiple versions (though this is unlikely). Clients MUST
|
||||
check the version number before attempting to use the extension.
|
||||
|
||||
9. sftp: Extension request "posix-rename@openssh.com"
|
||||
3.3. sftp: Extension request "posix-rename@openssh.com"
|
||||
|
||||
This operation provides a rename operation with POSIX semantics, which
|
||||
are different to those provided by the standard SSH_FXP_RENAME in
|
||||
@ -217,7 +234,7 @@ rename(oldpath, newpath) and will respond with a SSH_FXP_STATUS message.
|
||||
This extension is advertised in the SSH_FXP_VERSION hello with version
|
||||
"1".
|
||||
|
||||
10. sftp: Extension requests "statvfs@openssh.com" and
|
||||
3.4. sftp: Extension requests "statvfs@openssh.com" and
|
||||
"fstatvfs@openssh.com"
|
||||
|
||||
These requests correspond to the statvfs and fstatvfs POSIX system
|
||||
@ -258,4 +275,20 @@ The values of the f_flag bitmask are as follows:
|
||||
Both the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are
|
||||
advertised in the SSH_FXP_VERSION hello with version "2".
|
||||
|
||||
$OpenBSD: PROTOCOL,v 1.15 2010/02/26 20:29:54 djm Exp $
|
||||
10. sftp: Extension request "hardlink@openssh.com"
|
||||
|
||||
This request is for creating a hard link to a regular file. This
|
||||
request is implemented as a SSH_FXP_EXTENDED request with the
|
||||
following format:
|
||||
|
||||
uint32 id
|
||||
string "hardlink@openssh.com"
|
||||
string oldpath
|
||||
string newpath
|
||||
|
||||
On receiving this request the server will perform the operation
|
||||
link(oldpath, newpath) and will respond with a SSH_FXP_STATUS message.
|
||||
This extension is advertised in the SSH_FXP_VERSION hello with version
|
||||
"1".
|
||||
|
||||
$OpenBSD: PROTOCOL,v 1.17 2010/12/04 00:18:01 djm Exp $
|
||||
|
@ -159,8 +159,8 @@ successfully added or a SSH_AGENT_FAILURE if an error occurred.
|
||||
|
||||
2.2.3 Add protocol 2 key
|
||||
|
||||
The OpenSSH agent supports DSA and RSA keys for protocol 2. DSA keys may
|
||||
be added using the following request
|
||||
The OpenSSH agent supports DSA, ECDSA and RSA keys for protocol 2. DSA
|
||||
keys may be added using the following request
|
||||
|
||||
byte SSH2_AGENTC_ADD_IDENTITY or
|
||||
SSH2_AGENTC_ADD_ID_CONSTRAINED
|
||||
@ -182,6 +182,30 @@ DSA certificates may be added with:
|
||||
string key_comment
|
||||
constraint[] key_constraints
|
||||
|
||||
ECDSA keys may be added using the following request
|
||||
|
||||
byte SSH2_AGENTC_ADD_IDENTITY or
|
||||
SSH2_AGENTC_ADD_ID_CONSTRAINED
|
||||
string "ecdsa-sha2-nistp256" |
|
||||
"ecdsa-sha2-nistp384" |
|
||||
"ecdsa-sha2-nistp521"
|
||||
string ecdsa_curve_name
|
||||
string ecdsa_public_key
|
||||
mpint ecdsa_private
|
||||
string key_comment
|
||||
constraint[] key_constraints
|
||||
|
||||
ECDSA certificates may be added with:
|
||||
byte SSH2_AGENTC_ADD_IDENTITY or
|
||||
SSH2_AGENTC_ADD_ID_CONSTRAINED
|
||||
string "ecdsa-sha2-nistp256-cert-v01@openssh.com" |
|
||||
"ecdsa-sha2-nistp384-cert-v01@openssh.com" |
|
||||
"ecdsa-sha2-nistp521-cert-v01@openssh.com"
|
||||
string certificate
|
||||
mpint ecdsa_private_key
|
||||
string key_comment
|
||||
constraint[] key_constraints
|
||||
|
||||
RSA keys may be added with this request:
|
||||
|
||||
byte SSH2_AGENTC_ADD_IDENTITY or
|
||||
@ -214,7 +238,7 @@ order to the protocol 1 add keys message. As with the corresponding
|
||||
protocol 1 "add key" request, the private key is overspecified to avoid
|
||||
redundant processing.
|
||||
|
||||
For both DSA and RSA key add requests, "key_constraints" may only be
|
||||
For DSA, ECDSA and RSA key add requests, "key_constraints" may only be
|
||||
present if the request type is SSH2_AGENTC_ADD_ID_CONSTRAINED.
|
||||
|
||||
The agent will reply with a SSH_AGENT_SUCCESS if the key has been
|
||||
@ -294,8 +318,7 @@ Protocol 2 keys may be removed with the following request:
|
||||
string key_blob
|
||||
|
||||
Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
|
||||
Algorithms" for either of the supported key types: "ssh-dss" or
|
||||
"ssh-rsa".
|
||||
Algorithms" for any of the supported protocol 2 key types.
|
||||
|
||||
The agent will delete any private key matching the specified public key
|
||||
and return SSH_AGENT_SUCCESS. If no such key was found, the agent will
|
||||
@ -364,8 +387,7 @@ Followed by zero or more consecutive keys, encoded as:
|
||||
string key_comment
|
||||
|
||||
Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
|
||||
Algorithms" for either of the supported key types: "ssh-dss" or
|
||||
"ssh-rsa".
|
||||
Algorithms" for any of the supported protocol 2 key types.
|
||||
|
||||
2.6 Private key operations
|
||||
|
||||
@ -429,9 +451,9 @@ a protocol 2 key:
|
||||
uint32 flags
|
||||
|
||||
Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
|
||||
Algorithms" for either of the supported key types: "ssh-dss" or
|
||||
"ssh-rsa". "flags" is a bit-mask, but at present only one possible value
|
||||
is defined (see below for its meaning):
|
||||
Algorithms" for any of the supported protocol 2 key types. "flags" is
|
||||
a bit-mask, but at present only one possible value is defined (see below
|
||||
for its meaning):
|
||||
|
||||
SSH_AGENT_OLD_SIGNATURE 1
|
||||
|
||||
@ -535,4 +557,4 @@ Locking and unlocking affects both protocol 1 and protocol 2 keys.
|
||||
SSH_AGENT_CONSTRAIN_LIFETIME 1
|
||||
SSH_AGENT_CONSTRAIN_CONFIRM 2
|
||||
|
||||
$OpenBSD: PROTOCOL.agent,v 1.5 2010/02/26 20:29:54 djm Exp $
|
||||
$OpenBSD: PROTOCOL.agent,v 1.6 2010/08/31 11:54:45 djm Exp $
|
||||
|
@ -5,31 +5,37 @@ Background
|
||||
----------
|
||||
|
||||
The SSH protocol currently supports a simple public key authentication
|
||||
mechanism. Unlike other public key implementations, SSH eschews the
|
||||
use of X.509 certificates and uses raw keys. This approach has some
|
||||
benefits relating to simplicity of configuration and minimisation
|
||||
of attack surface, but it does not support the important use-cases
|
||||
of centrally managed, passwordless authentication and centrally
|
||||
certified host keys.
|
||||
mechanism. Unlike other public key implementations, SSH eschews the use
|
||||
of X.509 certificates and uses raw keys. This approach has some benefits
|
||||
relating to simplicity of configuration and minimisation of attack
|
||||
surface, but it does not support the important use-cases of centrally
|
||||
managed, passwordless authentication and centrally certified host keys.
|
||||
|
||||
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 options
|
||||
that have been signed with some other trusted key.
|
||||
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 options that have been signed
|
||||
with some other trusted key.
|
||||
|
||||
A sshd server may be configured to allow authentication via certified
|
||||
keys, by extending the existing ~/.ssh/authorized_keys mechanism
|
||||
to allow specification of certification authority keys in addition
|
||||
to raw user keys. The ssh client will support automatic verification
|
||||
of acceptance of certified host keys, by adding a similar ability
|
||||
to specify CA keys in ~/.ssh/known_hosts.
|
||||
keys, by extending the existing ~/.ssh/authorized_keys mechanism to
|
||||
allow specification of certification authority keys in addition to
|
||||
raw user keys. The ssh client will support automatic verification 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-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.
|
||||
Certified keys are represented using new key types:
|
||||
|
||||
ssh-rsa-cert-v01@openssh.com
|
||||
ssh-dss-cert-v01@openssh.com
|
||||
ecdsa-sha2-nistp256-cert-v01@openssh.com
|
||||
ecdsa-sha2-nistp384-cert-v01@openssh.com
|
||||
ecdsa-sha2-nistp521-cert-v01@openssh.com
|
||||
|
||||
These include certification information along with the public key
|
||||
that is used to sign challenges. ssh-keygen performs the CA signing
|
||||
operation.
|
||||
|
||||
Protocol extensions
|
||||
-------------------
|
||||
@ -47,10 +53,9 @@ in RFC4252 section 7.
|
||||
New public key formats
|
||||
----------------------
|
||||
|
||||
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.
|
||||
The certificate 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.
|
||||
|
||||
#define SSH_CERT_TYPE_USER 1
|
||||
#define SSH_CERT_TYPE_HOST 2
|
||||
@ -93,6 +98,26 @@ DSA certificate
|
||||
string signature key
|
||||
string signature
|
||||
|
||||
ECDSA certificate
|
||||
|
||||
string "ecdsa-sha2-nistp256@openssh.com" |
|
||||
"ecdsa-sha2-nistp384@openssh.com" |
|
||||
"ecdsa-sha2-nistp521@openssh.com"
|
||||
string nonce
|
||||
string curve
|
||||
string public_key
|
||||
uint64 serial
|
||||
uint32 type
|
||||
string key id
|
||||
string valid principals
|
||||
uint64 valid after
|
||||
uint64 valid before
|
||||
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.
|
||||
@ -101,6 +126,9 @@ 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.
|
||||
|
||||
curve and public key are respectively the ECDSA "[identifier]" and "Q"
|
||||
defined in section 3.1 of RFC5656.
|
||||
|
||||
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
|
||||
@ -123,6 +151,7 @@ any principal of the specified type. XXX DNS wildcards?
|
||||
"valid after" and "valid before" specify a validity period for the
|
||||
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
|
||||
|
||||
criticial options is a set of zero or more key options encoded as
|
||||
@ -137,15 +166,17 @@ 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.
|
||||
The valid key types for CA keys are ssh-rsa and ssh-dss. "Chained"
|
||||
The valid key types for CA keys are ssh-rsa, ssh-dss and the ECDSA types
|
||||
ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521. "Chained"
|
||||
certificates, where the signature key type is a certificate type itself
|
||||
are NOT supported. Note that it is possible for a RSA certificate key to
|
||||
be signed by a DSS CA key and vice-versa.
|
||||
be signed by a DSS or ECDSA CA key and vice-versa.
|
||||
|
||||
signature is computed over all preceding fields from the initial string
|
||||
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).
|
||||
(RFC4253 section 6.6 for ssh-rsa and ssh-dss, RFC5656 for the ECDSA
|
||||
types).
|
||||
|
||||
Critical options
|
||||
----------------
|
||||
@ -222,4 +253,4 @@ permit-user-rc empty Flag indicating that execution of
|
||||
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 $
|
||||
$OpenBSD: PROTOCOL.certkeys,v 1.8 2010/08/31 11:54:45 djm Exp $
|
||||
|
26
PROTOCOL.mux
26
PROTOCOL.mux
@ -28,7 +28,7 @@ defined.
|
||||
To open a new multiplexed session, a client may send the following
|
||||
request:
|
||||
|
||||
uint32 MUX_C_MSG_NEW_SESSION
|
||||
uint32 MUX_C_NEW_SESSION
|
||||
uint32 request id
|
||||
string reserved
|
||||
bool want tty flag
|
||||
@ -99,7 +99,7 @@ The server will reply with one of MUX_S_OK or MUX_S_PERMISSION_DENIED.
|
||||
|
||||
A client may request the master to establish a port forward:
|
||||
|
||||
uint32 MUX_C_OPEN_FORWARD
|
||||
uint32 MUX_C_OPEN_FWD
|
||||
uint32 request id
|
||||
uint32 forwarding type
|
||||
string listen host
|
||||
@ -118,24 +118,23 @@ For dynamically allocated listen port the server replies with
|
||||
uint32 client request id
|
||||
uint32 allocated remote listen port
|
||||
|
||||
5. Requesting closure of port forwards
|
||||
6. Requesting closure of port forwards
|
||||
|
||||
Note: currently unimplemented (server will always reply with MUX_S_FAILURE).
|
||||
|
||||
A client may request the master to establish a port forward:
|
||||
|
||||
uint32 MUX_C_OPEN_FORWARD
|
||||
uint32 MUX_C_CLOSE_FWD
|
||||
uint32 request id
|
||||
uint32 forwarding type
|
||||
string listen host
|
||||
string listen port
|
||||
string connect host
|
||||
string connect port
|
||||
|
||||
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.
|
||||
|
||||
6. Requesting stdio forwarding
|
||||
7. Requesting stdio forwarding
|
||||
|
||||
A client may request the master to establish a stdio forwarding:
|
||||
|
||||
@ -153,7 +152,7 @@ The contents of "reserved" are currently ignored.
|
||||
A server may reply with a MUX_S_SESSION_OPEED, a MUX_S_PERMISSION_DENIED
|
||||
or a MUX_S_FAILURE.
|
||||
|
||||
7. Status messages
|
||||
8. Status messages
|
||||
|
||||
The MUX_S_OK message is empty:
|
||||
|
||||
@ -170,14 +169,15 @@ The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason:
|
||||
uint32 client request id
|
||||
string reason
|
||||
|
||||
7. Protocol numbers
|
||||
9. Protocol numbers
|
||||
|
||||
#define MUX_MSG_HELLO 0x00000001
|
||||
#define MUX_C_NEW_SESSION 0x10000002
|
||||
#define MUX_C_ALIVE_CHECK 0x10000004
|
||||
#define MUX_C_TERMINATE 0x10000005
|
||||
#define MUX_C_OPEN_FORWARD 0x10000006
|
||||
#define MUX_C_CLOSE_FORWARD 0x10000007
|
||||
#define MUX_C_OPEN_FWD 0x10000006
|
||||
#define MUX_C_CLOSE_FWD 0x10000007
|
||||
#define MUX_C_NEW_STDIO_FWD 0x10000008
|
||||
#define MUX_S_OK 0x80000001
|
||||
#define MUX_S_PERMISSION_DENIED 0x80000002
|
||||
#define MUX_S_FAILURE 0x80000003
|
||||
@ -200,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.2 2010/05/16 12:55:51 markus Exp $
|
||||
$OpenBSD: PROTOCOL.mux,v 1.3 2011/01/13 21:55:25 djm Exp $
|
||||
|
4
README
4
README
@ -1,4 +1,4 @@
|
||||
See http://www.openssh.com/txt/release-5.6 for the release notes.
|
||||
See http://www.openssh.com/txt/release-5.7 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.74 2010/08/08 16:32:06 djm Exp $
|
||||
$Id: README,v 1.75 2011/01/22 09:23:12 djm Exp $
|
||||
|
33
atomicio.c
33
atomicio.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: atomicio.c,v 1.25 2007/06/25 12:02:27 dtucker Exp $ */
|
||||
/* $OpenBSD: atomicio.c,v 1.26 2010/09/22 22:58:51 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2006 Damien Miller. All rights reserved.
|
||||
* Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.
|
||||
@ -48,7 +48,8 @@
|
||||
* ensure all of data on socket comes through. f==read || f==vwrite
|
||||
*/
|
||||
size_t
|
||||
atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)
|
||||
atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n,
|
||||
int (*cb)(void *, size_t), void *cb_arg)
|
||||
{
|
||||
char *s = _s;
|
||||
size_t pos = 0;
|
||||
@ -73,17 +74,28 @@ atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)
|
||||
return pos;
|
||||
default:
|
||||
pos += (size_t)res;
|
||||
if (cb != NULL && cb(cb_arg, (size_t)res) == -1) {
|
||||
errno = EINTR;
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
return (pos);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
size_t
|
||||
atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)
|
||||
{
|
||||
return atomicio6(f, fd, _s, n, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* ensure all of data on socket comes through. f==readv || f==writev
|
||||
*/
|
||||
size_t
|
||||
atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd,
|
||||
const struct iovec *_iov, int iovcnt)
|
||||
atomiciov6(ssize_t (*f) (int, const struct iovec *, int), int fd,
|
||||
const struct iovec *_iov, int iovcnt,
|
||||
int (*cb)(void *, size_t), void *cb_arg)
|
||||
{
|
||||
size_t pos = 0, rem;
|
||||
ssize_t res;
|
||||
@ -137,6 +149,17 @@ atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd,
|
||||
iov[0].iov_base = ((char *)iov[0].iov_base) + rem;
|
||||
iov[0].iov_len -= rem;
|
||||
}
|
||||
if (cb != NULL && cb(cb_arg, (size_t)res) == -1) {
|
||||
errno = EINTR;
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
size_t
|
||||
atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd,
|
||||
const struct iovec *_iov, int iovcnt)
|
||||
{
|
||||
return atomiciov6(f, fd, _iov, iovcnt, NULL, NULL);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: atomicio.h,v 1.10 2006/08/03 03:34:41 deraadt Exp $ */
|
||||
/* $OpenBSD: atomicio.h,v 1.11 2010/09/22 22:58:51 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Damien Miller. All rights reserved.
|
||||
@ -32,6 +32,9 @@
|
||||
/*
|
||||
* Ensure all of data on socket comes through. f==read || f==vwrite
|
||||
*/
|
||||
size_t
|
||||
atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n,
|
||||
int (*cb)(void *, size_t), void *);
|
||||
size_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t);
|
||||
|
||||
#define vwrite (ssize_t (*)(int, void *, size_t))write
|
||||
@ -39,6 +42,9 @@ size_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t);
|
||||
/*
|
||||
* ensure all of data on socket comes through. f==readv || f==writev
|
||||
*/
|
||||
size_t
|
||||
atomiciov6(ssize_t (*f) (int, const struct iovec *, int), int fd,
|
||||
const struct iovec *_iov, int iovcnt, int (*cb)(void *, size_t), void *);
|
||||
size_t atomiciov(ssize_t (*)(int, const struct iovec *, int),
|
||||
int, const struct iovec *, int);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: audit-bsm.c,v 1.6 2008/02/25 10:05:04 dtucker Exp $ */
|
||||
/* $Id: audit-bsm.c,v 1.7 2011/01/17 10:15:29 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* TODO
|
||||
@ -305,13 +305,13 @@ audit_run_command(const char *command)
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_open(const char *ttyn)
|
||||
audit_session_open(struct logininfo *li)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_close(const char *ttyn)
|
||||
audit_session_close(struct logininfo *li)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
|
126
audit-linux.c
Normal file
126
audit-linux.c
Normal file
@ -0,0 +1,126 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright 2010 Red Hat, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Red Hat author: Jan F. Chadima <jchadima@redhat.com>
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#if defined(USE_LINUX_AUDIT)
|
||||
#include <libaudit.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "audit.h"
|
||||
#include "canohost.h"
|
||||
|
||||
const char* audit_username(void);
|
||||
|
||||
int
|
||||
linux_audit_record_event(int uid, const char *username,
|
||||
const char *hostname, const char *ip, const char *ttyn, int success)
|
||||
{
|
||||
int audit_fd, rc, saved_errno;
|
||||
|
||||
audit_fd = audit_open();
|
||||
if (audit_fd < 0) {
|
||||
if (errno == EINVAL || errno == EPROTONOSUPPORT ||
|
||||
errno == EAFNOSUPPORT)
|
||||
return 1; /* No audit support in kernel */
|
||||
else
|
||||
return 0; /* Must prevent login */
|
||||
}
|
||||
rc = audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN,
|
||||
NULL, "login", username ? username : "(unknown)",
|
||||
username == NULL ? uid : -1, hostname, ip, ttyn, success);
|
||||
saved_errno = errno;
|
||||
close(audit_fd);
|
||||
/*
|
||||
* Do not report error if the error is EPERM and sshd is run as non
|
||||
* root user.
|
||||
*/
|
||||
if ((rc == -EPERM) && (geteuid() != 0))
|
||||
rc = 0;
|
||||
errno = saved_errno;
|
||||
return (rc >= 0);
|
||||
}
|
||||
|
||||
/* Below is the sshd audit API code */
|
||||
|
||||
void
|
||||
audit_connection_from(const char *host, int port)
|
||||
{
|
||||
}
|
||||
/* not implemented */
|
||||
|
||||
void
|
||||
audit_run_command(const char *command)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_open(struct logininfo *li)
|
||||
{
|
||||
if (linux_audit_record_event(li->uid, NULL, li->hostname,
|
||||
NULL, li->line, 1) == 0)
|
||||
fatal("linux_audit_write_entry failed: %s", strerror(errno));
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_close(struct logininfo *li)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
void
|
||||
audit_event(ssh_audit_event_t event)
|
||||
{
|
||||
switch(event) {
|
||||
case SSH_AUTH_SUCCESS:
|
||||
case SSH_CONNECTION_CLOSE:
|
||||
case SSH_NOLOGIN:
|
||||
case SSH_LOGIN_EXCEED_MAXTRIES:
|
||||
case SSH_LOGIN_ROOT_DENIED:
|
||||
break;
|
||||
|
||||
case SSH_AUTH_FAIL_NONE:
|
||||
case SSH_AUTH_FAIL_PASSWD:
|
||||
case SSH_AUTH_FAIL_KBDINT:
|
||||
case SSH_AUTH_FAIL_PUBKEY:
|
||||
case SSH_AUTH_FAIL_HOSTBASED:
|
||||
case SSH_AUTH_FAIL_GSSAPI:
|
||||
case SSH_INVALID_USER:
|
||||
linux_audit_record_event(-1, audit_username(), NULL,
|
||||
get_remote_ipaddr(), "sshd", 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
debug("%s: unhandled event %d", __func__, event);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_LINUX_AUDIT */
|
10
audit.c
10
audit.c
@ -1,4 +1,4 @@
|
||||
/* $Id: audit.c,v 1.5 2006/09/01 05:38:36 djm Exp $ */
|
||||
/* $Id: audit.c,v 1.6 2011/01/17 10:15:30 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004, 2005 Darren Tucker. All rights reserved.
|
||||
@ -147,9 +147,9 @@ audit_event(ssh_audit_event_t event)
|
||||
* within a single connection.
|
||||
*/
|
||||
void
|
||||
audit_session_open(const char *ttyn)
|
||||
audit_session_open(struct logininfo *li)
|
||||
{
|
||||
const char *t = ttyn ? ttyn : "(no tty)";
|
||||
const char *t = li->line ? li->line : "(no tty)";
|
||||
|
||||
debug("audit session open euid %d user %s tty name %s", geteuid(),
|
||||
audit_username(), t);
|
||||
@ -163,9 +163,9 @@ audit_session_open(const char *ttyn)
|
||||
* within a single connection.
|
||||
*/
|
||||
void
|
||||
audit_session_close(const char *ttyn)
|
||||
audit_session_close(struct logininfo *li)
|
||||
{
|
||||
const char *t = ttyn ? ttyn : "(no tty)";
|
||||
const char *t = li->line ? li->line : "(no tty)";
|
||||
|
||||
debug("audit session close euid %d user %s tty name %s", geteuid(),
|
||||
audit_username(), t);
|
||||
|
9
audit.h
9
audit.h
@ -1,4 +1,4 @@
|
||||
/* $Id: audit.h,v 1.3 2006/08/05 14:05:10 dtucker Exp $ */
|
||||
/* $Id: audit.h,v 1.4 2011/01/17 10:15:30 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004, 2005 Darren Tucker. All rights reserved.
|
||||
@ -26,6 +26,9 @@
|
||||
|
||||
#ifndef _SSH_AUDIT_H
|
||||
# define _SSH_AUDIT_H
|
||||
|
||||
#include "loginrec.h"
|
||||
|
||||
enum ssh_audit_event_type {
|
||||
SSH_LOGIN_EXCEED_MAXTRIES,
|
||||
SSH_LOGIN_ROOT_DENIED,
|
||||
@ -46,8 +49,8 @@ typedef enum ssh_audit_event_type ssh_audit_event_t;
|
||||
|
||||
void audit_connection_from(const char *, int);
|
||||
void audit_event(ssh_audit_event_t);
|
||||
void audit_session_open(const char *);
|
||||
void audit_session_close(const char *);
|
||||
void audit_session_open(struct logininfo *);
|
||||
void audit_session_close(struct logininfo *);
|
||||
void audit_run_command(const char *);
|
||||
ssh_audit_event_t audit_classify_auth(const char *);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth-options.c,v 1.52 2010/05/20 23:46:02 djm Exp $ */
|
||||
/* $OpenBSD: auth-options.c,v 1.54 2010/12/24 21:41:48 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -172,7 +172,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
|
||||
goto bad_option;
|
||||
}
|
||||
forced_command[i] = '\0';
|
||||
auth_debug_add("Forced command: %.900s", forced_command);
|
||||
auth_debug_add("Forced command.");
|
||||
opts++;
|
||||
goto next_option;
|
||||
}
|
||||
@ -444,7 +444,7 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw,
|
||||
buffer_append(&c, optblob, optblob_len);
|
||||
|
||||
while (buffer_len(&c) > 0) {
|
||||
if ((name = buffer_get_string_ret(&c, &nlen)) == NULL ||
|
||||
if ((name = buffer_get_cstring_ret(&c, &nlen)) == NULL ||
|
||||
(data_blob = buffer_get_string_ret(&c, &dlen)) == NULL) {
|
||||
error("Certificate options corrupt");
|
||||
goto out;
|
||||
@ -479,7 +479,7 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw,
|
||||
}
|
||||
if (!found && (which & OPTIONS_CRITICAL) != 0) {
|
||||
if (strcmp(name, "force-command") == 0) {
|
||||
if ((command = buffer_get_string_ret(&data,
|
||||
if ((command = buffer_get_cstring_ret(&data,
|
||||
&clen)) == NULL) {
|
||||
error("Certificate constraint \"%s\" "
|
||||
"corrupt", name);
|
||||
@ -500,7 +500,7 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw,
|
||||
found = 1;
|
||||
}
|
||||
if (strcmp(name, "source-address") == 0) {
|
||||
if ((allowed = buffer_get_string_ret(&data,
|
||||
if ((allowed = buffer_get_cstring_ret(&data,
|
||||
&clen)) == NULL) {
|
||||
error("Certificate constraint "
|
||||
"\"%s\" corrupt", name);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth-rsa.c,v 1.78 2010/07/13 23:13:16 djm Exp $ */
|
||||
/* $OpenBSD: auth-rsa.c,v 1.79 2010/12/03 23:55:27 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -94,9 +94,6 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16])
|
||||
MD5_CTX md;
|
||||
int len;
|
||||
|
||||
if (auth_key_is_revoked(key))
|
||||
return 0;
|
||||
|
||||
/* don't allow short keys */
|
||||
if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
|
||||
error("auth_rsa_verify_response: RSA modulus too small: %d < minimum %d bits",
|
||||
@ -249,6 +246,10 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
|
||||
"actual %d vs. announced %d.",
|
||||
file, linenum, BN_num_bits(key->rsa->n), bits);
|
||||
|
||||
/* Never accept a revoked key */
|
||||
if (auth_key_is_revoked(key))
|
||||
break;
|
||||
|
||||
/* We have found the desired key. */
|
||||
/*
|
||||
* If our options do not allow this key to be used,
|
||||
|
32
auth.c
32
auth.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth.c,v 1.89 2010/08/04 05:42:47 djm Exp $ */
|
||||
/* $OpenBSD: auth.c,v 1.91 2010/11/29 23:45:51 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -379,16 +379,15 @@ HostStatus
|
||||
check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
|
||||
const char *sysfile, const char *userfile)
|
||||
{
|
||||
Key *found;
|
||||
char *user_hostfile;
|
||||
struct stat st;
|
||||
HostStatus host_status;
|
||||
struct hostkeys *hostkeys;
|
||||
const struct hostkey_entry *found;
|
||||
|
||||
/* Check if we know the host and its host key. */
|
||||
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) {
|
||||
hostkeys = init_hostkeys();
|
||||
load_hostkeys(hostkeys, host, sysfile);
|
||||
if (userfile != NULL) {
|
||||
user_hostfile = tilde_expand_filename(userfile, pw->pw_uid);
|
||||
if (options.strict_modes &&
|
||||
(stat(user_hostfile, &st) == 0) &&
|
||||
@ -401,16 +400,23 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
|
||||
user_hostfile);
|
||||
} else {
|
||||
temporarily_use_uid(pw);
|
||||
host_status = check_host_in_hostfile(user_hostfile,
|
||||
host, key, found, NULL);
|
||||
load_hostkeys(hostkeys, host, user_hostfile);
|
||||
restore_uid();
|
||||
}
|
||||
xfree(user_hostfile);
|
||||
}
|
||||
key_free(found);
|
||||
host_status = check_key_in_hostkeys(hostkeys, key, &found);
|
||||
if (host_status == HOST_REVOKED)
|
||||
error("WARNING: revoked key for %s attempted authentication",
|
||||
found->host);
|
||||
else if (host_status == HOST_OK)
|
||||
debug("%s: key for %s found at %s:%ld", __func__,
|
||||
found->host, found->file, found->line);
|
||||
else
|
||||
debug("%s: key for host %s not found", __func__, host);
|
||||
|
||||
free_hostkeys(hostkeys);
|
||||
|
||||
debug2("check_key_in_hostfiles: key %s for %s", host_status == HOST_OK ?
|
||||
"ok" : "not found", host);
|
||||
return host_status;
|
||||
}
|
||||
|
||||
@ -518,7 +524,7 @@ auth_openfile(const char *file, struct passwd *pw, int strict_modes,
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
if (options.strict_modes &&
|
||||
if (strict_modes &&
|
||||
secure_filename(f, file, pw, line, sizeof(line)) != 0) {
|
||||
fclose(f);
|
||||
logit("Authentication refused: %s", line);
|
||||
|
6
auth1.c
6
auth1.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth1.c,v 1.74 2010/06/25 08:46:17 djm Exp $ */
|
||||
/* $OpenBSD: auth1.c,v 1.75 2010/08/31 09:58:37 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
@ -167,7 +167,7 @@ auth1_process_rhosts_rsa(Authctxt *authctxt, char *info, size_t infolen)
|
||||
* trust the client; root on the client machine can
|
||||
* claim to be any user.
|
||||
*/
|
||||
client_user = packet_get_string(&ulen);
|
||||
client_user = packet_get_cstring(&ulen);
|
||||
|
||||
/* Get the client host key. */
|
||||
client_host_key = key_new(KEY_RSA1);
|
||||
@ -389,7 +389,7 @@ do_authentication(Authctxt *authctxt)
|
||||
packet_read_expect(SSH_CMSG_USER);
|
||||
|
||||
/* Get the user name. */
|
||||
user = packet_get_string(&ulen);
|
||||
user = packet_get_cstring(&ulen);
|
||||
packet_check_eom();
|
||||
|
||||
if ((style = strchr(user, ':')) != NULL)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth2-jpake.c,v 1.3 2009/03/05 07:18:19 djm Exp $ */
|
||||
/* $OpenBSD: auth2-jpake.c,v 1.4 2010/08/31 11:54:45 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008 Damien Miller. All rights reserved.
|
||||
*
|
||||
@ -162,6 +162,11 @@ derive_rawsalt(const char *username, u_char *rawsalt, u_int len)
|
||||
fatal("%s: DSA key missing priv_key", __func__);
|
||||
buffer_put_bignum2(&b, k->dsa->priv_key);
|
||||
break;
|
||||
case KEY_ECDSA:
|
||||
if (EC_KEY_get0_private_key(k->ecdsa) == NULL)
|
||||
fatal("%s: ECDSA key missing priv_key", __func__);
|
||||
buffer_put_bignum2(&b, EC_KEY_get0_private_key(k->ecdsa));
|
||||
break;
|
||||
default:
|
||||
fatal("%s: unknown key type %d", __func__, k->type);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth2-pubkey.c,v 1.26 2010/06/29 23:16:46 djm Exp $ */
|
||||
/* $OpenBSD: auth2-pubkey.c,v 1.27 2010/11/20 05:12:38 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -232,7 +232,7 @@ match_principals_file(char *file, struct passwd *pw, struct KeyCert *cert)
|
||||
if ((ep = strrchr(cp, ' ')) != NULL ||
|
||||
(ep = strrchr(cp, '\t')) != NULL) {
|
||||
for (; *ep == ' ' || *ep == '\t'; ep++)
|
||||
;;
|
||||
;
|
||||
line_opts = cp;
|
||||
cp = ep;
|
||||
}
|
||||
|
10
auth2.c
10
auth2.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth2.c,v 1.121 2009/06/22 05:39:28 dtucker Exp $ */
|
||||
/* $OpenBSD: auth2.c,v 1.122 2010/08/31 09:58:37 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -182,7 +182,7 @@ input_service_request(int type, u_int32_t seq, void *ctxt)
|
||||
Authctxt *authctxt = ctxt;
|
||||
u_int len;
|
||||
int acceptit = 0;
|
||||
char *service = packet_get_string(&len);
|
||||
char *service = packet_get_cstring(&len);
|
||||
packet_check_eom();
|
||||
|
||||
if (authctxt == NULL)
|
||||
@ -221,9 +221,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
|
||||
if (authctxt == NULL)
|
||||
fatal("input_userauth_request: no authctxt");
|
||||
|
||||
user = packet_get_string(NULL);
|
||||
service = packet_get_string(NULL);
|
||||
method = packet_get_string(NULL);
|
||||
user = packet_get_cstring(NULL);
|
||||
service = packet_get_cstring(NULL);
|
||||
method = packet_get_cstring(NULL);
|
||||
debug("userauth-request for user %s service %s method %s", user, service, method);
|
||||
debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
|
||||
|
||||
|
22
authfd.c
22
authfd.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: authfd.c,v 1.83 2010/04/16 01:47:26 djm Exp $ */
|
||||
/* $OpenBSD: authfd.c,v 1.84 2010/08/31 11:54:45 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -509,6 +509,21 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
|
||||
buffer_len(&key->cert->certblob));
|
||||
buffer_put_bignum2(b, key->dsa->priv_key);
|
||||
break;
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
case KEY_ECDSA:
|
||||
buffer_put_cstring(b, key_curve_nid_to_name(key->ecdsa_nid));
|
||||
buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
|
||||
EC_KEY_get0_public_key(key->ecdsa));
|
||||
buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa));
|
||||
break;
|
||||
case KEY_ECDSA_CERT:
|
||||
if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
|
||||
fatal("%s: no cert/certblob", __func__);
|
||||
buffer_put_string(b, buffer_ptr(&key->cert->certblob),
|
||||
buffer_len(&key->cert->certblob));
|
||||
buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa));
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
buffer_put_cstring(b, comment);
|
||||
}
|
||||
@ -541,6 +556,8 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key,
|
||||
case KEY_DSA:
|
||||
case KEY_DSA_CERT:
|
||||
case KEY_DSA_CERT_V00:
|
||||
case KEY_ECDSA:
|
||||
case KEY_ECDSA_CERT:
|
||||
type = constrained ?
|
||||
SSH2_AGENTC_ADD_ID_CONSTRAINED :
|
||||
SSH2_AGENTC_ADD_IDENTITY;
|
||||
@ -589,7 +606,8 @@ ssh_remove_identity(AuthenticationConnection *auth, Key *key)
|
||||
buffer_put_bignum(&msg, key->rsa->e);
|
||||
buffer_put_bignum(&msg, key->rsa->n);
|
||||
} else if (key_type_plain(key->type) == KEY_DSA ||
|
||||
key_type_plain(key->type) == KEY_RSA) {
|
||||
key_type_plain(key->type) == KEY_RSA ||
|
||||
key_type_plain(key->type) == KEY_ECDSA) {
|
||||
key_to_blob(key, &blob, &blen);
|
||||
buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY);
|
||||
buffer_put_string(&msg, blob, blen);
|
||||
|
488
authfile.c
488
authfile.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: authfile.c,v 1.82 2010/08/04 05:49:22 djm Exp $ */
|
||||
/* $OpenBSD: authfile.c,v 1.87 2010/11/29 18:57:04 markus Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -74,19 +74,18 @@ static const char authfile_id_string[] =
|
||||
"SSH PRIVATE KEY FILE FORMAT 1.1\n";
|
||||
|
||||
/*
|
||||
* Saves the authentication (private) key in a file, encrypting it with
|
||||
* passphrase. The identification of the file (lowest 64 bits of n) will
|
||||
* Serialises the authentication (private) key to a blob, encrypting it with
|
||||
* passphrase. The identification of the blob (lowest 64 bits of n) will
|
||||
* precede the key to provide identification of the key without needing a
|
||||
* passphrase.
|
||||
*/
|
||||
|
||||
static int
|
||||
key_save_private_rsa1(Key *key, const char *filename, const char *passphrase,
|
||||
key_private_rsa1_to_blob(Key *key, Buffer *blob, const char *passphrase,
|
||||
const char *comment)
|
||||
{
|
||||
Buffer buffer, encrypted;
|
||||
u_char buf[100], *cp;
|
||||
int fd, i, cipher_num;
|
||||
int i, cipher_num;
|
||||
CipherContext ciphercontext;
|
||||
Cipher *cipher;
|
||||
u_int32_t rnd;
|
||||
@ -157,156 +156,222 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase,
|
||||
memset(buf, 0, sizeof(buf));
|
||||
buffer_free(&buffer);
|
||||
|
||||
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
if (fd < 0) {
|
||||
error("open %s failed: %s.", filename, strerror(errno));
|
||||
buffer_free(&encrypted);
|
||||
return 0;
|
||||
}
|
||||
if (atomicio(vwrite, fd, buffer_ptr(&encrypted),
|
||||
buffer_len(&encrypted)) != buffer_len(&encrypted)) {
|
||||
error("write to key file %s failed: %s", filename,
|
||||
strerror(errno));
|
||||
buffer_free(&encrypted);
|
||||
close(fd);
|
||||
unlink(filename);
|
||||
return 0;
|
||||
}
|
||||
close(fd);
|
||||
buffer_append(blob, buffer_ptr(&encrypted), buffer_len(&encrypted));
|
||||
buffer_free(&encrypted);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* save SSH v2 key in OpenSSL PEM format */
|
||||
/* convert SSH v2 key in OpenSSL PEM format */
|
||||
static int
|
||||
key_save_private_pem(Key *key, const char *filename, const char *_passphrase,
|
||||
key_private_pem_to_blob(Key *key, Buffer *blob, const char *_passphrase,
|
||||
const char *comment)
|
||||
{
|
||||
FILE *fp;
|
||||
int fd;
|
||||
int success = 0;
|
||||
int len = strlen(_passphrase);
|
||||
int blen, len = strlen(_passphrase);
|
||||
u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x00907000L)
|
||||
const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL;
|
||||
#else
|
||||
const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
|
||||
#endif
|
||||
const u_char *bptr;
|
||||
BIO *bio;
|
||||
|
||||
if (len > 0 && len <= 4) {
|
||||
error("passphrase too short: have %d bytes, need > 4", len);
|
||||
return 0;
|
||||
}
|
||||
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
if (fd < 0) {
|
||||
error("open %s failed: %s.", filename, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
fp = fdopen(fd, "w");
|
||||
if (fp == NULL) {
|
||||
error("fdopen %s failed: %s.", filename, strerror(errno));
|
||||
close(fd);
|
||||
if ((bio = BIO_new(BIO_s_mem())) == NULL) {
|
||||
error("%s: BIO_new failed", __func__);
|
||||
return 0;
|
||||
}
|
||||
switch (key->type) {
|
||||
case KEY_DSA:
|
||||
success = PEM_write_DSAPrivateKey(fp, key->dsa,
|
||||
success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
|
||||
cipher, passphrase, len, NULL, NULL);
|
||||
break;
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
case KEY_ECDSA:
|
||||
success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
|
||||
cipher, passphrase, len, NULL, NULL);
|
||||
break;
|
||||
#endif
|
||||
case KEY_RSA:
|
||||
success = PEM_write_RSAPrivateKey(fp, key->rsa,
|
||||
success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
|
||||
cipher, passphrase, len, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
fclose(fp);
|
||||
if (success) {
|
||||
if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0)
|
||||
success = 0;
|
||||
else
|
||||
buffer_append(blob, bptr, blen);
|
||||
}
|
||||
BIO_free(bio);
|
||||
return success;
|
||||
}
|
||||
|
||||
/* Save a key blob to a file */
|
||||
static int
|
||||
key_save_private_blob(Buffer *keybuf, const char *filename)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0) {
|
||||
error("open %s failed: %s.", filename, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if (atomicio(vwrite, fd, buffer_ptr(keybuf),
|
||||
buffer_len(keybuf)) != buffer_len(keybuf)) {
|
||||
error("write to key file %s failed: %s", filename,
|
||||
strerror(errno));
|
||||
close(fd);
|
||||
unlink(filename);
|
||||
return 0;
|
||||
}
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Serialise "key" to buffer "blob" */
|
||||
static int
|
||||
key_private_to_blob(Key *key, Buffer *blob, const char *passphrase,
|
||||
const char *comment)
|
||||
{
|
||||
switch (key->type) {
|
||||
case KEY_RSA1:
|
||||
return key_private_rsa1_to_blob(key, blob, passphrase, comment);
|
||||
case KEY_DSA:
|
||||
case KEY_ECDSA:
|
||||
case KEY_RSA:
|
||||
return key_private_pem_to_blob(key, blob, passphrase, comment);
|
||||
default:
|
||||
error("%s: cannot save key type %d", __func__, key->type);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
key_save_private(Key *key, const char *filename, const char *passphrase,
|
||||
const char *comment)
|
||||
{
|
||||
switch (key->type) {
|
||||
case KEY_RSA1:
|
||||
return key_save_private_rsa1(key, filename, passphrase,
|
||||
comment);
|
||||
case KEY_DSA:
|
||||
case KEY_RSA:
|
||||
return key_save_private_pem(key, filename, passphrase,
|
||||
comment);
|
||||
default:
|
||||
break;
|
||||
Buffer keyblob;
|
||||
int success = 0;
|
||||
|
||||
buffer_init(&keyblob);
|
||||
if (!key_private_to_blob(key, &keyblob, passphrase, comment))
|
||||
goto out;
|
||||
if (!key_save_private_blob(&keyblob, filename))
|
||||
goto out;
|
||||
success = 1;
|
||||
out:
|
||||
buffer_free(&keyblob);
|
||||
return success;
|
||||
}
|
||||
error("key_save_private: cannot save key type %d", key->type);
|
||||
|
||||
/*
|
||||
* Parse the public, unencrypted portion of a RSA1 key.
|
||||
*/
|
||||
static Key *
|
||||
key_parse_public_rsa1(Buffer *blob, char **commentp)
|
||||
{
|
||||
Key *pub;
|
||||
|
||||
/* Check that it is at least big enough to contain the ID string. */
|
||||
if (buffer_len(blob) < sizeof(authfile_id_string)) {
|
||||
debug3("Truncated RSA1 identifier");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure it begins with the id string. Consume the id string
|
||||
* from the buffer.
|
||||
*/
|
||||
if (memcmp(buffer_ptr(blob), authfile_id_string,
|
||||
sizeof(authfile_id_string)) != 0) {
|
||||
debug3("Incorrect RSA1 identifier");
|
||||
return NULL;
|
||||
}
|
||||
buffer_consume(blob, sizeof(authfile_id_string));
|
||||
|
||||
/* Skip cipher type and reserved data. */
|
||||
(void) buffer_get_char(blob); /* cipher type */
|
||||
(void) buffer_get_int(blob); /* reserved */
|
||||
|
||||
/* Read the public key from the buffer. */
|
||||
(void) buffer_get_int(blob);
|
||||
pub = key_new(KEY_RSA1);
|
||||
buffer_get_bignum(blob, pub->rsa->n);
|
||||
buffer_get_bignum(blob, pub->rsa->e);
|
||||
if (commentp)
|
||||
*commentp = buffer_get_string(blob, NULL);
|
||||
/* The encrypted private part is not parsed by this function. */
|
||||
buffer_clear(blob);
|
||||
|
||||
return pub;
|
||||
}
|
||||
|
||||
/* Load the contents of a key file into a buffer */
|
||||
static int
|
||||
key_load_file(int fd, const char *filename, Buffer *blob)
|
||||
{
|
||||
size_t len;
|
||||
u_char *cp;
|
||||
struct stat st;
|
||||
|
||||
if (fstat(fd, &st) < 0) {
|
||||
error("%s: fstat of key file %.200s%sfailed: %.100s", __func__,
|
||||
filename == NULL ? "" : filename,
|
||||
filename == NULL ? "" : " ",
|
||||
strerror(errno));
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
if (st.st_size > 1*1024*1024) {
|
||||
error("%s: key file %.200s%stoo large", __func__,
|
||||
filename == NULL ? "" : filename,
|
||||
filename == NULL ? "" : " ");
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
len = (size_t)st.st_size; /* truncated */
|
||||
|
||||
buffer_init(blob);
|
||||
cp = buffer_append_space(blob, len);
|
||||
|
||||
if (atomicio(read, fd, cp, len) != len) {
|
||||
debug("%s: read from key file %.200s%sfailed: %.100s", __func__,
|
||||
filename == NULL ? "" : filename,
|
||||
filename == NULL ? "" : " ",
|
||||
strerror(errno));
|
||||
buffer_clear(blob);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads the public part of the ssh v1 key file. Returns NULL if an error was
|
||||
* encountered (the file does not exist or is not readable), and the key
|
||||
* otherwise.
|
||||
*/
|
||||
|
||||
static Key *
|
||||
key_load_public_rsa1(int fd, const char *filename, char **commentp)
|
||||
{
|
||||
Buffer buffer;
|
||||
Key *pub;
|
||||
struct stat st;
|
||||
char *cp;
|
||||
u_int i;
|
||||
size_t len;
|
||||
|
||||
if (fstat(fd, &st) < 0) {
|
||||
error("fstat for key file %.200s failed: %.100s",
|
||||
filename, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
if (st.st_size > 1*1024*1024) {
|
||||
error("key file %.200s too large", filename);
|
||||
return NULL;
|
||||
}
|
||||
len = (size_t)st.st_size; /* truncated */
|
||||
|
||||
buffer_init(&buffer);
|
||||
cp = buffer_append_space(&buffer, len);
|
||||
|
||||
if (atomicio(read, fd, cp, len) != len) {
|
||||
debug("Read from key file %.200s failed: %.100s", filename,
|
||||
strerror(errno));
|
||||
if (!key_load_file(fd, filename, &buffer)) {
|
||||
buffer_free(&buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check that it is at least big enough to contain the ID string. */
|
||||
if (len < sizeof(authfile_id_string)) {
|
||||
debug3("Not a RSA1 key file %.200s.", filename);
|
||||
buffer_free(&buffer);
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
* Make sure it begins with the id string. Consume the id string
|
||||
* from the buffer.
|
||||
*/
|
||||
for (i = 0; i < sizeof(authfile_id_string); i++)
|
||||
if (buffer_get_char(&buffer) != authfile_id_string[i]) {
|
||||
debug3("Not a RSA1 key file %.200s.", filename);
|
||||
buffer_free(&buffer);
|
||||
return NULL;
|
||||
}
|
||||
/* Skip cipher type and reserved data. */
|
||||
(void) buffer_get_char(&buffer); /* cipher type */
|
||||
(void) buffer_get_int(&buffer); /* reserved */
|
||||
|
||||
/* Read the public key from the buffer. */
|
||||
(void) buffer_get_int(&buffer);
|
||||
pub = key_new(KEY_RSA1);
|
||||
buffer_get_bignum(&buffer, pub->rsa->n);
|
||||
buffer_get_bignum(&buffer, pub->rsa->e);
|
||||
if (commentp)
|
||||
*commentp = buffer_get_string(&buffer, NULL);
|
||||
/* The encrypted private part is not parsed by this function. */
|
||||
|
||||
pub = key_parse_public_rsa1(&buffer, commentp);
|
||||
if (pub == NULL)
|
||||
debug3("Could not load \"%s\" as a RSA1 public key", filename);
|
||||
buffer_free(&buffer);
|
||||
return pub;
|
||||
}
|
||||
@ -329,113 +394,73 @@ key_load_public_type(int type, const char *filename, char **commentp)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads the private key from the file. Returns 0 if an error is encountered
|
||||
* (file does not exist or is not readable, or passphrase is bad). This
|
||||
* initializes the private key.
|
||||
* Assumes we are called under uid of the owner of the file.
|
||||
*/
|
||||
|
||||
static Key *
|
||||
key_load_private_rsa1(int fd, const char *filename, const char *passphrase,
|
||||
char **commentp)
|
||||
key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp)
|
||||
{
|
||||
u_int i;
|
||||
int check1, check2, cipher_type;
|
||||
size_t len;
|
||||
Buffer buffer, decrypted;
|
||||
Buffer decrypted;
|
||||
u_char *cp;
|
||||
CipherContext ciphercontext;
|
||||
Cipher *cipher;
|
||||
Key *prv = NULL;
|
||||
struct stat st;
|
||||
|
||||
if (fstat(fd, &st) < 0) {
|
||||
error("fstat for key file %.200s failed: %.100s",
|
||||
filename, strerror(errno));
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
if (st.st_size > 1*1024*1024) {
|
||||
error("key file %.200s too large", filename);
|
||||
close(fd);
|
||||
return (NULL);
|
||||
}
|
||||
len = (size_t)st.st_size; /* truncated */
|
||||
|
||||
buffer_init(&buffer);
|
||||
cp = buffer_append_space(&buffer, len);
|
||||
|
||||
if (atomicio(read, fd, cp, len) != len) {
|
||||
debug("Read from key file %.200s failed: %.100s", filename,
|
||||
strerror(errno));
|
||||
buffer_free(&buffer);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check that it is at least big enough to contain the ID string. */
|
||||
if (len < sizeof(authfile_id_string)) {
|
||||
debug3("Not a RSA1 key file %.200s.", filename);
|
||||
buffer_free(&buffer);
|
||||
close(fd);
|
||||
if (buffer_len(blob) < sizeof(authfile_id_string)) {
|
||||
debug3("Truncated RSA1 identifier");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure it begins with the id string. Consume the id string
|
||||
* from the buffer.
|
||||
*/
|
||||
for (i = 0; i < sizeof(authfile_id_string); i++)
|
||||
if (buffer_get_char(&buffer) != authfile_id_string[i]) {
|
||||
debug3("Not a RSA1 key file %.200s.", filename);
|
||||
buffer_free(&buffer);
|
||||
close(fd);
|
||||
if (memcmp(buffer_ptr(blob), authfile_id_string,
|
||||
sizeof(authfile_id_string)) != 0) {
|
||||
debug3("Incorrect RSA1 identifier");
|
||||
return NULL;
|
||||
}
|
||||
buffer_consume(blob, sizeof(authfile_id_string));
|
||||
|
||||
/* Read cipher type. */
|
||||
cipher_type = buffer_get_char(&buffer);
|
||||
(void) buffer_get_int(&buffer); /* Reserved data. */
|
||||
cipher_type = buffer_get_char(blob);
|
||||
(void) buffer_get_int(blob); /* Reserved data. */
|
||||
|
||||
/* Read the public key from the buffer. */
|
||||
(void) buffer_get_int(&buffer);
|
||||
(void) buffer_get_int(blob);
|
||||
prv = key_new_private(KEY_RSA1);
|
||||
|
||||
buffer_get_bignum(&buffer, prv->rsa->n);
|
||||
buffer_get_bignum(&buffer, prv->rsa->e);
|
||||
buffer_get_bignum(blob, prv->rsa->n);
|
||||
buffer_get_bignum(blob, prv->rsa->e);
|
||||
if (commentp)
|
||||
*commentp = buffer_get_string(&buffer, NULL);
|
||||
*commentp = buffer_get_string(blob, NULL);
|
||||
else
|
||||
xfree(buffer_get_string(&buffer, NULL));
|
||||
(void)buffer_get_string_ptr(blob, NULL);
|
||||
|
||||
/* Check that it is a supported cipher. */
|
||||
cipher = cipher_by_number(cipher_type);
|
||||
if (cipher == NULL) {
|
||||
debug("Unsupported cipher %d used in key file %.200s.",
|
||||
cipher_type, filename);
|
||||
buffer_free(&buffer);
|
||||
debug("Unsupported RSA1 cipher %d", cipher_type);
|
||||
goto fail;
|
||||
}
|
||||
/* Initialize space for decrypted data. */
|
||||
buffer_init(&decrypted);
|
||||
cp = buffer_append_space(&decrypted, buffer_len(&buffer));
|
||||
cp = buffer_append_space(&decrypted, buffer_len(blob));
|
||||
|
||||
/* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
|
||||
cipher_set_key_string(&ciphercontext, cipher, passphrase,
|
||||
CIPHER_DECRYPT);
|
||||
cipher_crypt(&ciphercontext, cp,
|
||||
buffer_ptr(&buffer), buffer_len(&buffer));
|
||||
buffer_ptr(blob), buffer_len(blob));
|
||||
cipher_cleanup(&ciphercontext);
|
||||
memset(&ciphercontext, 0, sizeof(ciphercontext));
|
||||
buffer_free(&buffer);
|
||||
buffer_clear(blob);
|
||||
|
||||
check1 = buffer_get_char(&decrypted);
|
||||
check2 = buffer_get_char(&decrypted);
|
||||
if (check1 != buffer_get_char(&decrypted) ||
|
||||
check2 != buffer_get_char(&decrypted)) {
|
||||
if (strcmp(passphrase, "") != 0)
|
||||
debug("Bad passphrase supplied for key file %.200s.",
|
||||
filename);
|
||||
debug("Bad passphrase supplied for RSA1 key");
|
||||
/* Bad passphrase. */
|
||||
buffer_free(&decrypted);
|
||||
goto fail;
|
||||
@ -454,38 +479,37 @@ key_load_private_rsa1(int fd, const char *filename, const char *passphrase,
|
||||
|
||||
/* enable blinding */
|
||||
if (RSA_blinding_on(prv->rsa, NULL) != 1) {
|
||||
error("key_load_private_rsa1: RSA_blinding_on failed");
|
||||
error("%s: RSA_blinding_on failed", __func__);
|
||||
goto fail;
|
||||
}
|
||||
close(fd);
|
||||
return prv;
|
||||
|
||||
fail:
|
||||
if (commentp)
|
||||
xfree(*commentp);
|
||||
close(fd);
|
||||
key_free(prv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Key *
|
||||
key_load_private_pem(int fd, int type, const char *passphrase,
|
||||
static Key *
|
||||
key_parse_private_pem(Buffer *blob, int type, const char *passphrase,
|
||||
char **commentp)
|
||||
{
|
||||
FILE *fp;
|
||||
EVP_PKEY *pk = NULL;
|
||||
Key *prv = NULL;
|
||||
char *name = "<no key>";
|
||||
BIO *bio;
|
||||
|
||||
fp = fdopen(fd, "r");
|
||||
if (fp == NULL) {
|
||||
error("fdopen failed: %s", strerror(errno));
|
||||
close(fd);
|
||||
if ((bio = BIO_new_mem_buf(buffer_ptr(blob),
|
||||
buffer_len(blob))) == NULL) {
|
||||
error("%s: BIO_new_mem_buf failed", __func__);
|
||||
return NULL;
|
||||
}
|
||||
pk = PEM_read_PrivateKey(fp, NULL, NULL, (char *)passphrase);
|
||||
|
||||
pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, (char *)passphrase);
|
||||
BIO_free(bio);
|
||||
if (pk == NULL) {
|
||||
debug("PEM_read_PrivateKey failed");
|
||||
debug("%s: PEM_read_PrivateKey failed", __func__);
|
||||
(void)ERR_get_error();
|
||||
} else if (pk->type == EVP_PKEY_RSA &&
|
||||
(type == KEY_UNSPEC||type==KEY_RSA)) {
|
||||
@ -497,7 +521,7 @@ key_load_private_pem(int fd, int type, const char *passphrase,
|
||||
RSA_print_fp(stderr, prv->rsa, 8);
|
||||
#endif
|
||||
if (RSA_blinding_on(prv->rsa, NULL) != 1) {
|
||||
error("key_load_private_pem: RSA_blinding_on failed");
|
||||
error("%s: RSA_blinding_on failed", __func__);
|
||||
key_free(prv);
|
||||
prv = NULL;
|
||||
}
|
||||
@ -510,11 +534,31 @@ key_load_private_pem(int fd, int type, const char *passphrase,
|
||||
#ifdef DEBUG_PK
|
||||
DSA_print_fp(stderr, prv->dsa, 8);
|
||||
#endif
|
||||
} else {
|
||||
error("PEM_read_PrivateKey: mismatch or "
|
||||
"unknown EVP_PKEY save_type %d", pk->save_type);
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
} else if (pk->type == EVP_PKEY_EC &&
|
||||
(type == KEY_UNSPEC||type==KEY_ECDSA)) {
|
||||
prv = key_new(KEY_UNSPEC);
|
||||
prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk);
|
||||
prv->type = KEY_ECDSA;
|
||||
if ((prv->ecdsa_nid = key_ecdsa_key_to_nid(prv->ecdsa)) == -1 ||
|
||||
key_curve_nid_to_name(prv->ecdsa_nid) == NULL ||
|
||||
key_ec_validate_public(EC_KEY_get0_group(prv->ecdsa),
|
||||
EC_KEY_get0_public_key(prv->ecdsa)) != 0 ||
|
||||
key_ec_validate_private(prv->ecdsa) != 0) {
|
||||
error("%s: bad ECDSA key", __func__);
|
||||
key_free(prv);
|
||||
prv = NULL;
|
||||
}
|
||||
name = "ecdsa w/o comment";
|
||||
#ifdef DEBUG_PK
|
||||
if (prv != NULL && prv->ecdsa != NULL)
|
||||
key_dump_ec_key(prv->ecdsa);
|
||||
#endif
|
||||
#endif /* OPENSSL_HAS_ECC */
|
||||
} else {
|
||||
error("%s: PEM_read_PrivateKey: mismatch or "
|
||||
"unknown EVP_PKEY save_type %d", __func__, pk->save_type);
|
||||
}
|
||||
fclose(fp);
|
||||
if (pk != NULL)
|
||||
EVP_PKEY_free(pk);
|
||||
if (prv != NULL && commentp)
|
||||
@ -524,6 +568,23 @@ key_load_private_pem(int fd, int type, const char *passphrase,
|
||||
return prv;
|
||||
}
|
||||
|
||||
Key *
|
||||
key_load_private_pem(int fd, int type, const char *passphrase,
|
||||
char **commentp)
|
||||
{
|
||||
Buffer buffer;
|
||||
Key *prv;
|
||||
|
||||
buffer_init(&buffer);
|
||||
if (!key_load_file(fd, NULL, &buffer)) {
|
||||
buffer_free(&buffer);
|
||||
return NULL;
|
||||
}
|
||||
prv = key_parse_private_pem(&buffer, type, passphrase, commentp);
|
||||
buffer_free(&buffer);
|
||||
return prv;
|
||||
}
|
||||
|
||||
int
|
||||
key_perm_ok(int fd, const char *filename)
|
||||
{
|
||||
@ -552,11 +613,31 @@ key_perm_ok(int fd, const char *filename)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static Key *
|
||||
key_parse_private_type(Buffer *blob, int type, const char *passphrase,
|
||||
char **commentp)
|
||||
{
|
||||
switch (type) {
|
||||
case KEY_RSA1:
|
||||
return key_parse_private_rsa1(blob, passphrase, commentp);
|
||||
case KEY_DSA:
|
||||
case KEY_ECDSA:
|
||||
case KEY_RSA:
|
||||
case KEY_UNSPEC:
|
||||
return key_parse_private_pem(blob, type, passphrase, commentp);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Key *
|
||||
key_load_private_type(int type, const char *filename, const char *passphrase,
|
||||
char **commentp, int *perm_ok)
|
||||
{
|
||||
int fd;
|
||||
Key *ret;
|
||||
Buffer buffer;
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
@ -575,28 +656,25 @@ key_load_private_type(int type, const char *filename, const char *passphrase,
|
||||
}
|
||||
if (perm_ok != NULL)
|
||||
*perm_ok = 1;
|
||||
switch (type) {
|
||||
case KEY_RSA1:
|
||||
return key_load_private_rsa1(fd, filename, passphrase,
|
||||
commentp);
|
||||
/* closes fd */
|
||||
case KEY_DSA:
|
||||
case KEY_RSA:
|
||||
case KEY_UNSPEC:
|
||||
return key_load_private_pem(fd, type, passphrase, commentp);
|
||||
/* closes fd */
|
||||
default:
|
||||
|
||||
buffer_init(&buffer);
|
||||
if (!key_load_file(fd, filename, &buffer)) {
|
||||
buffer_free(&buffer);
|
||||
close(fd);
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
close(fd);
|
||||
ret = key_parse_private_type(&buffer, type, passphrase, commentp);
|
||||
buffer_free(&buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Key *
|
||||
key_load_private(const char *filename, const char *passphrase,
|
||||
char **commentp)
|
||||
{
|
||||
Key *pub, *prv;
|
||||
Buffer buffer, pubcopy;
|
||||
int fd;
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
@ -610,20 +688,33 @@ key_load_private(const char *filename, const char *passphrase,
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
pub = key_load_public_rsa1(fd, filename, commentp);
|
||||
lseek(fd, (off_t) 0, SEEK_SET); /* rewind */
|
||||
|
||||
buffer_init(&buffer);
|
||||
if (!key_load_file(fd, filename, &buffer)) {
|
||||
buffer_free(&buffer);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
buffer_init(&pubcopy);
|
||||
buffer_append(&pubcopy, buffer_ptr(&buffer), buffer_len(&buffer));
|
||||
/* it's a SSH v1 key if the public key part is readable */
|
||||
pub = key_parse_public_rsa1(&pubcopy, commentp);
|
||||
buffer_free(&pubcopy);
|
||||
if (pub == NULL) {
|
||||
/* closes fd */
|
||||
prv = key_load_private_pem(fd, KEY_UNSPEC, passphrase, NULL);
|
||||
prv = key_parse_private_type(&buffer, KEY_UNSPEC,
|
||||
passphrase, NULL);
|
||||
/* use the filename as a comment for PEM */
|
||||
if (commentp && prv)
|
||||
*commentp = xstrdup(filename);
|
||||
} else {
|
||||
/* it's a SSH v1 key if the public key part is readable */
|
||||
key_free(pub);
|
||||
/* closes fd */
|
||||
prv = key_load_private_rsa1(fd, filename, passphrase, NULL);
|
||||
/* key_parse_public_rsa1() has already loaded the comment */
|
||||
prv = key_parse_private_type(&buffer, KEY_RSA1, passphrase,
|
||||
NULL);
|
||||
}
|
||||
buffer_free(&buffer);
|
||||
return prv;
|
||||
}
|
||||
|
||||
@ -721,6 +812,7 @@ key_load_private_cert(int type, const char *filename, const char *passphrase,
|
||||
switch (type) {
|
||||
case KEY_RSA:
|
||||
case KEY_DSA:
|
||||
case KEY_ECDSA:
|
||||
break;
|
||||
default:
|
||||
error("%s: unsupported key type", __func__);
|
||||
|
35
bufaux.c
35
bufaux.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: bufaux.c,v 1.49 2010/03/26 03:13:17 djm Exp $ */
|
||||
/* $OpenBSD: bufaux.c,v 1.50 2010/08/31 09:58:37 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -202,6 +202,39 @@ buffer_get_string(Buffer *buffer, u_int *length_ptr)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
char *
|
||||
buffer_get_cstring_ret(Buffer *buffer, u_int *length_ptr)
|
||||
{
|
||||
u_int length;
|
||||
char *cp, *ret = buffer_get_string_ret(buffer, &length);
|
||||
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
if ((cp = memchr(ret, '\0', length)) != NULL) {
|
||||
/* XXX allow \0 at end-of-string for a while, remove later */
|
||||
if (cp == ret + length - 1)
|
||||
error("buffer_get_cstring_ret: string contains \\0");
|
||||
else {
|
||||
bzero(ret, length);
|
||||
xfree(ret);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (length_ptr != NULL)
|
||||
*length_ptr = length;
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
buffer_get_cstring(Buffer *buffer, u_int *length_ptr)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
if ((ret = buffer_get_cstring_ret(buffer, length_ptr)) == NULL)
|
||||
fatal("buffer_get_cstring: buffer error");
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *
|
||||
buffer_get_string_ptr_ret(Buffer *buffer, u_int *length_ptr)
|
||||
{
|
||||
|
146
bufec.c
Normal file
146
bufec.c
Normal file
@ -0,0 +1,146 @@
|
||||
/* $OpenBSD: bufec.c,v 1.1 2010/08/31 11:54:45 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/ec.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
|
||||
/*
|
||||
* Maximum supported EC GFp field length is 528 bits. SEC1 uncompressed
|
||||
* encoding represents this as two bitstring points that should each
|
||||
* be no longer than the field length, SEC1 specifies a 1 byte
|
||||
* point type header.
|
||||
* Being paranoid here may insulate us to parsing problems in
|
||||
* EC_POINT_oct2point.
|
||||
*/
|
||||
#define BUFFER_MAX_ECPOINT_LEN ((528*2 / 8) + 1)
|
||||
|
||||
/*
|
||||
* Append an EC_POINT to the buffer as a string containing a SEC1 encoded
|
||||
* uncompressed point. Fortunately OpenSSL handles the gory details for us.
|
||||
*/
|
||||
int
|
||||
buffer_put_ecpoint_ret(Buffer *buffer, const EC_GROUP *curve,
|
||||
const EC_POINT *point)
|
||||
{
|
||||
u_char *buf = NULL;
|
||||
size_t len;
|
||||
BN_CTX *bnctx;
|
||||
int ret = -1;
|
||||
|
||||
/* Determine length */
|
||||
if ((bnctx = BN_CTX_new()) == NULL)
|
||||
fatal("%s: BN_CTX_new failed", __func__);
|
||||
len = EC_POINT_point2oct(curve, point, POINT_CONVERSION_UNCOMPRESSED,
|
||||
NULL, 0, bnctx);
|
||||
if (len > BUFFER_MAX_ECPOINT_LEN) {
|
||||
error("%s: giant EC point: len = %lu (max %u)",
|
||||
__func__, (u_long)len, BUFFER_MAX_ECPOINT_LEN);
|
||||
goto out;
|
||||
}
|
||||
/* Convert */
|
||||
buf = xmalloc(len);
|
||||
if (EC_POINT_point2oct(curve, point, POINT_CONVERSION_UNCOMPRESSED,
|
||||
buf, len, bnctx) != len) {
|
||||
error("%s: EC_POINT_point2oct length mismatch", __func__);
|
||||
goto out;
|
||||
}
|
||||
/* Append */
|
||||
buffer_put_string(buffer, buf, len);
|
||||
ret = 0;
|
||||
out:
|
||||
if (buf != NULL) {
|
||||
bzero(buf, len);
|
||||
xfree(buf);
|
||||
}
|
||||
BN_CTX_free(bnctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
buffer_put_ecpoint(Buffer *buffer, const EC_GROUP *curve,
|
||||
const EC_POINT *point)
|
||||
{
|
||||
if (buffer_put_ecpoint_ret(buffer, curve, point) == -1)
|
||||
fatal("%s: buffer error", __func__);
|
||||
}
|
||||
|
||||
int
|
||||
buffer_get_ecpoint_ret(Buffer *buffer, const EC_GROUP *curve,
|
||||
EC_POINT *point)
|
||||
{
|
||||
u_char *buf;
|
||||
u_int len;
|
||||
BN_CTX *bnctx;
|
||||
int ret = -1;
|
||||
|
||||
if ((buf = buffer_get_string_ret(buffer, &len)) == NULL) {
|
||||
error("%s: invalid point", __func__);
|
||||
return -1;
|
||||
}
|
||||
if ((bnctx = BN_CTX_new()) == NULL)
|
||||
fatal("%s: BN_CTX_new failed", __func__);
|
||||
if (len > BUFFER_MAX_ECPOINT_LEN) {
|
||||
error("%s: EC_POINT too long: %u > max %u", __func__,
|
||||
len, BUFFER_MAX_ECPOINT_LEN);
|
||||
goto out;
|
||||
}
|
||||
if (len == 0) {
|
||||
error("%s: EC_POINT buffer is empty", __func__);
|
||||
goto out;
|
||||
}
|
||||
if (buf[0] != POINT_CONVERSION_UNCOMPRESSED) {
|
||||
error("%s: EC_POINT is in an incorrect form: "
|
||||
"0x%02x (want 0x%02x)", __func__, buf[0],
|
||||
POINT_CONVERSION_UNCOMPRESSED);
|
||||
goto out;
|
||||
}
|
||||
if (EC_POINT_oct2point(curve, point, buf, len, bnctx) != 1) {
|
||||
error("buffer_get_bignum2_ret: BN_bin2bn failed");
|
||||
goto out;
|
||||
}
|
||||
/* EC_POINT_oct2point verifies that the point is on the curve for us */
|
||||
ret = 0;
|
||||
out:
|
||||
BN_CTX_free(bnctx);
|
||||
bzero(buf, len);
|
||||
xfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
buffer_get_ecpoint(Buffer *buffer, const EC_GROUP *curve,
|
||||
EC_POINT *point)
|
||||
{
|
||||
if (buffer_get_ecpoint_ret(buffer, curve, point) == -1)
|
||||
fatal("%s: buffer error", __func__);
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_HAS_ECC */
|
13
buffer.h
13
buffer.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: buffer.h,v 1.19 2010/02/09 03:56:28 djm Exp $ */
|
||||
/* $OpenBSD: buffer.h,v 1.21 2010/08/31 11:54:45 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -68,6 +68,7 @@ void buffer_put_char(Buffer *, int);
|
||||
void *buffer_get_string(Buffer *, u_int *);
|
||||
void *buffer_get_string_ptr(Buffer *, u_int *);
|
||||
void buffer_put_string(Buffer *, const void *, u_int);
|
||||
char *buffer_get_cstring(Buffer *, u_int *);
|
||||
void buffer_put_cstring(Buffer *, const char *);
|
||||
|
||||
#define buffer_skip_string(b) \
|
||||
@ -81,7 +82,17 @@ int buffer_get_short_ret(u_short *, Buffer *);
|
||||
int buffer_get_int_ret(u_int *, Buffer *);
|
||||
int buffer_get_int64_ret(u_int64_t *, Buffer *);
|
||||
void *buffer_get_string_ret(Buffer *, u_int *);
|
||||
char *buffer_get_cstring_ret(Buffer *, u_int *);
|
||||
void *buffer_get_string_ptr_ret(Buffer *, u_int *);
|
||||
int buffer_get_char_ret(char *, Buffer *);
|
||||
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
#include <openssl/ec.h>
|
||||
|
||||
int buffer_put_ecpoint_ret(Buffer *, const EC_GROUP *, const EC_POINT *);
|
||||
void buffer_put_ecpoint(Buffer *, const EC_GROUP *, const EC_POINT *);
|
||||
int buffer_get_ecpoint_ret(Buffer *, const EC_GROUP *, EC_POINT *);
|
||||
void buffer_get_ecpoint(Buffer *, const EC_GROUP *, EC_POINT *);
|
||||
#endif
|
||||
|
||||
#endif /* BUFFER_H */
|
||||
|
@ -199,7 +199,7 @@ ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len)
|
||||
memcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr));
|
||||
port = a6->sin6_port;
|
||||
|
||||
memset(addr, 0, sizeof(*a4));
|
||||
bzero(a4, sizeof(*a4));
|
||||
|
||||
a4->sin_family = AF_INET;
|
||||
*len = sizeof(*a4);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: channels.c,v 1.309 2010/08/05 13:08:42 djm Exp $ */
|
||||
/* $OpenBSD: channels.c,v 1.310 2010/11/24 01:24:14 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -373,9 +373,6 @@ channel_close_fd(int *fdp)
|
||||
static void
|
||||
channel_close_fds(Channel *c)
|
||||
{
|
||||
debug3("channel %d: close_fds r %d w %d e %d",
|
||||
c->self, c->rfd, c->wfd, c->efd);
|
||||
|
||||
channel_close_fd(&c->sock);
|
||||
channel_close_fd(&c->rfd);
|
||||
channel_close_fd(&c->wfd);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: cipher-3des1.c,v 1.6 2006/08/03 03:34:42 deraadt Exp $ */
|
||||
/* $OpenBSD: cipher-3des1.c,v 1.7 2010/10/01 23:05:32 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -103,7 +103,8 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
|
||||
}
|
||||
|
||||
static int
|
||||
ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len)
|
||||
ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
|
||||
LIBCRYPTO_EVP_INL_TYPE len)
|
||||
{
|
||||
struct ssh1_3des_ctx *c;
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#if !defined(EVP_CTRL_SET_ACSS_MODE) && (OPENSSL_VERSION_NUMBER >= 0x00907000L)
|
||||
|
||||
#include "acss.h"
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
|
||||
#define data(ctx) ((EVP_ACSS_KEY *)(ctx)->cipher_data)
|
||||
|
||||
@ -43,7 +44,7 @@ acss_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
|
||||
static int
|
||||
acss_ciph(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
|
||||
unsigned int inl)
|
||||
LIBCRYPTO_EVP_INL_TYPE inl)
|
||||
{
|
||||
acss(&data(ctx)->ks,inl,in,out);
|
||||
return 1;
|
||||
|
@ -72,7 +72,7 @@ ssh_rijndael_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
|
||||
|
||||
static int
|
||||
ssh_rijndael_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
|
||||
u_int len)
|
||||
LIBCRYPTO_EVP_INL_TYPE len)
|
||||
{
|
||||
struct ssh_rijndael_ctx *c;
|
||||
u_char buf[RIJNDAEL_BLOCKSIZE];
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: cipher-bf1.c,v 1.5 2006/08/03 03:34:42 deraadt Exp $ */
|
||||
/* $OpenBSD: cipher-bf1.c,v 1.6 2010/10/01 23:05:32 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -76,10 +76,12 @@ static void bf_ssh1_init (EVP_CIPHER_CTX * ctx, const unsigned char *key,
|
||||
}
|
||||
#endif
|
||||
|
||||
static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *, const u_char *, u_int) = NULL;
|
||||
static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *,
|
||||
const u_char *, LIBCRYPTO_EVP_INL_TYPE) = NULL;
|
||||
|
||||
static int
|
||||
bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in, u_int len)
|
||||
bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in,
|
||||
LIBCRYPTO_EVP_INL_TYPE len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
12
cipher-ctr.c
12
cipher-ctr.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: cipher-ctr.c,v 1.10 2006/08/03 03:34:42 deraadt Exp $ */
|
||||
/* $OpenBSD: cipher-ctr.c,v 1.11 2010/10/01 23:05:32 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
|
||||
*
|
||||
@ -34,7 +34,7 @@
|
||||
#endif
|
||||
|
||||
const EVP_CIPHER *evp_aes_128_ctr(void);
|
||||
void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
|
||||
void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, size_t);
|
||||
|
||||
struct ssh_aes_ctr_ctx
|
||||
{
|
||||
@ -48,7 +48,7 @@ struct ssh_aes_ctr_ctx
|
||||
* (LSB at ctr[len-1], MSB at ctr[0])
|
||||
*/
|
||||
static void
|
||||
ssh_ctr_inc(u_char *ctr, u_int len)
|
||||
ssh_ctr_inc(u_char *ctr, size_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -59,10 +59,10 @@ ssh_ctr_inc(u_char *ctr, u_int len)
|
||||
|
||||
static int
|
||||
ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
|
||||
u_int len)
|
||||
LIBCRYPTO_EVP_INL_TYPE len)
|
||||
{
|
||||
struct ssh_aes_ctr_ctx *c;
|
||||
u_int n = 0;
|
||||
size_t n = 0;
|
||||
u_char buf[AES_BLOCK_SIZE];
|
||||
|
||||
if (len == 0)
|
||||
@ -113,7 +113,7 @@ ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
|
||||
}
|
||||
|
||||
void
|
||||
ssh_aes_ctr_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, u_int len)
|
||||
ssh_aes_ctr_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, size_t len)
|
||||
{
|
||||
struct ssh_aes_ctr_ctx *c;
|
||||
|
||||
|
36
clientloop.c
36
clientloop.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: clientloop.c,v 1.222 2010/07/19 09:15:12 djm Exp $ */
|
||||
/* $OpenBSD: clientloop.c,v 1.231 2011/01/16 12:05:59 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -325,7 +325,7 @@ client_x11_get_proto(const char *display, const char *xauth_path,
|
||||
if (trusted == 0) {
|
||||
xauthdir = xmalloc(MAXPATHLEN);
|
||||
xauthfile = xmalloc(MAXPATHLEN);
|
||||
strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN);
|
||||
mktemp_proto(xauthdir, MAXPATHLEN);
|
||||
if (mkdtemp(xauthdir) != NULL) {
|
||||
do_unlink = 1;
|
||||
snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile",
|
||||
@ -544,7 +544,7 @@ static void
|
||||
server_alive_check(void)
|
||||
{
|
||||
if (packet_inc_alive_timeouts() > options.server_alive_count_max) {
|
||||
logit("Timeout, server not responding.");
|
||||
logit("Timeout, server %s not responding.", host);
|
||||
cleanup_exit(255);
|
||||
}
|
||||
packet_start(SSH2_MSG_GLOBAL_REQUEST);
|
||||
@ -1590,24 +1590,22 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
|
||||
}
|
||||
|
||||
/* Output any buffered data for stdout. */
|
||||
while (buffer_len(&stdout_buffer) > 0) {
|
||||
len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
|
||||
buffer_len(&stdout_buffer));
|
||||
if (len <= 0) {
|
||||
if (buffer_len(&stdout_buffer) > 0) {
|
||||
len = atomicio(vwrite, fileno(stdout),
|
||||
buffer_ptr(&stdout_buffer), buffer_len(&stdout_buffer));
|
||||
if (len < 0 || (u_int)len != buffer_len(&stdout_buffer))
|
||||
error("Write failed flushing stdout buffer.");
|
||||
break;
|
||||
}
|
||||
else
|
||||
buffer_consume(&stdout_buffer, len);
|
||||
}
|
||||
|
||||
/* Output any buffered data for stderr. */
|
||||
while (buffer_len(&stderr_buffer) > 0) {
|
||||
len = write(fileno(stderr), buffer_ptr(&stderr_buffer),
|
||||
buffer_len(&stderr_buffer));
|
||||
if (len <= 0) {
|
||||
if (buffer_len(&stderr_buffer) > 0) {
|
||||
len = atomicio(vwrite, fileno(stderr),
|
||||
buffer_ptr(&stderr_buffer), buffer_len(&stderr_buffer));
|
||||
if (len < 0 || (u_int)len != buffer_len(&stderr_buffer))
|
||||
error("Write failed flushing stderr buffer.");
|
||||
break;
|
||||
}
|
||||
else
|
||||
buffer_consume(&stderr_buffer, len);
|
||||
}
|
||||
|
||||
@ -1622,7 +1620,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
|
||||
packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes);
|
||||
packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes);
|
||||
verbose("Transferred: sent %llu, received %llu bytes, in %.1f seconds",
|
||||
obytes, ibytes, total_time);
|
||||
(unsigned long long)obytes, (unsigned long long)ibytes, total_time);
|
||||
if (total_time > 0)
|
||||
verbose("Bytes per second: sent %.1f, received %.1f",
|
||||
obytes / total_time, ibytes / total_time);
|
||||
@ -1933,7 +1931,7 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt)
|
||||
}
|
||||
packet_check_eom();
|
||||
}
|
||||
if (reply) {
|
||||
if (reply && c != NULL) {
|
||||
packet_start(success ?
|
||||
SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
|
||||
packet_put_int(c->remote_id);
|
||||
@ -1973,6 +1971,9 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
|
||||
if ((c = channel_lookup(id)) == NULL)
|
||||
fatal("client_session2_setup: channel %d: unknown channel", id);
|
||||
|
||||
packet_set_interactive(want_tty,
|
||||
options.ip_qos_interactive, options.ip_qos_bulk);
|
||||
|
||||
if (want_tty) {
|
||||
struct winsize ws;
|
||||
|
||||
@ -2129,5 +2130,6 @@ cleanup_exit(int i)
|
||||
leave_non_blocking();
|
||||
if (options.control_path != NULL && muxserver_sock != -1)
|
||||
unlink(options.control_path);
|
||||
ssh_kill_proxy_command();
|
||||
_exit(i);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: compress.c,v 1.25 2006/08/06 01:13:32 stevesk Exp $ */
|
||||
/* $OpenBSD: compress.c,v 1.26 2010/09/08 04:13:31 deraadt Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -17,12 +17,13 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "buffer.h"
|
||||
#include "compress.h"
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
z_stream incoming_stream;
|
||||
z_stream outgoing_stream;
|
||||
static int compress_init_send_called = 0;
|
||||
|
36
config.h.in
36
config.h.in
@ -125,6 +125,9 @@
|
||||
/* Builtin PRNG command timeout */
|
||||
#undef ENTROPY_TIMEOUT_MSEC
|
||||
|
||||
/* File names may not contain backslash characters */
|
||||
#undef FILESYSTEM_NO_BACKSLASH
|
||||
|
||||
/* fsid_t has member val */
|
||||
#undef FSID_HAS_VAL
|
||||
|
||||
@ -143,6 +146,9 @@
|
||||
/* Define if your system glob() function has gl_matchc options in glob_t */
|
||||
#undef GLOB_HAS_GL_MATCHC
|
||||
|
||||
/* Define if your system glob() function has gl_statv options in glob_t */
|
||||
#undef GLOB_HAS_GL_STATV
|
||||
|
||||
/* Define this if you want GSSAPI support in the version 2 protocol */
|
||||
#undef GSSAPI
|
||||
|
||||
@ -203,6 +209,9 @@
|
||||
/* Define to 1 if you have the `bindresvport_sa' function. */
|
||||
#undef HAVE_BINDRESVPORT_SA
|
||||
|
||||
/* Define to 1 if you have the `BN_is_prime_ex' function. */
|
||||
#undef HAVE_BN_IS_PRIME_EX
|
||||
|
||||
/* Define to 1 if you have the <bsm/audit.h> header file. */
|
||||
#undef HAVE_BSM_AUDIT_H
|
||||
|
||||
@ -311,6 +320,9 @@
|
||||
/* Define to 1 if you have the `dirname' function. */
|
||||
#undef HAVE_DIRNAME
|
||||
|
||||
/* Define to 1 if you have the `DSA_generate_parameters_ex' function. */
|
||||
#undef HAVE_DSA_GENERATE_PARAMETERS_EX
|
||||
|
||||
/* Define to 1 if you have the <endian.h> header file. */
|
||||
#undef HAVE_ENDIAN_H
|
||||
|
||||
@ -533,9 +545,15 @@
|
||||
/* Define to 1 if the system has the type `in_port_t'. */
|
||||
#undef HAVE_IN_PORT_T
|
||||
|
||||
/* Define if you have isblank(3C). */
|
||||
#undef HAVE_ISBLANK
|
||||
|
||||
/* Define to 1 if you have the <lastlog.h> header file. */
|
||||
#undef HAVE_LASTLOG_H
|
||||
|
||||
/* Define to 1 if you have the <libaudit.h> header file. */
|
||||
#undef HAVE_LIBAUDIT_H
|
||||
|
||||
/* Define to 1 if you have the `bsm' library (-lbsm). */
|
||||
#undef HAVE_LIBBSM
|
||||
|
||||
@ -738,6 +756,12 @@
|
||||
/* Define to 1 if you have the `rresvport_af' function. */
|
||||
#undef HAVE_RRESVPORT_AF
|
||||
|
||||
/* Define to 1 if you have the `RSA_generate_key_ex' function. */
|
||||
#undef HAVE_RSA_GENERATE_KEY_EX
|
||||
|
||||
/* Define to 1 if you have the `RSA_get_default_method' function. */
|
||||
#undef HAVE_RSA_GET_DEFAULT_METHOD
|
||||
|
||||
/* define if you have sa_family_t data type */
|
||||
#undef HAVE_SA_FAMILY_T
|
||||
|
||||
@ -1044,6 +1068,9 @@
|
||||
/* Define if you have ut_time in utmpx.h */
|
||||
#undef HAVE_TIME_IN_UTMPX
|
||||
|
||||
/* Define to 1 if you have the `timingsafe_bcmp' function. */
|
||||
#undef HAVE_TIMINGSAFE_BCMP
|
||||
|
||||
/* Define to 1 if you have the <tmpdir.h> header file. */
|
||||
#undef HAVE_TMPDIR_H
|
||||
|
||||
@ -1259,6 +1286,9 @@
|
||||
/* Define if EVP_DigestUpdate returns void */
|
||||
#undef OPENSSL_EVP_DIGESTUPDATE_VOID
|
||||
|
||||
/* libcrypto includes complete ECC support */
|
||||
#undef OPENSSL_HAS_ECC
|
||||
|
||||
/* libcrypto is missing AES 192 and 256 bit functions */
|
||||
#undef OPENSSL_LOBOTOMISED_AES
|
||||
|
||||
@ -1390,6 +1420,9 @@
|
||||
/* Use libedit for sftp */
|
||||
#undef USE_LIBEDIT
|
||||
|
||||
/* Use Linux audit module */
|
||||
#undef USE_LINUX_AUDIT
|
||||
|
||||
/* Enable OpenSSL engine support */
|
||||
#undef USE_OPENSSL_ENGINE
|
||||
|
||||
@ -1402,6 +1435,9 @@
|
||||
/* Define if you have Solaris process contracts */
|
||||
#undef USE_SOLARIS_PROCESS_CONTRACTS
|
||||
|
||||
/* Define if you have Solaris projects */
|
||||
#undef USE_SOLARIS_PROJECTS
|
||||
|
||||
/* Define if you shouldn't strip 'tty' from your ttyname in [uw]tmp */
|
||||
#undef WITH_ABBREV_NO_TTY
|
||||
|
||||
|
153
configure.ac
153
configure.ac
@ -1,4 +1,4 @@
|
||||
# $Id: configure.ac,v 1.451 2010/08/16 03:15:23 dtucker Exp $
|
||||
# $Id: configure.ac,v 1.469 2011/01/21 22:37:05 dtucker Exp $
|
||||
#
|
||||
# Copyright (c) 1999-2004 Damien Miller
|
||||
#
|
||||
@ -15,9 +15,21 @@
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org)
|
||||
AC_REVISION($Revision: 1.451 $)
|
||||
AC_REVISION($Revision: 1.469 $)
|
||||
AC_CONFIG_SRCDIR([ssh.c])
|
||||
|
||||
# local macros
|
||||
AC_DEFUN([OPENSSH_CHECK_CFLAG_COMPILE], [{
|
||||
AC_MSG_CHECKING([if $CC supports $1])
|
||||
saved_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $1"
|
||||
AC_COMPILE_IFELSE([void main(void) { return 0; }],
|
||||
[ AC_MSG_RESULT(yes) ],
|
||||
[ AC_MSG_RESULT(no)
|
||||
CFLAGS="$saved_CFLAGS" ]
|
||||
)
|
||||
}])
|
||||
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_PROG_CC
|
||||
AC_CANONICAL_HOST
|
||||
@ -41,8 +53,24 @@ AC_PATH_PROG(TEST_MINUS_S_SH, bash)
|
||||
AC_PATH_PROG(TEST_MINUS_S_SH, ksh)
|
||||
AC_PATH_PROG(TEST_MINUS_S_SH, sh)
|
||||
AC_PATH_PROG(SH, sh)
|
||||
AC_PATH_PROG(GROFF, groff)
|
||||
AC_PATH_PROG(NROFF, nroff)
|
||||
AC_PATH_PROG(MANDOC, mandoc)
|
||||
AC_SUBST(TEST_SHELL,sh)
|
||||
|
||||
dnl select manpage formatter
|
||||
if test "x$MANDOC" != "x" ; then
|
||||
MANFMT="$MANDOC"
|
||||
elif test "x$NROFF" != "x" ; then
|
||||
MANFMT="$NROFF -mandoc"
|
||||
elif test "x$GROFF" != "x" ; then
|
||||
MANFMT="$GROFF -mandoc -Tascii"
|
||||
else
|
||||
AC_MSG_WARN([no manpage formatted found])
|
||||
MANFMT="false"
|
||||
fi
|
||||
AC_SUBST(MANFMT)
|
||||
|
||||
dnl for buildpkg.sh
|
||||
AC_PATH_PROG(PATH_GROUPADD_PROG, groupadd, groupadd,
|
||||
[/usr/sbin${PATH_SEPARATOR}/etc])
|
||||
@ -97,20 +125,27 @@ AC_ARG_WITH(stackprotect,
|
||||
use_stack_protector=0
|
||||
fi ])
|
||||
|
||||
|
||||
if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
|
||||
CFLAGS="$CFLAGS -Wall -Wpointer-arith -Wuninitialized"
|
||||
OPENSSH_CHECK_CFLAG_COMPILE([-Wall])
|
||||
OPENSSH_CHECK_CFLAG_COMPILE([-Wpointer-arith])
|
||||
OPENSSH_CHECK_CFLAG_COMPILE([-Wuninitialized])
|
||||
OPENSSH_CHECK_CFLAG_COMPILE([-Wsign-compare])
|
||||
OPENSSH_CHECK_CFLAG_COMPILE([-Wformat-security])
|
||||
OPENSSH_CHECK_CFLAG_COMPILE([-Wno-pointer-sign])
|
||||
OPENSSH_CHECK_CFLAG_COMPILE([-Wno-unused-result])
|
||||
OPENSSH_CHECK_CFLAG_COMPILE([-fno-strict-aliasing])
|
||||
AC_MSG_CHECKING(gcc version)
|
||||
GCC_VER=`$CC -v 2>&1 | $AWK '/gcc version /{print $3}'`
|
||||
case $GCC_VER in
|
||||
1.*) no_attrib_nonnull=1 ;;
|
||||
2.8* | 2.9*)
|
||||
CFLAGS="$CFLAGS -Wsign-compare"
|
||||
no_attrib_nonnull=1
|
||||
;;
|
||||
2.*) no_attrib_nonnull=1 ;;
|
||||
3.*) CFLAGS="$CFLAGS -Wsign-compare -Wformat-security" ;;
|
||||
4.*) CFLAGS="$CFLAGS -Wsign-compare -Wno-pointer-sign -Wformat-security -fno-strict-aliasing" ;;
|
||||
*) ;;
|
||||
esac
|
||||
AC_MSG_RESULT($GCC_VER)
|
||||
|
||||
AC_MSG_CHECKING(if $CC accepts -fno-builtin-memset)
|
||||
saved_CFLAGS="$CFLAGS"
|
||||
@ -333,6 +368,7 @@ AC_CHECK_HEADERS(sys/mount.h, [], [], [
|
||||
# Messages for features tested for in target-specific section
|
||||
SIA_MSG="no"
|
||||
SPC_MSG="no"
|
||||
SP_MSG="no"
|
||||
|
||||
# Check for some target-specific stuff
|
||||
case "$host" in
|
||||
@ -447,6 +483,7 @@ int main(void) { exit(0); }
|
||||
[Define if your platform needs to skip post auth
|
||||
file descriptor passing])
|
||||
AC_DEFINE(SSH_IOBUFSZ, 65535, [Windows is sensitive to read buffer size])
|
||||
AC_DEFINE(FILESYSTEM_NO_BACKSLASH, 1, [File names may not contain backslash characters])
|
||||
;;
|
||||
*-*-dgux*)
|
||||
AC_DEFINE(IP_TOS_IS_BROKEN, 1,
|
||||
@ -704,6 +741,17 @@ mips-sony-bsd|mips-sony-newsos4)
|
||||
SPC_MSG="yes" ], )
|
||||
],
|
||||
)
|
||||
AC_ARG_WITH(solaris-projects,
|
||||
[ --with-solaris-projects Enable Solaris projects (experimental)],
|
||||
[
|
||||
AC_CHECK_LIB(project, setproject,
|
||||
[ AC_DEFINE(USE_SOLARIS_PROJECTS, 1,
|
||||
[Define if you have Solaris projects])
|
||||
SSHDLIBS="$SSHDLIBS -lproject"
|
||||
AC_SUBST(SSHDLIBS)
|
||||
SP_MSG="yes" ], )
|
||||
],
|
||||
)
|
||||
;;
|
||||
*-*-sunos4*)
|
||||
CPPFLAGS="$CPPFLAGS -DSUNOS4"
|
||||
@ -1118,6 +1166,28 @@ AC_TRY_COMPILE(
|
||||
]
|
||||
)
|
||||
|
||||
# Check for g.gl_statv glob() extension
|
||||
AC_MSG_CHECKING(for gl_statv and GLOB_KEEPSTAT extensions for glob)
|
||||
AC_TRY_COMPILE(
|
||||
[ #include <glob.h> ],
|
||||
[
|
||||
#ifndef GLOB_KEEPSTAT
|
||||
#error "glob does not support GLOB_KEEPSTAT extension"
|
||||
#endif
|
||||
glob_t g;
|
||||
g.gl_statv = NULL;
|
||||
],
|
||||
[
|
||||
AC_DEFINE(GLOB_HAS_GL_STATV, 1,
|
||||
[Define if your system glob() function has
|
||||
gl_statv options in glob_t])
|
||||
AC_MSG_RESULT(yes)
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
]
|
||||
)
|
||||
|
||||
AC_CHECK_DECLS(GLOB_NOMATCH, , , [#include <glob.h>])
|
||||
|
||||
AC_MSG_CHECKING([whether struct dirent allocates space for d_name])
|
||||
@ -1273,7 +1343,7 @@ AC_ARG_WITH(libedit,
|
||||
LDFLAGS="-L${withval}/lib ${LDFLAGS}"
|
||||
fi
|
||||
fi
|
||||
if test "x$use_pkgconfig_for_libedit" == "xyes"; then
|
||||
if test "x$use_pkgconfig_for_libedit" = "xyes"; then
|
||||
LIBEDIT=`$PKGCONFIG --libs-only-l libedit`
|
||||
CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libedit`"
|
||||
else
|
||||
@ -1308,7 +1378,7 @@ int main(void)
|
||||
|
||||
AUDIT_MODULE=none
|
||||
AC_ARG_WITH(audit,
|
||||
[ --with-audit=module Enable EXPERIMENTAL audit support (modules=debug,bsm)],
|
||||
[ --with-audit=module Enable audit support (modules=debug,bsm,linux)],
|
||||
[
|
||||
AC_MSG_CHECKING(for supported audit module)
|
||||
case "$withval" in
|
||||
@ -1332,10 +1402,18 @@ AC_ARG_WITH(audit,
|
||||
AC_CHECK_FUNCS(getaudit_addr aug_get_machine)
|
||||
AC_DEFINE(USE_BSM_AUDIT, 1, [Use BSM audit module])
|
||||
;;
|
||||
linux)
|
||||
AC_MSG_RESULT(linux)
|
||||
AUDIT_MODULE=linux
|
||||
dnl Checks for headers, libs and functions
|
||||
AC_CHECK_HEADERS(libaudit.h)
|
||||
SSHDLIBS="$SSHDLIBS -laudit"
|
||||
AC_DEFINE(USE_LINUX_AUDIT, 1, [Use Linux audit module])
|
||||
;;
|
||||
debug)
|
||||
AUDIT_MODULE=debug
|
||||
AC_MSG_RESULT(debug)
|
||||
AC_DEFINE(SSH_AUDIT_EVENTS, 1, Use audit debugging module)
|
||||
AC_DEFINE(SSH_AUDIT_EVENTS, 1, [Use audit debugging module])
|
||||
;;
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
@ -1434,6 +1512,7 @@ AC_CHECK_FUNCS( \
|
||||
swap32 \
|
||||
sysconf \
|
||||
tcgetpgrp \
|
||||
timingsafe_bcmp \
|
||||
truncate \
|
||||
unsetenv \
|
||||
updwtmpx \
|
||||
@ -1444,6 +1523,17 @@ AC_CHECK_FUNCS( \
|
||||
waitpid \
|
||||
)
|
||||
|
||||
AC_LINK_IFELSE(
|
||||
[
|
||||
#include <ctype.h>
|
||||
int main(void)
|
||||
{
|
||||
return (isblank('a'));
|
||||
}
|
||||
],
|
||||
[AC_DEFINE(HAVE_ISBLANK, 1, [Define if you have isblank(3C).])
|
||||
])
|
||||
|
||||
# PKCS#11 support requires dlopen() and co
|
||||
AC_SEARCH_LIBS(dlopen, dl,
|
||||
AC_DEFINE([ENABLE_PKCS11], [], [Enable for PKCS#11 support])
|
||||
@ -2090,6 +2180,8 @@ int main(void) { SSLeay_add_all_algorithms(); }
|
||||
]
|
||||
)
|
||||
|
||||
AC_CHECK_FUNCS(RSA_generate_key_ex DSA_generate_parameters_ex BN_is_prime_ex RSA_get_default_method)
|
||||
|
||||
AC_ARG_WITH(ssl-engine,
|
||||
[ --with-ssl-engine Enable OpenSSL (hardware) ENGINE support ],
|
||||
[ if test "x$withval" != "xno" ; then
|
||||
@ -2156,7 +2248,43 @@ if test "x$check_for_libcrypt_later" = "x1"; then
|
||||
fi
|
||||
|
||||
# Search for SHA256 support in libc and/or OpenSSL
|
||||
AC_CHECK_FUNCS(SHA256_Update EVP_sha256)
|
||||
AC_CHECK_FUNCS(SHA256_Update EVP_sha256, [TEST_SSH_SHA256=yes],
|
||||
[TEST_SSH_SHA256=no])
|
||||
AC_SUBST(TEST_SSH_SHA256)
|
||||
|
||||
# Check complete ECC support in OpenSSL
|
||||
AC_MSG_CHECKING([whether OpenSSL has complete ECC support])
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_SOURCE([[
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdh.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/opensslv.h>
|
||||
#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
|
||||
# error "OpenSSL < 0.9.8g has unreliable ECC code"
|
||||
#endif
|
||||
int main(void) {
|
||||
EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1);
|
||||
const EVP_MD *m = EVP_sha512(); /* We need this too */
|
||||
}
|
||||
]])],
|
||||
[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(OPENSSL_HAS_ECC, 1,
|
||||
[libcrypto includes complete ECC support])
|
||||
TEST_SSH_ECC=yes
|
||||
COMMENT_OUT_ECC=""
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
TEST_SSH_ECC=no
|
||||
COMMENT_OUT_ECC="#no ecc#"
|
||||
]
|
||||
)
|
||||
AC_SUBST(TEST_SSH_ECC)
|
||||
AC_SUBST(COMMENT_OUT_ECC)
|
||||
|
||||
saved_LIBS="$LIBS"
|
||||
AC_CHECK_LIB(iaf, ia_openinfo, [
|
||||
@ -3443,10 +3571,12 @@ AC_ARG_WITH(kerberos5,
|
||||
[ char *tmp = heimdal_version; ],
|
||||
[ AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HEIMDAL)
|
||||
K5LIBS="-lkrb5 -ldes"
|
||||
K5LIBS="-lkrb5"
|
||||
K5LIBS="$K5LIBS -lcom_err -lasn1"
|
||||
AC_CHECK_LIB(roken, net_write,
|
||||
[K5LIBS="$K5LIBS -lroken"])
|
||||
AC_CHECK_LIB(des, des_cbc_encrypt,
|
||||
[K5LIBS="$K5LIBS -ldes"])
|
||||
],
|
||||
[ AC_MSG_RESULT(no)
|
||||
K5LIBS="-lkrb5 -lk5crypto -lcom_err"
|
||||
@ -4191,6 +4321,7 @@ echo " TCP Wrappers support: $TCPW_MSG"
|
||||
echo " MD5 password support: $MD5_MSG"
|
||||
echo " libedit support: $LIBEDIT_MSG"
|
||||
echo " Solaris process contract support: $SPC_MSG"
|
||||
echo " Solaris project support: $SP_MSG"
|
||||
echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
|
||||
echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
|
||||
echo " BSD Auth support: $BSD_AUTH_MSG"
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#old cvs stuff. please update before use. may be deprecated.
|
||||
%define use_stable 1
|
||||
%define version 5.6p1
|
||||
%define version 5.7p1
|
||||
%if %{use_stable}
|
||||
%define cvs %{nil}
|
||||
%define release 1
|
||||
@ -57,7 +57,7 @@ BuildRequires : XFree86-imake
|
||||
# %{use_stable}==0: :pserver:cvs@bass.directhit.com:/cvs/openssh_cvs
|
||||
Source0: see-above:/.../openssh-%{version}.tar.gz
|
||||
%if %{use_stable}
|
||||
Source1: see-above:/.../openssh-%{version}.tar.gz.sig
|
||||
Source1: see-above:/.../openssh-%{version}.tar.gz.asc
|
||||
%endif
|
||||
Source2: http://www.jmknoble.net/software/%{xsa}/%{askpass}.tar.gz
|
||||
Source3: http://www.openssh.com/faq.html
|
||||
@ -182,7 +182,7 @@ CFLAGS="$RPM_OPT_FLAGS" \
|
||||
--with-privsep-path=%{_var}/empty/sshd \
|
||||
#leave this line for easy edits.
|
||||
|
||||
%__make CFLAGS="$RPM_OPT_FLAGS"
|
||||
%__make
|
||||
|
||||
cd %{askpass}
|
||||
%configure \
|
||||
@ -356,7 +356,11 @@ fi
|
||||
|
||||
|
||||
%ChangeLog
|
||||
* Tue Jan 18 2011 Tim Rice <tim@multitalents.net>
|
||||
- Use CFLAGS from Makefile instead of RPM so build completes.
|
||||
- Signatures were changed to .asc since 4.1p1.
|
||||
|
||||
* Mon Jan 01 1998 ...
|
||||
Template Version: 1.31
|
||||
|
||||
$Id: openssh.spec,v 1.71 2010/08/08 16:32:09 djm Exp $
|
||||
$Id: openssh.spec,v 1.73 2011/01/22 09:23:33 djm Exp $
|
||||
|
@ -1,4 +1,4 @@
|
||||
%define ver 5.6p1
|
||||
%define ver 5.7p1
|
||||
%define rel 1
|
||||
|
||||
# OpenSSH privilege separation requires a user & group ID
|
||||
|
@ -104,7 +104,7 @@ start()
|
||||
do_dsa_keygen
|
||||
|
||||
echo -n $"Starting $prog:"
|
||||
initlog -c "$SSHD $OPTIONS" && success || failure
|
||||
$SSHD $OPTIONS && success || failure
|
||||
RETVAL=$?
|
||||
[ "$RETVAL" = 0 ] && touch /var/lock/subsys/sshd
|
||||
echo
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
|
||||
Name: openssh
|
||||
Version: 5.6p1
|
||||
Version: 5.7p1
|
||||
URL: http://www.openssh.com/
|
||||
Release: 1
|
||||
Source0: openssh-%{version}.tar.gz
|
||||
|
48
defines.h
48
defines.h
@ -25,7 +25,7 @@
|
||||
#ifndef _DEFINES_H
|
||||
#define _DEFINES_H
|
||||
|
||||
/* $Id: defines.h,v 1.160 2010/04/09 08:13:27 dtucker Exp $ */
|
||||
/* $Id: defines.h,v 1.164 2011/01/17 10:15:31 dtucker Exp $ */
|
||||
|
||||
|
||||
/* Constants */
|
||||
@ -42,6 +42,9 @@ enum
|
||||
# define SHUT_RDWR SHUT_RDWR
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Definitions for IP type of service (ip_tos)
|
||||
*/
|
||||
#ifndef IPTOS_LOWDELAY
|
||||
# define IPTOS_LOWDELAY 0x10
|
||||
# define IPTOS_THROUGHPUT 0x08
|
||||
@ -50,6 +53,40 @@ enum
|
||||
# define IPTOS_MINCOST IPTOS_LOWCOST
|
||||
#endif /* IPTOS_LOWDELAY */
|
||||
|
||||
/*
|
||||
* Definitions for DiffServ Codepoints as per RFC2474
|
||||
*/
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#ifndef IPTOS_DSCP_AF11
|
||||
# define IPTOS_DSCP_AF11 0x28
|
||||
# define IPTOS_DSCP_AF12 0x30
|
||||
# define IPTOS_DSCP_AF13 0x38
|
||||
# define IPTOS_DSCP_AF21 0x48
|
||||
# define IPTOS_DSCP_AF22 0x50
|
||||
# define IPTOS_DSCP_AF23 0x58
|
||||
# define IPTOS_DSCP_AF31 0x68
|
||||
# define IPTOS_DSCP_AF32 0x70
|
||||
# define IPTOS_DSCP_AF33 0x78
|
||||
# define IPTOS_DSCP_AF41 0x88
|
||||
# define IPTOS_DSCP_AF42 0x90
|
||||
# define IPTOS_DSCP_AF43 0x98
|
||||
# define IPTOS_DSCP_EF 0xb8
|
||||
#endif /* IPTOS_DSCP_AF11 */
|
||||
#ifndef IPTOS_DSCP_CS0
|
||||
# define IPTOS_DSCP_CS0 0x00
|
||||
# define IPTOS_DSCP_CS1 0x20
|
||||
# define IPTOS_DSCP_CS2 0x40
|
||||
# define IPTOS_DSCP_CS3 0x60
|
||||
# define IPTOS_DSCP_CS4 0x80
|
||||
# define IPTOS_DSCP_CS5 0xa0
|
||||
# define IPTOS_DSCP_CS6 0xc0
|
||||
# define IPTOS_DSCP_CS7 0xe0
|
||||
#endif /* IPTOS_DSCP_CS0 */
|
||||
#ifndef IPTOS_DSCP_EF
|
||||
# define IPTOS_DSCP_EF 0xb8
|
||||
#endif /* IPTOS_DSCP_EF */
|
||||
|
||||
#ifndef MAXPATHLEN
|
||||
# ifdef PATH_MAX
|
||||
# define MAXPATHLEN PATH_MAX
|
||||
@ -256,6 +293,10 @@ typedef unsigned int size_t;
|
||||
# define SIZE_T_MAX UINT_MAX
|
||||
#endif /* HAVE_SIZE_T */
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX SIZE_T_MAX
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SSIZE_T
|
||||
typedef int ssize_t;
|
||||
# define HAVE_SSIZE_T
|
||||
@ -566,6 +607,11 @@ struct winsize {
|
||||
# define CUSTOM_SSH_AUDIT_EVENTS
|
||||
#endif
|
||||
|
||||
#ifdef USE_LINUX_AUDIT
|
||||
# define SSH_AUDIT_EVENTS
|
||||
# define CUSTOM_SSH_AUDIT_EVENTS
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE___func__) && defined(HAVE___FUNCTION__)
|
||||
# define __func__ __FUNCTION__
|
||||
#elif !defined(HAVE___func__)
|
||||
|
3
dns.c
3
dns.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: dns.c,v 1.26 2010/02/26 20:29:54 djm Exp $ */
|
||||
/* $OpenBSD: dns.c,v 1.27 2010/08/31 11:54:45 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Wesley Griffin. All rights reserved.
|
||||
@ -86,6 +86,7 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
|
||||
case KEY_DSA:
|
||||
*algorithm = SSHFP_KEY_DSA;
|
||||
break;
|
||||
/* XXX KEY_ECDSA */
|
||||
default:
|
||||
*algorithm = SSHFP_KEY_RESERVED; /* 0 */
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ init_rng(void)
|
||||
*/
|
||||
if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & ~0xff0L)
|
||||
fatal("OpenSSL version mismatch. Built against %lx, you "
|
||||
"have %lx", OPENSSL_VERSION_NUMBER, SSLeay());
|
||||
"have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay());
|
||||
|
||||
#ifndef OPENSSL_PRNG_ONLY
|
||||
original_uid = getuid();
|
||||
|
288
hostfile.c
288
hostfile.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: hostfile.c,v 1.48 2010/03/04 10:36:03 djm Exp $ */
|
||||
/* $OpenBSD: hostfile.c,v 1.50 2010/12/04 13:31:37 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -56,6 +56,12 @@
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
|
||||
struct hostkeys {
|
||||
struct hostkey_entry *entries;
|
||||
u_int num_entries;
|
||||
};
|
||||
|
||||
static int
|
||||
extract_salt(const char *s, u_int l, char *salt, size_t salt_len)
|
||||
@ -164,26 +170,28 @@ hostfile_read_key(char **cpp, u_int *bitsp, Key *ret)
|
||||
|
||||
/* Return results. */
|
||||
*cpp = cp;
|
||||
if (bitsp != NULL)
|
||||
*bitsp = key_size(ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
hostfile_check_key(int bits, const Key *key, const char *host, const char *filename, int linenum)
|
||||
hostfile_check_key(int bits, const Key *key, const char *host,
|
||||
const char *filename, u_long linenum)
|
||||
{
|
||||
if (key == NULL || key->type != KEY_RSA1 || key->rsa == NULL)
|
||||
return 1;
|
||||
if (bits != BN_num_bits(key->rsa->n)) {
|
||||
logit("Warning: %s, line %d: keysize mismatch for host %s: "
|
||||
logit("Warning: %s, line %lu: keysize mismatch for host %s: "
|
||||
"actual %d vs. announced %d.",
|
||||
filename, linenum, host, BN_num_bits(key->rsa->n), bits);
|
||||
logit("Warning: replace %d with %d in %s, line %d.",
|
||||
logit("Warning: replace %d with %d in %s, line %lu.",
|
||||
bits, BN_num_bits(key->rsa->n), filename, linenum);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static enum { MRK_ERROR, MRK_NONE, MRK_REVOKE, MRK_CA }
|
||||
static HostkeyMarker
|
||||
check_markers(char **cpp)
|
||||
{
|
||||
char marker[32], *sp, *cp = *cpp;
|
||||
@ -218,49 +226,32 @@ check_markers(char **cpp)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks whether the given host (which must be in all lowercase) is already
|
||||
* in the list of our known hosts. Returns HOST_OK if the host is known and
|
||||
* has the specified key, HOST_NEW if the host is not known, and HOST_CHANGED
|
||||
* if the host is known but used to have a different host key.
|
||||
*
|
||||
* If no 'key' has been specified and a key of type 'keytype' is known
|
||||
* for the specified host, then HOST_FOUND is returned.
|
||||
*/
|
||||
struct hostkeys *
|
||||
init_hostkeys(void)
|
||||
{
|
||||
struct hostkeys *ret = xcalloc(1, sizeof(*ret));
|
||||
|
||||
static HostStatus
|
||||
check_host_in_hostfile_by_key_or_type(const char *filename,
|
||||
const char *host, const Key *key, int keytype, Key *found,
|
||||
int want_revocation, int *numret)
|
||||
ret->entries = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path)
|
||||
{
|
||||
FILE *f;
|
||||
char line[8192];
|
||||
int want, have, linenum = 0, want_cert = key_is_cert(key);
|
||||
u_int kbits;
|
||||
u_long linenum = 0, num_loaded = 0;
|
||||
char *cp, *cp2, *hashed_host;
|
||||
HostStatus end_return;
|
||||
HostkeyMarker marker;
|
||||
Key *key;
|
||||
int kbits;
|
||||
|
||||
debug3("check_host_in_hostfile: host %s filename %s", host, filename);
|
||||
|
||||
if (want_revocation && (key == NULL || keytype != 0 || found != NULL))
|
||||
fatal("%s: invalid arguments", __func__);
|
||||
|
||||
/* Open the file containing the list of known hosts. */
|
||||
f = fopen(filename, "r");
|
||||
if (!f)
|
||||
return HOST_NEW;
|
||||
|
||||
/*
|
||||
* Return value when the loop terminates. This is set to
|
||||
* HOST_CHANGED if we have seen a different key for the host and have
|
||||
* not found the proper one.
|
||||
*/
|
||||
end_return = HOST_NEW;
|
||||
|
||||
/* Go through the file. */
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
if ((f = fopen(path, "r")) == NULL)
|
||||
return;
|
||||
debug3("%s: loading entries for host \"%.100s\" from file \"%s\"",
|
||||
__func__, host, path);
|
||||
while (read_keyfile_line(f, path, line, sizeof(line), &linenum) == 0) {
|
||||
cp = line;
|
||||
linenum++;
|
||||
|
||||
/* Skip any leading whitespace, comments and empty lines. */
|
||||
for (; *cp == ' ' || *cp == '\t'; cp++)
|
||||
@ -268,19 +259,11 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
|
||||
if (!*cp || *cp == '#' || *cp == '\n')
|
||||
continue;
|
||||
|
||||
if (want_revocation)
|
||||
want = MRK_REVOKE;
|
||||
else if (want_cert)
|
||||
want = MRK_CA;
|
||||
else
|
||||
want = MRK_NONE;
|
||||
|
||||
if ((have = check_markers(&cp)) == MRK_ERROR) {
|
||||
verbose("%s: invalid marker at %s:%d",
|
||||
__func__, filename, linenum);
|
||||
continue;
|
||||
} else if (want != have)
|
||||
if ((marker = check_markers(&cp)) == MRK_ERROR) {
|
||||
verbose("%s: invalid marker at %s:%lu",
|
||||
__func__, path, linenum);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Find the end of the host name portion. */
|
||||
for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++)
|
||||
@ -292,8 +275,8 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
|
||||
continue;
|
||||
hashed_host = host_hash(host, cp, (u_int) (cp2 - cp));
|
||||
if (hashed_host == NULL) {
|
||||
debug("Invalid hashed host line %d of %s",
|
||||
linenum, filename);
|
||||
debug("Invalid hashed host line %lu of %s",
|
||||
linenum, path);
|
||||
continue;
|
||||
}
|
||||
if (strncmp(hashed_host, cp, (u_int) (cp2 - cp)) != 0)
|
||||
@ -303,98 +286,167 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
|
||||
/* Got a match. Skip host name. */
|
||||
cp = cp2;
|
||||
|
||||
if (want_revocation)
|
||||
found = key_new(KEY_UNSPEC);
|
||||
|
||||
/*
|
||||
* Extract the key from the line. This will skip any leading
|
||||
* whitespace. Ignore badly formatted lines.
|
||||
*/
|
||||
if (!hostfile_read_key(&cp, &kbits, found))
|
||||
key = key_new(KEY_UNSPEC);
|
||||
if (!hostfile_read_key(&cp, &kbits, key)) {
|
||||
key_free(key);
|
||||
key = key_new(KEY_RSA1);
|
||||
if (!hostfile_read_key(&cp, &kbits, key)) {
|
||||
key_free(key);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!hostfile_check_key(kbits, key, host, path, linenum))
|
||||
continue;
|
||||
|
||||
if (numret != NULL)
|
||||
*numret = linenum;
|
||||
|
||||
if (key == NULL) {
|
||||
/* we found a key of the requested type */
|
||||
if (found->type == keytype) {
|
||||
debug3("%s: found %skey type %s in file %s:%lu", __func__,
|
||||
marker == MRK_NONE ? "" :
|
||||
(marker == MRK_CA ? "ca " : "revoked "),
|
||||
key_type(key), path, linenum);
|
||||
hostkeys->entries = xrealloc(hostkeys->entries,
|
||||
hostkeys->num_entries + 1, sizeof(*hostkeys->entries));
|
||||
hostkeys->entries[hostkeys->num_entries].host = xstrdup(host);
|
||||
hostkeys->entries[hostkeys->num_entries].file = xstrdup(path);
|
||||
hostkeys->entries[hostkeys->num_entries].line = linenum;
|
||||
hostkeys->entries[hostkeys->num_entries].key = key;
|
||||
hostkeys->entries[hostkeys->num_entries].marker = marker;
|
||||
hostkeys->num_entries++;
|
||||
num_loaded++;
|
||||
}
|
||||
debug3("%s: loaded %lu keys", __func__, num_loaded);
|
||||
fclose(f);
|
||||
return HOST_FOUND;
|
||||
}
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hostfile_check_key(kbits, found, host, filename, linenum))
|
||||
continue;
|
||||
void
|
||||
free_hostkeys(struct hostkeys *hostkeys)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
if (want_revocation) {
|
||||
if (key_is_cert(key) &&
|
||||
key_equal_public(key->cert->signature_key, found)) {
|
||||
verbose("check_host_in_hostfile: revoked CA "
|
||||
"line %d", linenum);
|
||||
key_free(found);
|
||||
return HOST_REVOKED;
|
||||
for (i = 0; i < hostkeys->num_entries; i++) {
|
||||
xfree(hostkeys->entries[i].host);
|
||||
xfree(hostkeys->entries[i].file);
|
||||
key_free(hostkeys->entries[i].key);
|
||||
bzero(hostkeys->entries + i, sizeof(*hostkeys->entries));
|
||||
}
|
||||
if (key_equal_public(key, found)) {
|
||||
verbose("check_host_in_hostfile: revoked key "
|
||||
"line %d", linenum);
|
||||
key_free(found);
|
||||
return HOST_REVOKED;
|
||||
}
|
||||
key_free(found);
|
||||
continue;
|
||||
if (hostkeys->entries != NULL)
|
||||
xfree(hostkeys->entries);
|
||||
hostkeys->entries = NULL;
|
||||
hostkeys->num_entries = 0;
|
||||
xfree(hostkeys);
|
||||
}
|
||||
|
||||
/* Check if the current key is the same as the given key. */
|
||||
if (want_cert && key_equal(key->cert->signature_key, found)) {
|
||||
/* Found CA cert for key */
|
||||
debug3("check_host_in_hostfile: CA match line %d",
|
||||
linenum);
|
||||
fclose(f);
|
||||
return HOST_OK;
|
||||
} else if (!want_cert && key_equal(key, found)) {
|
||||
/* Found identical key */
|
||||
debug3("check_host_in_hostfile: match line %d", linenum);
|
||||
fclose(f);
|
||||
return HOST_OK;
|
||||
static int
|
||||
check_key_not_revoked(struct hostkeys *hostkeys, Key *k)
|
||||
{
|
||||
int is_cert = key_is_cert(k);
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < hostkeys->num_entries; i++) {
|
||||
if (hostkeys->entries[i].marker != MRK_REVOKE)
|
||||
continue;
|
||||
if (key_equal_public(k, hostkeys->entries[i].key))
|
||||
return -1;
|
||||
if (is_cert &&
|
||||
key_equal_public(k->cert->signature_key,
|
||||
hostkeys->entries[i].key))
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* They do not match. We will continue to go through the
|
||||
* file; however, we note that we will not return that it is
|
||||
* new.
|
||||
* Match keys against a specified key, or look one up by key type.
|
||||
*
|
||||
* If looking for a keytype (key == NULL) and one is found then return
|
||||
* HOST_FOUND, otherwise HOST_NEW.
|
||||
*
|
||||
* If looking for a key (key != NULL):
|
||||
* 1. If the key is a cert and a matching CA is found, return HOST_OK
|
||||
* 2. If the key is not a cert and a matching key is found, return HOST_OK
|
||||
* 3. If no key matches but a key with a different type is found, then
|
||||
* return HOST_CHANGED
|
||||
* 4. If no matching keys are found, then return HOST_NEW.
|
||||
*
|
||||
* Finally, check any found key is not revoked.
|
||||
*/
|
||||
static HostStatus
|
||||
check_hostkeys_by_key_or_type(struct hostkeys *hostkeys,
|
||||
Key *k, int keytype, const struct hostkey_entry **found)
|
||||
{
|
||||
u_int i;
|
||||
HostStatus end_return = HOST_NEW;
|
||||
int want_cert = key_is_cert(k);
|
||||
HostkeyMarker want_marker = want_cert ? MRK_CA : MRK_NONE;
|
||||
int proto = (k ? k->type : keytype) == KEY_RSA1 ? 1 : 2;
|
||||
|
||||
if (found != NULL)
|
||||
*found = NULL;
|
||||
|
||||
for (i = 0; i < hostkeys->num_entries; i++) {
|
||||
if (proto == 1 && hostkeys->entries[i].key->type != KEY_RSA1)
|
||||
continue;
|
||||
if (proto == 2 && hostkeys->entries[i].key->type == KEY_RSA1)
|
||||
continue;
|
||||
if (hostkeys->entries[i].marker != want_marker)
|
||||
continue;
|
||||
if (k == NULL) {
|
||||
if (hostkeys->entries[i].key->type != keytype)
|
||||
continue;
|
||||
end_return = HOST_FOUND;
|
||||
if (found != NULL)
|
||||
*found = hostkeys->entries + i;
|
||||
k = hostkeys->entries[i].key;
|
||||
break;
|
||||
}
|
||||
if (want_cert) {
|
||||
if (key_equal_public(k->cert->signature_key,
|
||||
hostkeys->entries[i].key)) {
|
||||
/* A matching CA exists */
|
||||
end_return = HOST_OK;
|
||||
if (found != NULL)
|
||||
*found = hostkeys->entries + i;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (key_equal(k, hostkeys->entries[i].key)) {
|
||||
end_return = HOST_OK;
|
||||
if (found != NULL)
|
||||
*found = hostkeys->entries + i;
|
||||
break;
|
||||
}
|
||||
/* A non-maching key exists */
|
||||
end_return = HOST_CHANGED;
|
||||
if (found != NULL)
|
||||
*found = hostkeys->entries + i;
|
||||
}
|
||||
}
|
||||
if (check_key_not_revoked(hostkeys, k) != 0) {
|
||||
end_return = HOST_REVOKED;
|
||||
if (found != NULL)
|
||||
*found = NULL;
|
||||
}
|
||||
/* Clear variables and close the file. */
|
||||
fclose(f);
|
||||
|
||||
/*
|
||||
* Return either HOST_NEW or HOST_CHANGED, depending on whether we
|
||||
* saw a different key for the host.
|
||||
*/
|
||||
return end_return;
|
||||
}
|
||||
|
||||
HostStatus
|
||||
check_host_in_hostfile(const char *filename, const char *host, const Key *key,
|
||||
Key *found, int *numret)
|
||||
check_key_in_hostkeys(struct hostkeys *hostkeys, Key *key,
|
||||
const struct hostkey_entry **found)
|
||||
{
|
||||
if (key == NULL)
|
||||
fatal("no key to look up");
|
||||
if (check_host_in_hostfile_by_key_or_type(filename, host,
|
||||
key, 0, NULL, 1, NULL) == HOST_REVOKED)
|
||||
return HOST_REVOKED;
|
||||
return check_host_in_hostfile_by_key_or_type(filename, host, key, 0,
|
||||
found, 0, numret);
|
||||
return check_hostkeys_by_key_or_type(hostkeys, key, 0, found);
|
||||
}
|
||||
|
||||
int
|
||||
lookup_key_in_hostfile_by_type(const char *filename, const char *host,
|
||||
int keytype, Key *found, int *numret)
|
||||
lookup_key_in_hostkeys_by_type(struct hostkeys *hostkeys, int keytype,
|
||||
const struct hostkey_entry **found)
|
||||
{
|
||||
return (check_host_in_hostfile_by_key_or_type(filename, host, NULL,
|
||||
keytype, found, 0, numret) == HOST_FOUND);
|
||||
return (check_hostkeys_by_key_or_type(hostkeys, NULL, keytype,
|
||||
found) == HOST_FOUND);
|
||||
}
|
||||
|
||||
/*
|
||||
|
28
hostfile.h
28
hostfile.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: hostfile.h,v 1.18 2010/03/04 10:36:03 djm Exp $ */
|
||||
/* $OpenBSD: hostfile.h,v 1.19 2010/11/29 23:45:51 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -18,12 +18,30 @@ typedef enum {
|
||||
HOST_OK, HOST_NEW, HOST_CHANGED, HOST_REVOKED, HOST_FOUND
|
||||
} HostStatus;
|
||||
|
||||
typedef enum {
|
||||
MRK_ERROR, MRK_NONE, MRK_REVOKE, MRK_CA
|
||||
} HostkeyMarker;
|
||||
|
||||
struct hostkey_entry {
|
||||
char *host;
|
||||
char *file;
|
||||
u_long line;
|
||||
Key *key;
|
||||
HostkeyMarker marker;
|
||||
};
|
||||
struct hostkeys;
|
||||
|
||||
struct hostkeys *init_hostkeys(void);
|
||||
void load_hostkeys(struct hostkeys *, const char *, const char *);
|
||||
void free_hostkeys(struct hostkeys *);
|
||||
|
||||
HostStatus check_key_in_hostkeys(struct hostkeys *, Key *,
|
||||
const struct hostkey_entry **);
|
||||
int lookup_key_in_hostkeys_by_type(struct hostkeys *, int,
|
||||
const struct hostkey_entry **);
|
||||
|
||||
int hostfile_read_key(char **, u_int *, Key *);
|
||||
HostStatus check_host_in_hostfile(const char *, const char *,
|
||||
const Key *, Key *, int *);
|
||||
int add_host_to_hostfile(const char *, const char *, const Key *, int);
|
||||
int lookup_key_in_hostfile_by_type(const char *, const char *,
|
||||
int, Key *, int *);
|
||||
|
||||
#define HASH_MAGIC "|1|"
|
||||
#define HASH_DELIM '|'
|
||||
|
@ -30,7 +30,7 @@
|
||||
# include <bstring.h>
|
||||
#endif
|
||||
#if defined(HAVE_GLOB_H) && defined(GLOB_HAS_ALTDIRFUNC) && \
|
||||
defined(GLOB_HAS_GL_MATCHC) && \
|
||||
defined(GLOB_HAS_GL_MATCHC) && defined(GLOB_HAS_GL_STATV) && \
|
||||
defined(HAVE_DECL_GLOB_NOMATCH) && HAVE_DECL_GLOB_NOMATCH != 0 && \
|
||||
!defined(BROKEN_GLOB)
|
||||
# include <glob.h>
|
||||
|
9
jpake.c
9
jpake.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: jpake.c,v 1.4 2010/07/13 23:13:16 djm Exp $ */
|
||||
/* $OpenBSD: jpake.c,v 1.6 2010/09/20 04:54:07 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008 Damien Miller. All rights reserved.
|
||||
*
|
||||
@ -45,6 +45,7 @@
|
||||
#include "packet.h"
|
||||
#include "dispatch.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
|
||||
#include "jpake.h"
|
||||
#include "schnorr.h"
|
||||
@ -257,8 +258,12 @@ jpake_step2(struct modp_group *grp, BIGNUM *s,
|
||||
/* Validate peer's step 1 values */
|
||||
if (BN_cmp(theirpub1, BN_value_one()) <= 0)
|
||||
fatal("%s: theirpub1 <= 1", __func__);
|
||||
if (BN_cmp(theirpub1, grp->p) >= 0)
|
||||
fatal("%s: theirpub1 >= p", __func__);
|
||||
if (BN_cmp(theirpub2, BN_value_one()) <= 0)
|
||||
fatal("%s: theirpub2 <= 1", __func__);
|
||||
if (BN_cmp(theirpub2, grp->p) >= 0)
|
||||
fatal("%s: theirpub2 >= p", __func__);
|
||||
|
||||
if (schnorr_verify_buf(grp->p, grp->q, grp->g, theirpub1,
|
||||
theirid, theirid_len, theirpub1_proof, theirpub1_proof_len) != 1)
|
||||
@ -363,6 +368,8 @@ jpake_key_confirm(struct modp_group *grp, BIGNUM *s, BIGNUM *step2_val,
|
||||
/* Validate step 2 values */
|
||||
if (BN_cmp(step2_val, BN_value_one()) <= 0)
|
||||
fatal("%s: step2_val <= 1", __func__);
|
||||
if (BN_cmp(step2_val, grp->p) >= 0)
|
||||
fatal("%s: step2_val >= p", __func__);
|
||||
|
||||
/*
|
||||
* theirpriv2_s_proof is calculated with a different generator:
|
||||
|
40
kex.c
40
kex.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kex.c,v 1.82 2009/10/24 11:13:54 andreas Exp $ */
|
||||
/* $OpenBSD: kex.c,v 1.86 2010/09/22 05:01:29 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -62,6 +62,34 @@ extern const EVP_MD *evp_ssh_sha256(void);
|
||||
static void kex_kexinit_finish(Kex *);
|
||||
static void kex_choose_conf(Kex *);
|
||||
|
||||
/* Validate KEX method name list */
|
||||
int
|
||||
kex_names_valid(const char *names)
|
||||
{
|
||||
char *s, *cp, *p;
|
||||
|
||||
if (names == NULL || strcmp(names, "") == 0)
|
||||
return 0;
|
||||
s = cp = xstrdup(names);
|
||||
for ((p = strsep(&cp, ",")); p && *p != '\0';
|
||||
(p = strsep(&cp, ","))) {
|
||||
if (strcmp(p, KEX_DHGEX_SHA256) != 0 &&
|
||||
strcmp(p, KEX_DHGEX_SHA1) != 0 &&
|
||||
strcmp(p, KEX_DH14) != 0 &&
|
||||
strcmp(p, KEX_DH1) != 0 &&
|
||||
(strncmp(p, KEX_ECDH_SHA2_STEM,
|
||||
sizeof(KEX_ECDH_SHA2_STEM) - 1) != 0 ||
|
||||
kex_ecdh_name_to_nid(p) == -1)) {
|
||||
error("Unsupported KEX algorithm \"%.100s\"", p);
|
||||
xfree(s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
debug3("kex names ok: [%s]", names);
|
||||
xfree(s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* put algorithm proposal into buffer */
|
||||
static void
|
||||
kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
|
||||
@ -98,7 +126,7 @@ kex_buf2prop(Buffer *raw, int *first_kex_follows)
|
||||
buffer_get_char(&b);
|
||||
/* extract kex init proposal strings */
|
||||
for (i = 0; i < PROPOSAL_MAX; i++) {
|
||||
proposal[i] = buffer_get_string(&b,NULL);
|
||||
proposal[i] = buffer_get_cstring(&b,NULL);
|
||||
debug2("kex_parse_kexinit: %s", proposal[i]);
|
||||
}
|
||||
/* first kex follows / reserved */
|
||||
@ -325,6 +353,10 @@ choose_kex(Kex *k, char *client, char *server)
|
||||
} else if (strcmp(k->name, KEX_DHGEX_SHA256) == 0) {
|
||||
k->kex_type = KEX_DH_GEX_SHA256;
|
||||
k->evp_md = evp_ssh_sha256();
|
||||
} else if (strncmp(k->name, KEX_ECDH_SHA2_STEM,
|
||||
sizeof(KEX_ECDH_SHA2_STEM) - 1) == 0) {
|
||||
k->kex_type = KEX_ECDH_SHA2;
|
||||
k->evp_md = kex_ecdh_name_to_evpmd(k->name);
|
||||
#endif
|
||||
} else
|
||||
fatal("bad kex alg %s", k->name);
|
||||
@ -559,11 +591,11 @@ derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
|
||||
memset(&md, 0, sizeof(md));
|
||||
}
|
||||
|
||||
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH)
|
||||
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
|
||||
void
|
||||
dump_digest(char *msg, u_char *digest, int len)
|
||||
{
|
||||
u_int i;
|
||||
int i;
|
||||
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
for (i = 0; i < len; i++) {
|
||||
|
25
kex.h
25
kex.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kex.h,v 1.49 2010/02/26 20:29:54 djm Exp $ */
|
||||
/* $OpenBSD: kex.h,v 1.52 2010/09/22 05:01:29 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
@ -29,6 +29,9 @@
|
||||
#include <signal.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
#include <openssl/ec.h>
|
||||
#endif
|
||||
|
||||
#define KEX_COOKIE_LEN 16
|
||||
|
||||
@ -37,6 +40,8 @@
|
||||
#define KEX_DHGEX_SHA1 "diffie-hellman-group-exchange-sha1"
|
||||
#define KEX_DHGEX_SHA256 "diffie-hellman-group-exchange-sha256"
|
||||
#define KEX_RESUME "resume@appgate.com"
|
||||
/* The following represents the family of ECDH methods */
|
||||
#define KEX_ECDH_SHA2_STEM "ecdh-sha2-"
|
||||
|
||||
#define COMP_NONE 0
|
||||
#define COMP_ZLIB 1
|
||||
@ -67,6 +72,7 @@ enum kex_exchange {
|
||||
KEX_DH_GRP14_SHA1,
|
||||
KEX_DH_GEX_SHA1,
|
||||
KEX_DH_GEX_SHA256,
|
||||
KEX_ECDH_SHA2,
|
||||
KEX_MAX
|
||||
};
|
||||
|
||||
@ -132,6 +138,8 @@ struct Kex {
|
||||
void (*kex[KEX_MAX])(Kex *);
|
||||
};
|
||||
|
||||
int kex_names_valid(const char *);
|
||||
|
||||
Kex *kex_setup(char *[PROPOSAL_MAX]);
|
||||
void kex_finish(Kex *);
|
||||
|
||||
@ -145,6 +153,8 @@ void kexdh_client(Kex *);
|
||||
void kexdh_server(Kex *);
|
||||
void kexgex_client(Kex *);
|
||||
void kexgex_server(Kex *);
|
||||
void kexecdh_client(Kex *);
|
||||
void kexecdh_server(Kex *);
|
||||
|
||||
void
|
||||
kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int,
|
||||
@ -153,11 +163,22 @@ void
|
||||
kexgex_hash(const EVP_MD *, char *, char *, char *, int, char *,
|
||||
int, u_char *, int, int, int, int, BIGNUM *, BIGNUM *, BIGNUM *,
|
||||
BIGNUM *, BIGNUM *, u_char **, u_int *);
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
void
|
||||
kex_ecdh_hash(const EVP_MD *, const EC_GROUP *, char *, char *, char *, int,
|
||||
char *, int, u_char *, int, const EC_POINT *, const EC_POINT *,
|
||||
const BIGNUM *, u_char **, u_int *);
|
||||
int kex_ecdh_name_to_nid(const char *);
|
||||
const EVP_MD *kex_ecdh_name_to_evpmd(const char *);
|
||||
#else
|
||||
# define kex_ecdh_name_to_nid(x) (-1)
|
||||
# define kex_ecdh_name_to_evpmd(x) (NULL)
|
||||
#endif
|
||||
|
||||
void
|
||||
derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]);
|
||||
|
||||
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH)
|
||||
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
|
||||
void dump_digest(char *, u_char *, int);
|
||||
#endif
|
||||
|
||||
|
4
kexdhc.c
4
kexdhc.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kexdhc.c,v 1.11 2006/11/06 21:25:28 markus Exp $ */
|
||||
/* $OpenBSD: kexdhc.c,v 1.12 2010/11/10 01:33:07 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -27,6 +27,8 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/dh.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
4
kexdhs.c
4
kexdhs.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kexdhs.c,v 1.11 2010/02/26 20:29:54 djm Exp $ */
|
||||
/* $OpenBSD: kexdhs.c,v 1.12 2010/11/10 01:33:07 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -31,6 +31,8 @@
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <openssl/dh.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "key.h"
|
||||
|
117
kexecdh.c
Normal file
117
kexecdh.c
Normal file
@ -0,0 +1,117 @@
|
||||
/* $OpenBSD: kexecdh.c,v 1.3 2010/09/22 05:01:29 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdh.h>
|
||||
|
||||
#include "buffer.h"
|
||||
#include "ssh2.h"
|
||||
#include "key.h"
|
||||
#include "cipher.h"
|
||||
#include "kex.h"
|
||||
#include "log.h"
|
||||
|
||||
int
|
||||
kex_ecdh_name_to_nid(const char *kexname)
|
||||
{
|
||||
if (strlen(kexname) < sizeof(KEX_ECDH_SHA2_STEM) - 1)
|
||||
fatal("%s: kexname too short \"%s\"", __func__, kexname);
|
||||
return key_curve_name_to_nid(kexname + sizeof(KEX_ECDH_SHA2_STEM) - 1);
|
||||
}
|
||||
|
||||
const EVP_MD *
|
||||
kex_ecdh_name_to_evpmd(const char *kexname)
|
||||
{
|
||||
int nid = kex_ecdh_name_to_nid(kexname);
|
||||
|
||||
if (nid == -1)
|
||||
fatal("%s: unsupported ECDH curve \"%s\"", __func__, kexname);
|
||||
return key_ec_nid_to_evpmd(nid);
|
||||
}
|
||||
|
||||
void
|
||||
kex_ecdh_hash(
|
||||
const EVP_MD *evp_md,
|
||||
const EC_GROUP *ec_group,
|
||||
char *client_version_string,
|
||||
char *server_version_string,
|
||||
char *ckexinit, int ckexinitlen,
|
||||
char *skexinit, int skexinitlen,
|
||||
u_char *serverhostkeyblob, int sbloblen,
|
||||
const EC_POINT *client_dh_pub,
|
||||
const EC_POINT *server_dh_pub,
|
||||
const BIGNUM *shared_secret,
|
||||
u_char **hash, u_int *hashlen)
|
||||
{
|
||||
Buffer b;
|
||||
EVP_MD_CTX md;
|
||||
static u_char digest[EVP_MAX_MD_SIZE];
|
||||
|
||||
buffer_init(&b);
|
||||
buffer_put_cstring(&b, client_version_string);
|
||||
buffer_put_cstring(&b, server_version_string);
|
||||
|
||||
/* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
|
||||
buffer_put_int(&b, ckexinitlen+1);
|
||||
buffer_put_char(&b, SSH2_MSG_KEXINIT);
|
||||
buffer_append(&b, ckexinit, ckexinitlen);
|
||||
buffer_put_int(&b, skexinitlen+1);
|
||||
buffer_put_char(&b, SSH2_MSG_KEXINIT);
|
||||
buffer_append(&b, skexinit, skexinitlen);
|
||||
|
||||
buffer_put_string(&b, serverhostkeyblob, sbloblen);
|
||||
buffer_put_ecpoint(&b, ec_group, client_dh_pub);
|
||||
buffer_put_ecpoint(&b, ec_group, server_dh_pub);
|
||||
buffer_put_bignum2(&b, shared_secret);
|
||||
|
||||
#ifdef DEBUG_KEX
|
||||
buffer_dump(&b);
|
||||
#endif
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
|
||||
EVP_DigestFinal(&md, digest, NULL);
|
||||
|
||||
buffer_free(&b);
|
||||
|
||||
#ifdef DEBUG_KEX
|
||||
dump_digest("hash", digest, EVP_MD_size(evp_md));
|
||||
#endif
|
||||
*hash = digest;
|
||||
*hashlen = EVP_MD_size(evp_md);
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_HAS_ECC */
|
168
kexecdhc.c
Normal file
168
kexecdhc.c
Normal file
@ -0,0 +1,168 @@
|
||||
/* $OpenBSD: kexecdhc.c,v 1.2 2010/09/22 05:01:29 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "key.h"
|
||||
#include "cipher.h"
|
||||
#include "kex.h"
|
||||
#include "log.h"
|
||||
#include "packet.h"
|
||||
#include "dh.h"
|
||||
#include "ssh2.h"
|
||||
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
|
||||
#include <openssl/ecdh.h>
|
||||
|
||||
void
|
||||
kexecdh_client(Kex *kex)
|
||||
{
|
||||
EC_KEY *client_key;
|
||||
EC_POINT *server_public;
|
||||
const EC_GROUP *group;
|
||||
BIGNUM *shared_secret;
|
||||
Key *server_host_key;
|
||||
u_char *server_host_key_blob = NULL, *signature = NULL;
|
||||
u_char *kbuf, *hash;
|
||||
u_int klen, slen, sbloblen, hashlen;
|
||||
int curve_nid;
|
||||
|
||||
if ((curve_nid = kex_ecdh_name_to_nid(kex->name)) == -1)
|
||||
fatal("%s: unsupported ECDH curve \"%s\"", __func__, kex->name);
|
||||
if ((client_key = EC_KEY_new_by_curve_name(curve_nid)) == NULL)
|
||||
fatal("%s: EC_KEY_new_by_curve_name failed", __func__);
|
||||
if (EC_KEY_generate_key(client_key) != 1)
|
||||
fatal("%s: EC_KEY_generate_key failed", __func__);
|
||||
group = EC_KEY_get0_group(client_key);
|
||||
|
||||
packet_start(SSH2_MSG_KEX_ECDH_INIT);
|
||||
packet_put_ecpoint(group, EC_KEY_get0_public_key(client_key));
|
||||
packet_send();
|
||||
debug("sending SSH2_MSG_KEX_ECDH_INIT");
|
||||
|
||||
#ifdef DEBUG_KEXECDH
|
||||
fputs("client private key:\n", stderr);
|
||||
key_dump_ec_key(client_key);
|
||||
#endif
|
||||
|
||||
debug("expecting SSH2_MSG_KEX_ECDH_REPLY");
|
||||
packet_read_expect(SSH2_MSG_KEX_ECDH_REPLY);
|
||||
|
||||
/* hostkey */
|
||||
server_host_key_blob = packet_get_string(&sbloblen);
|
||||
server_host_key = key_from_blob(server_host_key_blob, sbloblen);
|
||||
if (server_host_key == NULL)
|
||||
fatal("cannot decode server_host_key_blob");
|
||||
if (server_host_key->type != kex->hostkey_type)
|
||||
fatal("type mismatch for decoded server_host_key_blob");
|
||||
if (kex->verify_host_key == NULL)
|
||||
fatal("cannot verify server_host_key");
|
||||
if (kex->verify_host_key(server_host_key) == -1)
|
||||
fatal("server_host_key verification failed");
|
||||
|
||||
/* Q_S, server public key */
|
||||
if ((server_public = EC_POINT_new(group)) == NULL)
|
||||
fatal("%s: EC_POINT_new failed", __func__);
|
||||
packet_get_ecpoint(group, server_public);
|
||||
|
||||
if (key_ec_validate_public(group, server_public) != 0)
|
||||
fatal("%s: invalid server public key", __func__);
|
||||
|
||||
#ifdef DEBUG_KEXECDH
|
||||
fputs("server public key:\n", stderr);
|
||||
key_dump_ec_point(group, server_public);
|
||||
#endif
|
||||
|
||||
/* signed H */
|
||||
signature = packet_get_string(&slen);
|
||||
packet_check_eom();
|
||||
|
||||
klen = (EC_GROUP_get_degree(group) + 7) / 8;
|
||||
kbuf = xmalloc(klen);
|
||||
if (ECDH_compute_key(kbuf, klen, server_public,
|
||||
client_key, NULL) != (int)klen)
|
||||
fatal("%s: ECDH_compute_key failed", __func__);
|
||||
|
||||
#ifdef DEBUG_KEXECDH
|
||||
dump_digest("shared secret", kbuf, klen);
|
||||
#endif
|
||||
if ((shared_secret = BN_new()) == NULL)
|
||||
fatal("%s: BN_new failed", __func__);
|
||||
if (BN_bin2bn(kbuf, klen, shared_secret) == NULL)
|
||||
fatal("%s: BN_bin2bn failed", __func__);
|
||||
memset(kbuf, 0, klen);
|
||||
xfree(kbuf);
|
||||
|
||||
/* calc and verify H */
|
||||
kex_ecdh_hash(
|
||||
kex->evp_md,
|
||||
group,
|
||||
kex->client_version_string,
|
||||
kex->server_version_string,
|
||||
buffer_ptr(&kex->my), buffer_len(&kex->my),
|
||||
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
|
||||
server_host_key_blob, sbloblen,
|
||||
EC_KEY_get0_public_key(client_key),
|
||||
server_public,
|
||||
shared_secret,
|
||||
&hash, &hashlen
|
||||
);
|
||||
xfree(server_host_key_blob);
|
||||
EC_POINT_clear_free(server_public);
|
||||
EC_KEY_free(client_key);
|
||||
|
||||
if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1)
|
||||
fatal("key_verify failed for server_host_key");
|
||||
key_free(server_host_key);
|
||||
xfree(signature);
|
||||
|
||||
/* save session id */
|
||||
if (kex->session_id == NULL) {
|
||||
kex->session_id_len = hashlen;
|
||||
kex->session_id = xmalloc(kex->session_id_len);
|
||||
memcpy(kex->session_id, hash, kex->session_id_len);
|
||||
}
|
||||
|
||||
kex_derive_keys(kex, hash, hashlen, shared_secret);
|
||||
BN_clear_free(shared_secret);
|
||||
kex_finish(kex);
|
||||
}
|
||||
#else /* OPENSSL_HAS_ECC */
|
||||
void
|
||||
kexecdh_client(Kex *kex)
|
||||
{
|
||||
fatal("ECC support is not enabled");
|
||||
}
|
||||
#endif /* OPENSSL_HAS_ECC */
|
173
kexecdhs.c
Normal file
173
kexecdhs.c
Normal file
@ -0,0 +1,173 @@
|
||||
/* $OpenBSD: kexecdhs.c,v 1.2 2010/09/22 05:01:29 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "key.h"
|
||||
#include "cipher.h"
|
||||
#include "kex.h"
|
||||
#include "log.h"
|
||||
#include "packet.h"
|
||||
#include "dh.h"
|
||||
#include "ssh2.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
|
||||
#include <openssl/ecdh.h>
|
||||
|
||||
void
|
||||
kexecdh_server(Kex *kex)
|
||||
{
|
||||
EC_POINT *client_public;
|
||||
EC_KEY *server_key;
|
||||
const EC_GROUP *group;
|
||||
BIGNUM *shared_secret;
|
||||
Key *server_host_private, *server_host_public;
|
||||
u_char *server_host_key_blob = NULL, *signature = NULL;
|
||||
u_char *kbuf, *hash;
|
||||
u_int klen, slen, sbloblen, hashlen;
|
||||
int curve_nid;
|
||||
|
||||
if ((curve_nid = kex_ecdh_name_to_nid(kex->name)) == -1)
|
||||
fatal("%s: unsupported ECDH curve \"%s\"", __func__, kex->name);
|
||||
if ((server_key = EC_KEY_new_by_curve_name(curve_nid)) == NULL)
|
||||
fatal("%s: EC_KEY_new_by_curve_name failed", __func__);
|
||||
if (EC_KEY_generate_key(server_key) != 1)
|
||||
fatal("%s: EC_KEY_generate_key failed", __func__);
|
||||
group = EC_KEY_get0_group(server_key);
|
||||
|
||||
#ifdef DEBUG_KEXECDH
|
||||
fputs("server private key:\n", stderr);
|
||||
key_dump_ec_key(server_key);
|
||||
#endif
|
||||
|
||||
if (kex->load_host_public_key == NULL ||
|
||||
kex->load_host_private_key == NULL)
|
||||
fatal("Cannot load hostkey");
|
||||
server_host_public = kex->load_host_public_key(kex->hostkey_type);
|
||||
if (server_host_public == NULL)
|
||||
fatal("Unsupported hostkey type %d", kex->hostkey_type);
|
||||
server_host_private = kex->load_host_private_key(kex->hostkey_type);
|
||||
if (server_host_private == NULL)
|
||||
fatal("Missing private key for hostkey type %d",
|
||||
kex->hostkey_type);
|
||||
|
||||
debug("expecting SSH2_MSG_KEX_ECDH_INIT");
|
||||
packet_read_expect(SSH2_MSG_KEX_ECDH_INIT);
|
||||
if ((client_public = EC_POINT_new(group)) == NULL)
|
||||
fatal("%s: EC_POINT_new failed", __func__);
|
||||
packet_get_ecpoint(group, client_public);
|
||||
packet_check_eom();
|
||||
|
||||
if (key_ec_validate_public(group, client_public) != 0)
|
||||
fatal("%s: invalid client public key", __func__);
|
||||
|
||||
#ifdef DEBUG_KEXECDH
|
||||
fputs("client public key:\n", stderr);
|
||||
key_dump_ec_point(group, client_public);
|
||||
#endif
|
||||
|
||||
/* Calculate shared_secret */
|
||||
klen = (EC_GROUP_get_degree(group) + 7) / 8;
|
||||
kbuf = xmalloc(klen);
|
||||
if (ECDH_compute_key(kbuf, klen, client_public,
|
||||
server_key, NULL) != (int)klen)
|
||||
fatal("%s: ECDH_compute_key failed", __func__);
|
||||
|
||||
#ifdef DEBUG_KEXDH
|
||||
dump_digest("shared secret", kbuf, klen);
|
||||
#endif
|
||||
if ((shared_secret = BN_new()) == NULL)
|
||||
fatal("%s: BN_new failed", __func__);
|
||||
if (BN_bin2bn(kbuf, klen, shared_secret) == NULL)
|
||||
fatal("%s: BN_bin2bn failed", __func__);
|
||||
memset(kbuf, 0, klen);
|
||||
xfree(kbuf);
|
||||
|
||||
/* calc H */
|
||||
key_to_blob(server_host_public, &server_host_key_blob, &sbloblen);
|
||||
kex_ecdh_hash(
|
||||
kex->evp_md,
|
||||
group,
|
||||
kex->client_version_string,
|
||||
kex->server_version_string,
|
||||
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
|
||||
buffer_ptr(&kex->my), buffer_len(&kex->my),
|
||||
server_host_key_blob, sbloblen,
|
||||
client_public,
|
||||
EC_KEY_get0_public_key(server_key),
|
||||
shared_secret,
|
||||
&hash, &hashlen
|
||||
);
|
||||
EC_POINT_clear_free(client_public);
|
||||
|
||||
/* save session id := H */
|
||||
if (kex->session_id == NULL) {
|
||||
kex->session_id_len = hashlen;
|
||||
kex->session_id = xmalloc(kex->session_id_len);
|
||||
memcpy(kex->session_id, hash, kex->session_id_len);
|
||||
}
|
||||
|
||||
/* sign H */
|
||||
if (PRIVSEP(key_sign(server_host_private, &signature, &slen,
|
||||
hash, hashlen)) < 0)
|
||||
fatal("kexdh_server: key_sign failed");
|
||||
|
||||
/* destroy_sensitive_data(); */
|
||||
|
||||
/* send server hostkey, ECDH pubkey 'Q_S' and signed H */
|
||||
packet_start(SSH2_MSG_KEX_ECDH_REPLY);
|
||||
packet_put_string(server_host_key_blob, sbloblen);
|
||||
packet_put_ecpoint(group, EC_KEY_get0_public_key(server_key));
|
||||
packet_put_string(signature, slen);
|
||||
packet_send();
|
||||
|
||||
xfree(signature);
|
||||
xfree(server_host_key_blob);
|
||||
/* have keys, free server key */
|
||||
EC_KEY_free(server_key);
|
||||
|
||||
kex_derive_keys(kex, hash, hashlen, shared_secret);
|
||||
BN_clear_free(shared_secret);
|
||||
kex_finish(kex);
|
||||
}
|
||||
#else /* OPENSSL_HAS_ECC */
|
||||
void
|
||||
kexecdh_server(Kex *kex)
|
||||
{
|
||||
fatal("ECC support is not enabled");
|
||||
}
|
||||
#endif /* OPENSSL_HAS_ECC */
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kexgexc.c,v 1.11 2006/11/06 21:25:28 markus Exp $ */
|
||||
/* $OpenBSD: kexgexc.c,v 1.12 2010/11/10 01:33:07 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Niels Provos. All rights reserved.
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
@ -28,6 +28,8 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/dh.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kexgexs.c,v 1.13 2010/02/26 20:29:54 djm Exp $ */
|
||||
/* $OpenBSD: kexgexs.c,v 1.14 2010/11/10 01:33:07 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Niels Provos. All rights reserved.
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
@ -33,6 +33,8 @@
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <openssl/dh.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "key.h"
|
||||
|
33
key.h
33
key.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: key.h,v 1.30 2010/04/16 01:47:26 djm Exp $ */
|
||||
/* $OpenBSD: key.h,v 1.33 2010/10/28 11:22:09 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
@ -29,14 +29,19 @@
|
||||
#include "buffer.h"
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/dsa.h>
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
#include <openssl/ec.h>
|
||||
#endif
|
||||
|
||||
typedef struct Key Key;
|
||||
enum types {
|
||||
KEY_RSA1,
|
||||
KEY_RSA,
|
||||
KEY_DSA,
|
||||
KEY_ECDSA,
|
||||
KEY_RSA_CERT,
|
||||
KEY_DSA_CERT,
|
||||
KEY_ECDSA_CERT,
|
||||
KEY_RSA_CERT_V00,
|
||||
KEY_DSA_CERT_V00,
|
||||
KEY_UNSPEC
|
||||
@ -73,6 +78,12 @@ struct Key {
|
||||
int flags;
|
||||
RSA *rsa;
|
||||
DSA *dsa;
|
||||
int ecdsa_nid; /* NID of curve */
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
EC_KEY *ecdsa;
|
||||
#else
|
||||
void *ecdsa;
|
||||
#endif
|
||||
struct KeyCert *cert;
|
||||
};
|
||||
|
||||
@ -104,9 +115,22 @@ int key_cert_check_authority(const Key *, int, int, const char *,
|
||||
const char **);
|
||||
int key_cert_is_legacy(Key *);
|
||||
|
||||
int key_ecdsa_nid_from_name(const char *);
|
||||
int key_curve_name_to_nid(const char *);
|
||||
const char * key_curve_nid_to_name(int);
|
||||
u_int key_curve_nid_to_bits(int);
|
||||
int key_ecdsa_bits_to_nid(int);
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
int key_ecdsa_key_to_nid(EC_KEY *);
|
||||
const EVP_MD * key_ec_nid_to_evpmd(int nid);
|
||||
int key_ec_validate_public(const EC_GROUP *, const EC_POINT *);
|
||||
int key_ec_validate_private(const EC_KEY *);
|
||||
#endif
|
||||
|
||||
Key *key_from_blob(const u_char *, u_int);
|
||||
int key_to_blob(const Key *, u_char **, u_int *);
|
||||
const char *key_ssh_name(const Key *);
|
||||
const char *key_ssh_name_plain(const Key *);
|
||||
int key_names_valid2(const char *);
|
||||
|
||||
int key_sign(const Key *, u_char **, u_int *, const u_char *, u_int);
|
||||
@ -114,7 +138,14 @@ int key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
|
||||
|
||||
int ssh_dss_sign(const Key *, u_char **, u_int *, const u_char *, u_int);
|
||||
int ssh_dss_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
|
||||
int ssh_ecdsa_sign(const Key *, u_char **, u_int *, const u_char *, u_int);
|
||||
int ssh_ecdsa_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
|
||||
int ssh_rsa_sign(const Key *, u_char **, u_int *, const u_char *, u_int);
|
||||
int ssh_rsa_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
|
||||
|
||||
#if defined(OPENSSL_HAS_ECC) && (defined(DEBUG_KEXECDH) || defined(DEBUG_PK))
|
||||
void key_dump_ec_point(const EC_GROUP *, const EC_POINT *);
|
||||
void key_dump_ec_key(const EC_KEY *);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
26
loginrec.c
26
loginrec.c
@ -273,7 +273,7 @@ login_logout(struct logininfo *li)
|
||||
* try to retrieve lastlog information from wtmp/wtmpx.
|
||||
*/
|
||||
unsigned int
|
||||
login_get_lastlog_time(const int uid)
|
||||
login_get_lastlog_time(const uid_t uid)
|
||||
{
|
||||
struct logininfo li;
|
||||
|
||||
@ -297,7 +297,7 @@ login_get_lastlog_time(const int uid)
|
||||
* 0 on failure (will use OpenSSH's logging facilities for diagnostics)
|
||||
*/
|
||||
struct logininfo *
|
||||
login_get_lastlog(struct logininfo *li, const int uid)
|
||||
login_get_lastlog(struct logininfo *li, const uid_t uid)
|
||||
{
|
||||
struct passwd *pw;
|
||||
|
||||
@ -311,7 +311,8 @@ login_get_lastlog(struct logininfo *li, const int uid)
|
||||
*/
|
||||
pw = getpwuid(uid);
|
||||
if (pw == NULL)
|
||||
fatal("%s: Cannot find account for uid %i", __func__, uid);
|
||||
fatal("%s: Cannot find account for uid %ld", __func__,
|
||||
(long)uid);
|
||||
|
||||
/* No MIN_SIZEOF here - we absolutely *must not* truncate the
|
||||
* username (XXX - so check for trunc!) */
|
||||
@ -335,7 +336,7 @@ login_get_lastlog(struct logininfo *li, const int uid)
|
||||
* allocation fails, the program halts.
|
||||
*/
|
||||
struct
|
||||
logininfo *login_alloc_entry(int pid, const char *username,
|
||||
logininfo *login_alloc_entry(pid_t pid, const char *username,
|
||||
const char *hostname, const char *line)
|
||||
{
|
||||
struct logininfo *newli;
|
||||
@ -363,7 +364,7 @@ login_free_entry(struct logininfo *li)
|
||||
* Returns: 1
|
||||
*/
|
||||
int
|
||||
login_init_entry(struct logininfo *li, int pid, const char *username,
|
||||
login_init_entry(struct logininfo *li, pid_t pid, const char *username,
|
||||
const char *hostname, const char *line)
|
||||
{
|
||||
struct passwd *pw;
|
||||
@ -468,9 +469,9 @@ login_write(struct logininfo *li)
|
||||
#endif
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
if (li->type == LTYPE_LOGIN)
|
||||
audit_session_open(li->line);
|
||||
audit_session_open(li);
|
||||
else if (li->type == LTYPE_LOGOUT)
|
||||
audit_session_close(li->line);
|
||||
audit_session_close(li);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
@ -872,11 +873,13 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut)
|
||||
pos = (off_t)tty * sizeof(struct utmp);
|
||||
if ((ret = lseek(fd, pos, SEEK_SET)) == -1) {
|
||||
logit("%s: lseek: %s", __func__, strerror(errno));
|
||||
close(fd);
|
||||
return (0);
|
||||
}
|
||||
if (ret != pos) {
|
||||
logit("%s: Couldn't seek to tty %d slot in %s",
|
||||
__func__, tty, UTMP_FILE);
|
||||
close(fd);
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
@ -892,16 +895,20 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut)
|
||||
|
||||
if ((ret = lseek(fd, pos, SEEK_SET)) == -1) {
|
||||
logit("%s: lseek: %s", __func__, strerror(errno));
|
||||
close(fd);
|
||||
return (0);
|
||||
}
|
||||
if (ret != pos) {
|
||||
logit("%s: Couldn't seek to tty %d slot in %s",
|
||||
__func__, tty, UTMP_FILE);
|
||||
close(fd);
|
||||
return (0);
|
||||
}
|
||||
if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) {
|
||||
logit("%s: error writing %s: %s", __func__,
|
||||
UTMP_FILE, strerror(errno));
|
||||
close(fd);
|
||||
return (0);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
@ -1496,11 +1503,12 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode)
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
/* find this uid's offset in the lastlog file */
|
||||
offset = (off_t) ((long)li->uid * sizeof(struct lastlog));
|
||||
offset = (off_t) ((u_long)li->uid * sizeof(struct lastlog));
|
||||
|
||||
if (lseek(*fd, offset, SEEK_SET) != offset) {
|
||||
logit("%s: %s->lseek(): %s", __func__,
|
||||
lastlog_file, strerror(errno));
|
||||
close(*fd);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
@ -1672,7 +1680,7 @@ record_failed_login(const char *username, const char *hostname,
|
||||
strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
if((fst.st_mode & (S_IRWXG | S_IRWXO)) || (fst.st_uid != 0)){
|
||||
if((fst.st_mode & (S_IXGRP | S_IRWXO)) || (fst.st_uid != 0)){
|
||||
logit("Excess permission or bad ownership on file %s",
|
||||
_PATH_BTMP);
|
||||
goto out;
|
||||
|
12
loginrec.h
12
loginrec.h
@ -63,8 +63,8 @@ struct logininfo {
|
||||
char progname[LINFO_PROGSIZE]; /* name of program (for PAM) */
|
||||
int progname_null;
|
||||
short int type; /* type of login (LTYPE_*) */
|
||||
int pid; /* PID of login process */
|
||||
int uid; /* UID of this user */
|
||||
pid_t pid; /* PID of login process */
|
||||
uid_t uid; /* UID of this user */
|
||||
char line[LINFO_LINESIZE]; /* tty/pty name */
|
||||
char username[LINFO_NAMESIZE]; /* login username */
|
||||
char hostname[LINFO_HOSTSIZE]; /* remote hostname */
|
||||
@ -86,12 +86,12 @@ struct logininfo {
|
||||
/** 'public' functions */
|
||||
|
||||
/* construct a new login entry */
|
||||
struct logininfo *login_alloc_entry(int pid, const char *username,
|
||||
struct logininfo *login_alloc_entry(pid_t pid, const char *username,
|
||||
const char *hostname, const char *line);
|
||||
/* free a structure */
|
||||
void login_free_entry(struct logininfo *li);
|
||||
/* fill out a pre-allocated structure with useful information */
|
||||
int login_init_entry(struct logininfo *li, int pid, const char *username,
|
||||
int login_init_entry(struct logininfo *li, pid_t pid, const char *username,
|
||||
const char *hostname, const char *line);
|
||||
/* place the current time in a logininfo struct */
|
||||
void login_set_current_time(struct logininfo *li);
|
||||
@ -117,9 +117,9 @@ void login_set_addr(struct logininfo *li, const struct sockaddr *sa,
|
||||
* lastlog retrieval functions
|
||||
*/
|
||||
/* lastlog *entry* functions fill out a logininfo */
|
||||
struct logininfo *login_get_lastlog(struct logininfo *li, const int uid);
|
||||
struct logininfo *login_get_lastlog(struct logininfo *li, const uid_t uid);
|
||||
/* lastlog *time* functions return time_t equivalent (uint) */
|
||||
unsigned int login_get_lastlog_time(const int uid);
|
||||
unsigned int login_get_lastlog_time(const uid_t uid);
|
||||
|
||||
/* produce various forms of the line filename */
|
||||
char *line_fullname(char *dst, const char *src, u_int dstsize);
|
||||
|
143
misc.c
143
misc.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: misc.c,v 1.80 2010/07/21 02:10:58 djm Exp $ */
|
||||
/* $OpenBSD: misc.c,v 1.84 2010/11/21 01:01:13 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
|
||||
@ -35,9 +35,12 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
#include <errno.h>
|
||||
@ -850,16 +853,138 @@ 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)
|
||||
void
|
||||
bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen)
|
||||
{
|
||||
const unsigned char *p1 = b1, *p2 = b2;
|
||||
int ret = 0;
|
||||
|
||||
for (; n > 0; n--)
|
||||
ret |= *p1++ ^ *p2++;
|
||||
return (ret != 0);
|
||||
bw->buflen = buflen;
|
||||
bw->rate = kbps;
|
||||
bw->thresh = bw->rate;
|
||||
bw->lamt = 0;
|
||||
timerclear(&bw->bwstart);
|
||||
timerclear(&bw->bwend);
|
||||
}
|
||||
|
||||
/* Callback from read/write loop to insert bandwidth-limiting delays */
|
||||
void
|
||||
bandwidth_limit(struct bwlimit *bw, size_t read_len)
|
||||
{
|
||||
u_int64_t waitlen;
|
||||
struct timespec ts, rm;
|
||||
|
||||
if (!timerisset(&bw->bwstart)) {
|
||||
gettimeofday(&bw->bwstart, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
bw->lamt += read_len;
|
||||
if (bw->lamt < bw->thresh)
|
||||
return;
|
||||
|
||||
gettimeofday(&bw->bwend, NULL);
|
||||
timersub(&bw->bwend, &bw->bwstart, &bw->bwend);
|
||||
if (!timerisset(&bw->bwend))
|
||||
return;
|
||||
|
||||
bw->lamt *= 8;
|
||||
waitlen = (double)1000000L * bw->lamt / bw->rate;
|
||||
|
||||
bw->bwstart.tv_sec = waitlen / 1000000L;
|
||||
bw->bwstart.tv_usec = waitlen % 1000000L;
|
||||
|
||||
if (timercmp(&bw->bwstart, &bw->bwend, >)) {
|
||||
timersub(&bw->bwstart, &bw->bwend, &bw->bwend);
|
||||
|
||||
/* Adjust the wait time */
|
||||
if (bw->bwend.tv_sec) {
|
||||
bw->thresh /= 2;
|
||||
if (bw->thresh < bw->buflen / 4)
|
||||
bw->thresh = bw->buflen / 4;
|
||||
} else if (bw->bwend.tv_usec < 10000) {
|
||||
bw->thresh *= 2;
|
||||
if (bw->thresh > bw->buflen * 8)
|
||||
bw->thresh = bw->buflen * 8;
|
||||
}
|
||||
|
||||
TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts);
|
||||
while (nanosleep(&ts, &rm) == -1) {
|
||||
if (errno != EINTR)
|
||||
break;
|
||||
ts = rm;
|
||||
}
|
||||
}
|
||||
|
||||
bw->lamt = 0;
|
||||
gettimeofday(&bw->bwstart, NULL);
|
||||
}
|
||||
|
||||
/* Make a template filename for mk[sd]temp() */
|
||||
void
|
||||
mktemp_proto(char *s, size_t len)
|
||||
{
|
||||
const char *tmpdir;
|
||||
int r;
|
||||
|
||||
if ((tmpdir = getenv("TMPDIR")) != NULL) {
|
||||
r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir);
|
||||
if (r > 0 && (size_t)r < len)
|
||||
return;
|
||||
}
|
||||
r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX");
|
||||
if (r < 0 || (size_t)r >= len)
|
||||
fatal("%s: template string too short", __func__);
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
int value;
|
||||
} ipqos[] = {
|
||||
{ "af11", IPTOS_DSCP_AF11 },
|
||||
{ "af12", IPTOS_DSCP_AF12 },
|
||||
{ "af13", IPTOS_DSCP_AF13 },
|
||||
{ "af14", IPTOS_DSCP_AF21 },
|
||||
{ "af22", IPTOS_DSCP_AF22 },
|
||||
{ "af23", IPTOS_DSCP_AF23 },
|
||||
{ "af31", IPTOS_DSCP_AF31 },
|
||||
{ "af32", IPTOS_DSCP_AF32 },
|
||||
{ "af33", IPTOS_DSCP_AF33 },
|
||||
{ "af41", IPTOS_DSCP_AF41 },
|
||||
{ "af42", IPTOS_DSCP_AF42 },
|
||||
{ "af43", IPTOS_DSCP_AF43 },
|
||||
{ "cs0", IPTOS_DSCP_CS0 },
|
||||
{ "cs1", IPTOS_DSCP_CS1 },
|
||||
{ "cs2", IPTOS_DSCP_CS2 },
|
||||
{ "cs3", IPTOS_DSCP_CS3 },
|
||||
{ "cs4", IPTOS_DSCP_CS4 },
|
||||
{ "cs5", IPTOS_DSCP_CS5 },
|
||||
{ "cs6", IPTOS_DSCP_CS6 },
|
||||
{ "cs7", IPTOS_DSCP_CS7 },
|
||||
{ "ef", IPTOS_DSCP_EF },
|
||||
{ "lowdelay", IPTOS_LOWDELAY },
|
||||
{ "throughput", IPTOS_THROUGHPUT },
|
||||
{ "reliability", IPTOS_RELIABILITY },
|
||||
{ NULL, -1 }
|
||||
};
|
||||
|
||||
int
|
||||
parse_ipqos(const char *cp)
|
||||
{
|
||||
u_int i;
|
||||
char *ep;
|
||||
long val;
|
||||
|
||||
if (cp == NULL)
|
||||
return -1;
|
||||
for (i = 0; ipqos[i].name != NULL; i++) {
|
||||
if (strcasecmp(cp, ipqos[i].name) == 0)
|
||||
return ipqos[i].value;
|
||||
}
|
||||
/* Try parsing as an integer */
|
||||
val = strtol(cp, &ep, 0);
|
||||
if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255)
|
||||
return -1;
|
||||
return val;
|
||||
}
|
||||
|
||||
void
|
||||
sock_set_v6only(int s)
|
||||
{
|
||||
|
14
misc.h
14
misc.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: misc.h,v 1.43 2010/07/13 23:13:16 djm Exp $ */
|
||||
/* $OpenBSD: misc.h,v 1.47 2010/11/21 01:01:13 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -36,7 +36,6 @@ 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);
|
||||
@ -80,6 +79,17 @@ void put_u32(void *, u_int32_t)
|
||||
void put_u16(void *, u_int16_t)
|
||||
__attribute__((__bounded__( __minbytes__, 1, 2)));
|
||||
|
||||
struct bwlimit {
|
||||
size_t buflen;
|
||||
u_int64_t rate, thresh, lamt;
|
||||
struct timeval bwstart, bwend;
|
||||
};
|
||||
|
||||
void bandwidth_limit_init(struct bwlimit *, u_int64_t, size_t);
|
||||
void bandwidth_limit(struct bwlimit *, size_t);
|
||||
|
||||
int parse_ipqos(const char *);
|
||||
void mktemp_proto(char *, size_t);
|
||||
|
||||
/* readpass.c */
|
||||
|
||||
|
1
moduli.0
1
moduli.0
@ -17,7 +17,6 @@ DESCRIPTION
|
||||
The file consists of newline-separated records, one per modulus,
|
||||
containing seven space separated fields. These fields are as follows:
|
||||
|
||||
|
||||
timestamp The time that the modulus was last processed as
|
||||
YYYYMMDDHHMMSS.
|
||||
|
||||
|
10
moduli.c
10
moduli.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: moduli.c,v 1.21 2008/06/26 09:19:40 djm Exp $ */
|
||||
/* $OpenBSD: moduli.c,v 1.22 2010/11/10 01:33:07 djm Exp $ */
|
||||
/*
|
||||
* Copyright 1994 Phil Karn <karn@qualcomm.com>
|
||||
* Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com>
|
||||
@ -54,6 +54,8 @@
|
||||
#include "dh.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
|
||||
/*
|
||||
* File output defines
|
||||
*/
|
||||
@ -600,7 +602,7 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted)
|
||||
* that p is also prime. A single pass will weed out the
|
||||
* vast majority of composite q's.
|
||||
*/
|
||||
if (BN_is_prime(q, 1, NULL, ctx, NULL) <= 0) {
|
||||
if (BN_is_prime_ex(q, 1, ctx, NULL) <= 0) {
|
||||
debug("%10u: q failed first possible prime test",
|
||||
count_in);
|
||||
continue;
|
||||
@ -613,14 +615,14 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted)
|
||||
* will show up on the first Rabin-Miller iteration so it
|
||||
* doesn't hurt to specify a high iteration count.
|
||||
*/
|
||||
if (!BN_is_prime(p, trials, NULL, ctx, NULL)) {
|
||||
if (!BN_is_prime_ex(p, trials, ctx, NULL)) {
|
||||
debug("%10u: p is not prime", count_in);
|
||||
continue;
|
||||
}
|
||||
debug("%10u: p is almost certainly prime", count_in);
|
||||
|
||||
/* recheck q more rigorously */
|
||||
if (!BN_is_prime(q, trials - 1, NULL, ctx, NULL)) {
|
||||
if (!BN_is_prime_ex(q, trials - 1, ctx, NULL)) {
|
||||
debug("%10u: q is not prime", count_in);
|
||||
continue;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: monitor.c,v 1.108 2010/07/13 23:13:16 djm Exp $ */
|
||||
/* $OpenBSD: monitor.c,v 1.110 2010/09/09 10:45:45 djm Exp $ */
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||
@ -590,10 +590,10 @@ mm_answer_sign(int sock, Buffer *m)
|
||||
p = buffer_get_string(m, &datlen);
|
||||
|
||||
/*
|
||||
* Supported KEX types will only return SHA1 (20 byte) or
|
||||
* SHA256 (32 byte) hashes
|
||||
* Supported KEX types use SHA1 (20 bytes), SHA256 (32 bytes),
|
||||
* SHA384 (48 bytes) and SHA512 (64 bytes).
|
||||
*/
|
||||
if (datlen != 20 && datlen != 32)
|
||||
if (datlen != 20 && datlen != 32 && datlen != 48 && datlen != 64)
|
||||
fatal("%s: data length incorrect: %u", __func__, datlen);
|
||||
|
||||
/* save session id, it will be passed on the first call */
|
||||
@ -1691,6 +1691,7 @@ mm_get_kex(Buffer *m)
|
||||
kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
|
||||
kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
|
||||
kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
|
||||
kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
|
||||
kex->server = 1;
|
||||
kex->hostkey_type = buffer_get_int(m);
|
||||
kex->kex_type = buffer_get_int(m);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: monitor_wrap.c,v 1.69 2010/03/07 11:57:13 dtucker Exp $ */
|
||||
/* $OpenBSD: monitor_wrap.c,v 1.70 2010/08/31 11:54:45 djm Exp $ */
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||
@ -73,6 +73,7 @@
|
||||
#include "misc.h"
|
||||
#include "schnorr.h"
|
||||
#include "jpake.h"
|
||||
#include "uuencode.h"
|
||||
|
||||
#include "channels.h"
|
||||
#include "session.h"
|
||||
|
60
mux.c
60
mux.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: mux.c,v 1.21 2010/06/25 23:15:36 djm Exp $ */
|
||||
/* $OpenBSD: mux.c,v 1.24 2011/01/13 21:54:53 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
|
||||
*
|
||||
@ -879,7 +879,7 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
||||
|
||||
if (options.control_master == SSHCTL_MASTER_ASK ||
|
||||
options.control_master == SSHCTL_MASTER_AUTO_ASK) {
|
||||
if (!ask_permission("Allow forward to to %s:%u? ",
|
||||
if (!ask_permission("Allow forward to %s:%u? ",
|
||||
chost, cport)) {
|
||||
debug2("%s: stdio fwd refused by user", __func__);
|
||||
/* prepare reply */
|
||||
@ -1026,6 +1026,9 @@ muxserver_listen(void)
|
||||
struct sockaddr_un addr;
|
||||
socklen_t sun_len;
|
||||
mode_t old_umask;
|
||||
char *orig_control_path = options.control_path;
|
||||
char rbuf[16+1];
|
||||
u_int i, r;
|
||||
|
||||
if (options.control_path == NULL ||
|
||||
options.control_master == SSHCTL_MASTER_NO)
|
||||
@ -1033,6 +1036,23 @@ muxserver_listen(void)
|
||||
|
||||
debug("setting up multiplex master socket");
|
||||
|
||||
/*
|
||||
* Use a temporary path before listen so we can pseudo-atomically
|
||||
* establish the listening socket in its final location to avoid
|
||||
* other processes racing in between bind() and listen() and hitting
|
||||
* an unready socket.
|
||||
*/
|
||||
for (i = 0; i < sizeof(rbuf) - 1; i++) {
|
||||
r = arc4random_uniform(26+26+10);
|
||||
rbuf[i] = (r < 26) ? 'a' + r :
|
||||
(r < 26*2) ? 'A' + r - 26 :
|
||||
'0' + r - 26 - 26;
|
||||
}
|
||||
rbuf[sizeof(rbuf) - 1] = '\0';
|
||||
options.control_path = NULL;
|
||||
xasprintf(&options.control_path, "%s.%s", orig_control_path, rbuf);
|
||||
debug3("%s: temporary control path %s", __func__, options.control_path);
|
||||
|
||||
memset(&addr, '\0', sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
sun_len = offsetof(struct sockaddr_un, sun_path) +
|
||||
@ -1051,6 +1071,7 @@ muxserver_listen(void)
|
||||
if (errno == EINVAL || errno == EADDRINUSE) {
|
||||
error("ControlSocket %s already exists, "
|
||||
"disabling multiplexing", options.control_path);
|
||||
disable_mux_master:
|
||||
close(muxserver_sock);
|
||||
muxserver_sock = -1;
|
||||
xfree(options.control_path);
|
||||
@ -1065,12 +1086,29 @@ muxserver_listen(void)
|
||||
if (listen(muxserver_sock, 64) == -1)
|
||||
fatal("%s listen(): %s", __func__, strerror(errno));
|
||||
|
||||
/* Now atomically "move" the mux socket into position */
|
||||
if (link(options.control_path, orig_control_path) != 0) {
|
||||
if (errno != EEXIST) {
|
||||
fatal("%s: link mux listener %s => %s: %s", __func__,
|
||||
options.control_path, orig_control_path,
|
||||
strerror(errno));
|
||||
}
|
||||
error("ControlSocket %s already exists, disabling multiplexing",
|
||||
orig_control_path);
|
||||
xfree(orig_control_path);
|
||||
unlink(options.control_path);
|
||||
goto disable_mux_master;
|
||||
}
|
||||
unlink(options.control_path);
|
||||
xfree(options.control_path);
|
||||
options.control_path = orig_control_path;
|
||||
|
||||
set_nonblock(muxserver_sock);
|
||||
|
||||
mux_listener_channel = channel_new("mux listener",
|
||||
SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1,
|
||||
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
|
||||
0, addr.sun_path, 1);
|
||||
0, options.control_path, 1);
|
||||
mux_listener_channel->mux_rcb = mux_master_read_cb;
|
||||
debug3("%s: mux listener channel %d fd %d", __func__,
|
||||
mux_listener_channel->self, mux_listener_channel->sock);
|
||||
@ -1492,7 +1530,7 @@ mux_client_request_forward(int fd, u_int ftype, Forward *fwd)
|
||||
case MUX_S_FAILURE:
|
||||
e = buffer_get_string(&m, NULL);
|
||||
buffer_free(&m);
|
||||
error("%s: session request failed: %s", __func__, e);
|
||||
error("%s: forwarding request failed: %s", __func__, e);
|
||||
return -1;
|
||||
default:
|
||||
fatal("%s: unexpected response from master 0x%08x",
|
||||
@ -1611,12 +1649,12 @@ mux_client_request_session(int fd)
|
||||
case MUX_S_PERMISSION_DENIED:
|
||||
e = buffer_get_string(&m, NULL);
|
||||
buffer_free(&m);
|
||||
error("Master refused forwarding request: %s", e);
|
||||
error("Master refused session request: %s", e);
|
||||
return -1;
|
||||
case MUX_S_FAILURE:
|
||||
e = buffer_get_string(&m, NULL);
|
||||
buffer_free(&m);
|
||||
error("%s: forwarding request failed: %s", __func__, e);
|
||||
error("%s: session request failed: %s", __func__, e);
|
||||
return -1;
|
||||
default:
|
||||
buffer_free(&m);
|
||||
@ -1743,7 +1781,7 @@ mux_client_request_stdio_fwd(int fd)
|
||||
case MUX_S_PERMISSION_DENIED:
|
||||
e = buffer_get_string(&m, NULL);
|
||||
buffer_free(&m);
|
||||
fatal("Master refused forwarding request: %s", e);
|
||||
fatal("Master refused stdio forwarding request: %s", e);
|
||||
case MUX_S_FAILURE:
|
||||
e = buffer_get_string(&m, NULL);
|
||||
buffer_free(&m);
|
||||
@ -1823,9 +1861,13 @@ muxclient(const char *path)
|
||||
fatal("Control socket connect(%.100s): %s", path,
|
||||
strerror(errno));
|
||||
}
|
||||
if (errno == ENOENT)
|
||||
if (errno == ECONNREFUSED &&
|
||||
options.control_master != SSHCTL_MASTER_NO) {
|
||||
debug("Stale control socket %.100s, unlinking", path);
|
||||
unlink(path);
|
||||
} else if (errno == ENOENT) {
|
||||
debug("Control socket \"%.100s\" does not exist", path);
|
||||
else {
|
||||
} else {
|
||||
error("Control socket connect(%.100s): %s", path,
|
||||
strerror(errno));
|
||||
}
|
||||
|
49
myproposal.h
49
myproposal.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: myproposal.h,v 1.25 2010/04/16 01:47:26 djm Exp $ */
|
||||
/* $OpenBSD: myproposal.h,v 1.27 2010/09/01 22:42:13 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -26,26 +26,49 @@
|
||||
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
/* Old OpenSSL doesn't support what we need for DHGEX-sha256 */
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00907000L
|
||||
# define KEX_DEFAULT_KEX \
|
||||
"diffie-hellman-group-exchange-sha1," \
|
||||
"diffie-hellman-group14-sha1," \
|
||||
"diffie-hellman-group1-sha1"
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
# define KEX_ECDH_METHODS \
|
||||
"ecdh-sha2-nistp256," \
|
||||
"ecdh-sha2-nistp384," \
|
||||
"ecdh-sha2-nistp521,"
|
||||
# define HOSTKEY_ECDSA_CERT_METHODS \
|
||||
"ecdsa-sha2-nistp256-cert-v01@openssh.com," \
|
||||
"ecdsa-sha2-nistp384-cert-v01@openssh.com," \
|
||||
"ecdsa-sha2-nistp521-cert-v01@openssh.com,"
|
||||
# define HOSTKEY_ECDSA_METHODS \
|
||||
"ecdsa-sha2-nistp256," \
|
||||
"ecdsa-sha2-nistp384," \
|
||||
"ecdsa-sha2-nistp521,"
|
||||
#else
|
||||
# define KEX_DEFAULT_KEX \
|
||||
"diffie-hellman-group-exchange-sha256," \
|
||||
"diffie-hellman-group-exchange-sha1," \
|
||||
"diffie-hellman-group14-sha1," \
|
||||
"diffie-hellman-group1-sha1"
|
||||
# define KEX_ECDH_METHODS
|
||||
# define HOSTKEY_ECDSA_CERT_METHODS
|
||||
# define HOSTKEY_ECDSA_METHODS
|
||||
#endif
|
||||
|
||||
/* Old OpenSSL doesn't support what we need for DHGEX-sha256 */
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
|
||||
# define KEX_SHA256_METHODS \
|
||||
"diffie-hellman-group-exchange-sha256,"
|
||||
#else
|
||||
# define KEX_SHA256_METHODS
|
||||
#endif
|
||||
|
||||
# define KEX_DEFAULT_KEX \
|
||||
KEX_ECDH_METHODS \
|
||||
KEX_SHA256_METHODS \
|
||||
"diffie-hellman-group-exchange-sha1," \
|
||||
"diffie-hellman-group14-sha1," \
|
||||
"diffie-hellman-group1-sha1"
|
||||
|
||||
#define KEX_DEFAULT_PK_ALG \
|
||||
HOSTKEY_ECDSA_CERT_METHODS \
|
||||
"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"
|
||||
HOSTKEY_ECDSA_METHODS \
|
||||
"ssh-rsa," \
|
||||
"ssh-dss"
|
||||
|
||||
#define KEX_DEFAULT_ENCRYPT \
|
||||
"aes128-ctr,aes192-ctr,aes256-ctr," \
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: Makefile.in,v 1.45 2010/08/16 03:15:23 dtucker Exp $
|
||||
# $Id: Makefile.in,v 1.46 2010/10/07 11:19:24 djm Exp $
|
||||
|
||||
sysconfdir=@sysconfdir@
|
||||
piddir=@piddir@
|
||||
@ -16,7 +16,7 @@ RANLIB=@RANLIB@
|
||||
INSTALL=@INSTALL@
|
||||
LDFLAGS=-L. @LDFLAGS@
|
||||
|
||||
OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o vis.o
|
||||
OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o timingsafe_bcmp.o vis.o
|
||||
|
||||
COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o
|
||||
|
||||
|
@ -89,7 +89,7 @@ bindresvport_sa(int sd, struct sockaddr *sa)
|
||||
|
||||
port = ntohs(*portp);
|
||||
if (port == 0)
|
||||
port = (arc4random() % NPORTS) + STARTPORT;
|
||||
port = arc4random_uniform(NPORTS) + STARTPORT;
|
||||
|
||||
/* Avoid warning */
|
||||
error = -1;
|
||||
|
@ -240,3 +240,10 @@ strdup(const char *str)
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_ISBLANK
|
||||
int isblank(int c)
|
||||
{
|
||||
return (c == ' ' || c == '\t');
|
||||
}
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: bsd-misc.h,v 1.18 2005/02/25 23:07:38 dtucker Exp $ */
|
||||
/* $Id: bsd-misc.h,v 1.19 2010/11/08 22:26:23 tim Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Damien Miller <djm@mindrot.org>
|
||||
@ -95,4 +95,8 @@ mysig_t mysignal(int sig, mysig_t act);
|
||||
|
||||
#define signal(a,b) mysignal(a,b)
|
||||
|
||||
#ifndef HAVE_ISBLANK
|
||||
int isblank(int);
|
||||
#endif
|
||||
|
||||
#endif /* _BSD_MISC_H */
|
||||
|
31
openbsd-compat/charclass.h
Normal file
31
openbsd-compat/charclass.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Public domain, 2008, Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* $OpenBSD: charclass.h,v 1.1 2008/10/01 23:04:13 millert Exp $
|
||||
*/
|
||||
|
||||
/* OPENBSD ORIGINAL: lib/libc/gen/charclass.h */
|
||||
|
||||
/*
|
||||
* POSIX character class support for fnmatch() and glob().
|
||||
*/
|
||||
static struct cclass {
|
||||
const char *name;
|
||||
int (*isctype)(int);
|
||||
} cclasses[] = {
|
||||
{ "alnum", isalnum },
|
||||
{ "alpha", isalpha },
|
||||
{ "blank", isblank },
|
||||
{ "cntrl", iscntrl },
|
||||
{ "digit", isdigit },
|
||||
{ "graph", isgraph },
|
||||
{ "lower", islower },
|
||||
{ "print", isprint },
|
||||
{ "punct", ispunct },
|
||||
{ "space", isspace },
|
||||
{ "upper", isupper },
|
||||
{ "xdigit", isxdigit },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
#define NCCLASSES (sizeof(cclasses) / sizeof(cclasses[0]) - 1)
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: glob.c,v 1.26 2005/11/28 17:50:12 deraadt Exp $ */
|
||||
/* $OpenBSD: glob.c,v 1.35 2011/01/12 01:53:14 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@ -33,36 +33,6 @@
|
||||
|
||||
/* OPENBSD ORIGINAL: lib/libc/gen/glob.c */
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || \
|
||||
!defined(GLOB_HAS_GL_MATCHC) || \
|
||||
!defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \
|
||||
defined(BROKEN_GLOB)
|
||||
|
||||
static long
|
||||
get_arg_max(void)
|
||||
{
|
||||
#ifdef ARG_MAX
|
||||
return(ARG_MAX);
|
||||
#elif defined(HAVE_SYSCONF) && defined(_SC_ARG_MAX)
|
||||
return(sysconf(_SC_ARG_MAX));
|
||||
#else
|
||||
return(256); /* XXX: arbitrary */
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* glob(3) -- a superset of the one defined in POSIX 1003.2.
|
||||
*
|
||||
@ -88,6 +58,25 @@ get_arg_max(void)
|
||||
* Number of matches in the current invocation of glob.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || \
|
||||
!defined(GLOB_HAS_GL_MATCHC) || !defined(GLOB_HAS_GL_STATV) || \
|
||||
!defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \
|
||||
defined(BROKEN_GLOB)
|
||||
|
||||
#include "charclass.h"
|
||||
|
||||
#define DOLLAR '$'
|
||||
#define DOT '.'
|
||||
@ -100,7 +89,6 @@ get_arg_max(void)
|
||||
#define RBRACKET ']'
|
||||
#define SEP '/'
|
||||
#define STAR '*'
|
||||
#undef TILDE /* Some platforms may already define it */
|
||||
#define TILDE '~'
|
||||
#define UNDERSCORE '_'
|
||||
#define LBRACE '{'
|
||||
@ -137,26 +125,39 @@ typedef char Char;
|
||||
#define M_ONE META('?')
|
||||
#define M_RNG META('-')
|
||||
#define M_SET META('[')
|
||||
#define M_CLASS META(':')
|
||||
#define ismeta(c) (((c)&M_QUOTE) != 0)
|
||||
|
||||
#define GLOB_LIMIT_MALLOC 65536
|
||||
#define GLOB_LIMIT_STAT 128
|
||||
#define GLOB_LIMIT_READDIR 16384
|
||||
|
||||
struct glob_lim {
|
||||
size_t glim_malloc;
|
||||
size_t glim_stat;
|
||||
size_t glim_readdir;
|
||||
};
|
||||
|
||||
static int compare(const void *, const void *);
|
||||
static int g_Ctoc(const Char *, char *, u_int);
|
||||
static int g_lstat(Char *, struct stat *, glob_t *);
|
||||
static DIR *g_opendir(Char *, glob_t *);
|
||||
static Char *g_strchr(Char *, int);
|
||||
static Char *g_strchr(const Char *, int);
|
||||
static int g_strncmp(const Char *, const char *, size_t);
|
||||
static int g_stat(Char *, struct stat *, glob_t *);
|
||||
static int glob0(const Char *, glob_t *);
|
||||
static int glob1(Char *, Char *, glob_t *, size_t *);
|
||||
static int glob0(const Char *, glob_t *, struct glob_lim *);
|
||||
static int glob1(Char *, Char *, glob_t *, struct glob_lim *);
|
||||
static int glob2(Char *, Char *, Char *, Char *, Char *, Char *,
|
||||
glob_t *, size_t *);
|
||||
glob_t *, struct glob_lim *);
|
||||
static int glob3(Char *, Char *, Char *, Char *, Char *,
|
||||
Char *, Char *, glob_t *, size_t *);
|
||||
static int globextend(const Char *, glob_t *, size_t *);
|
||||
Char *, Char *, glob_t *, struct glob_lim *);
|
||||
static int globextend(const Char *, glob_t *, struct glob_lim *,
|
||||
struct stat *);
|
||||
static const Char *
|
||||
globtilde(const Char *, Char *, size_t, glob_t *);
|
||||
static int globexp1(const Char *, glob_t *);
|
||||
static int globexp2(const Char *, const Char *, glob_t *, int *);
|
||||
static int globexp1(const Char *, glob_t *, struct glob_lim *);
|
||||
static int globexp2(const Char *, const Char *, glob_t *,
|
||||
struct glob_lim *);
|
||||
static int match(Char *, Char *, Char *);
|
||||
#ifdef DEBUG
|
||||
static void qprintf(const char *, Char *);
|
||||
@ -169,11 +170,13 @@ glob(const char *pattern, int flags, int (*errfunc)(const char *, int),
|
||||
const u_char *patnext;
|
||||
int c;
|
||||
Char *bufnext, *bufend, patbuf[MAXPATHLEN];
|
||||
struct glob_lim limit = { 0, 0, 0 };
|
||||
|
||||
patnext = (u_char *) pattern;
|
||||
if (!(flags & GLOB_APPEND)) {
|
||||
pglob->gl_pathc = 0;
|
||||
pglob->gl_pathv = NULL;
|
||||
pglob->gl_statv = NULL;
|
||||
if (!(flags & GLOB_DOOFFS))
|
||||
pglob->gl_offs = 0;
|
||||
}
|
||||
@ -181,6 +184,11 @@ glob(const char *pattern, int flags, int (*errfunc)(const char *, int),
|
||||
pglob->gl_errfunc = errfunc;
|
||||
pglob->gl_matchc = 0;
|
||||
|
||||
if (pglob->gl_offs < 0 || pglob->gl_pathc < 0 ||
|
||||
pglob->gl_offs >= INT_MAX || pglob->gl_pathc >= INT_MAX ||
|
||||
pglob->gl_pathc >= INT_MAX - pglob->gl_offs - 1)
|
||||
return GLOB_NOSPACE;
|
||||
|
||||
bufnext = patbuf;
|
||||
bufend = bufnext + MAXPATHLEN - 1;
|
||||
if (flags & GLOB_NOESCAPE)
|
||||
@ -201,9 +209,9 @@ glob(const char *pattern, int flags, int (*errfunc)(const char *, int),
|
||||
*bufnext = EOS;
|
||||
|
||||
if (flags & GLOB_BRACE)
|
||||
return globexp1(patbuf, pglob);
|
||||
return globexp1(patbuf, pglob, &limit);
|
||||
else
|
||||
return glob0(patbuf, pglob);
|
||||
return glob0(patbuf, pglob, &limit);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -212,20 +220,18 @@ glob(const char *pattern, int flags, int (*errfunc)(const char *, int),
|
||||
* characters
|
||||
*/
|
||||
static int
|
||||
globexp1(const Char *pattern, glob_t *pglob)
|
||||
globexp1(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)
|
||||
{
|
||||
const Char* ptr = pattern;
|
||||
int rv;
|
||||
|
||||
/* Protect a single {}, for find(1), like csh */
|
||||
if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
|
||||
return glob0(pattern, pglob);
|
||||
return glob0(pattern, pglob, limitp);
|
||||
|
||||
while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL)
|
||||
if (!globexp2(ptr, pattern, pglob, &rv))
|
||||
return rv;
|
||||
if ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL)
|
||||
return globexp2(ptr, pattern, pglob, limitp);
|
||||
|
||||
return glob0(pattern, pglob);
|
||||
return glob0(pattern, pglob, limitp);
|
||||
}
|
||||
|
||||
|
||||
@ -235,9 +241,10 @@ globexp1(const Char *pattern, glob_t *pglob)
|
||||
* If it fails then it tries to glob the rest of the pattern and returns.
|
||||
*/
|
||||
static int
|
||||
globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv)
|
||||
globexp2(const Char *ptr, const Char *pattern, glob_t *pglob,
|
||||
struct glob_lim *limitp)
|
||||
{
|
||||
int i;
|
||||
int i, rv;
|
||||
Char *lm, *ls;
|
||||
const Char *pe, *pm, *pl;
|
||||
Char patbuf[MAXPATHLEN];
|
||||
@ -270,10 +277,8 @@ globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv)
|
||||
}
|
||||
|
||||
/* Non matching braces; just glob the pattern */
|
||||
if (i != 0 || *pe == EOS) {
|
||||
*rv = glob0(patbuf, pglob);
|
||||
return 0;
|
||||
}
|
||||
if (i != 0 || *pe == EOS)
|
||||
return glob0(patbuf, pglob, limitp);
|
||||
|
||||
for (i = 0, pl = pm = ptr; pm <= pe; pm++) {
|
||||
switch (*pm) {
|
||||
@ -319,7 +324,9 @@ globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv)
|
||||
#ifdef DEBUG
|
||||
qprintf("globexp2:", patbuf);
|
||||
#endif
|
||||
*rv = globexp1(patbuf, pglob);
|
||||
rv = globexp1(patbuf, pglob, limitp);
|
||||
if (rv && rv != GLOB_NOMATCH)
|
||||
return rv;
|
||||
|
||||
/* move after the comma, to the next string */
|
||||
pl = pm + 1;
|
||||
@ -330,7 +337,6 @@ globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv)
|
||||
break;
|
||||
}
|
||||
}
|
||||
*rv = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -399,6 +405,47 @@ globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob)
|
||||
return patbuf;
|
||||
}
|
||||
|
||||
static int
|
||||
g_strncmp(const Char *s1, const char *s2, size_t n)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
while (n--) {
|
||||
rv = *(Char *)s1 - *(const unsigned char *)s2++;
|
||||
if (rv)
|
||||
break;
|
||||
if (*s1++ == '\0')
|
||||
break;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int
|
||||
g_charclass(const Char **patternp, Char **bufnextp)
|
||||
{
|
||||
const Char *pattern = *patternp + 1;
|
||||
Char *bufnext = *bufnextp;
|
||||
const Char *colon;
|
||||
struct cclass *cc;
|
||||
size_t len;
|
||||
|
||||
if ((colon = g_strchr(pattern, ':')) == NULL || colon[1] != ']')
|
||||
return 1; /* not a character class */
|
||||
|
||||
len = (size_t)(colon - pattern);
|
||||
for (cc = cclasses; cc->name != NULL; cc++) {
|
||||
if (!g_strncmp(pattern, cc->name, len) && cc->name[len] == '\0')
|
||||
break;
|
||||
}
|
||||
if (cc->name == NULL)
|
||||
return -1; /* invalid character class */
|
||||
*bufnext++ = M_CLASS;
|
||||
*bufnext++ = (Char)(cc - &cclasses[0]);
|
||||
*bufnextp = bufnext;
|
||||
*patternp += len + 3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The main glob() routine: compiles the pattern (optionally processing
|
||||
@ -408,12 +455,11 @@ globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob)
|
||||
* to find no matches.
|
||||
*/
|
||||
static int
|
||||
glob0(const Char *pattern, glob_t *pglob)
|
||||
glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)
|
||||
{
|
||||
const Char *qpatnext;
|
||||
int c, err, oldpathc;
|
||||
Char *bufnext, patbuf[MAXPATHLEN];
|
||||
size_t limit = 0;
|
||||
|
||||
qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob);
|
||||
oldpathc = pglob->gl_pathc;
|
||||
@ -427,7 +473,7 @@ glob0(const Char *pattern, glob_t *pglob)
|
||||
if (c == NOT)
|
||||
++qpatnext;
|
||||
if (*qpatnext == EOS ||
|
||||
g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) {
|
||||
g_strchr(qpatnext+1, RBRACKET) == NULL) {
|
||||
*bufnext++ = LBRACKET;
|
||||
if (c == NOT)
|
||||
--qpatnext;
|
||||
@ -438,6 +484,20 @@ glob0(const Char *pattern, glob_t *pglob)
|
||||
*bufnext++ = M_NOT;
|
||||
c = *qpatnext++;
|
||||
do {
|
||||
if (c == LBRACKET && *qpatnext == ':') {
|
||||
do {
|
||||
err = g_charclass(&qpatnext,
|
||||
&bufnext);
|
||||
if (err)
|
||||
break;
|
||||
c = *qpatnext++;
|
||||
} while (c == LBRACKET && *qpatnext == ':');
|
||||
if (err == -1 &&
|
||||
!(pglob->gl_flags & GLOB_NOCHECK))
|
||||
return GLOB_NOMATCH;
|
||||
if (c == RBRACKET)
|
||||
break;
|
||||
}
|
||||
*bufnext++ = CHAR(c);
|
||||
if (*qpatnext == RANGE &&
|
||||
(c = qpatnext[1]) != RBRACKET) {
|
||||
@ -471,7 +531,7 @@ glob0(const Char *pattern, glob_t *pglob)
|
||||
qprintf("glob0:", patbuf);
|
||||
#endif
|
||||
|
||||
if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, &limit)) != 0)
|
||||
if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, limitp)) != 0)
|
||||
return(err);
|
||||
|
||||
/*
|
||||
@ -484,7 +544,7 @@ glob0(const Char *pattern, glob_t *pglob)
|
||||
if ((pglob->gl_flags & GLOB_NOCHECK) ||
|
||||
((pglob->gl_flags & GLOB_NOMAGIC) &&
|
||||
!(pglob->gl_flags & GLOB_MAGCHAR)))
|
||||
return(globextend(pattern, pglob, &limit));
|
||||
return(globextend(pattern, pglob, limitp, NULL));
|
||||
else
|
||||
return(GLOB_NOMATCH);
|
||||
}
|
||||
@ -501,7 +561,7 @@ compare(const void *p, const void *q)
|
||||
}
|
||||
|
||||
static int
|
||||
glob1(Char *pattern, Char *pattern_last, glob_t *pglob, size_t *limitp)
|
||||
glob1(Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp)
|
||||
{
|
||||
Char pathbuf[MAXPATHLEN];
|
||||
|
||||
@ -520,7 +580,7 @@ glob1(Char *pattern, Char *pattern_last, glob_t *pglob, size_t *limitp)
|
||||
*/
|
||||
static int
|
||||
glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
|
||||
Char *pattern, Char *pattern_last, glob_t *pglob, size_t *limitp)
|
||||
Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp)
|
||||
{
|
||||
struct stat sb;
|
||||
Char *p, *q;
|
||||
@ -536,6 +596,14 @@ glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
|
||||
if (g_lstat(pathbuf, &sb, pglob))
|
||||
return(0);
|
||||
|
||||
if ((pglob->gl_flags & GLOB_LIMIT) &&
|
||||
limitp->glim_stat++ >= GLOB_LIMIT_STAT) {
|
||||
errno = 0;
|
||||
*pathend++ = SEP;
|
||||
*pathend = EOS;
|
||||
return(GLOB_NOSPACE);
|
||||
}
|
||||
|
||||
if (((pglob->gl_flags & GLOB_MARK) &&
|
||||
pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) ||
|
||||
(S_ISLNK(sb.st_mode) &&
|
||||
@ -547,7 +615,7 @@ glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
|
||||
*pathend = EOS;
|
||||
}
|
||||
++pglob->gl_matchc;
|
||||
return(globextend(pathbuf, pglob, limitp));
|
||||
return(globextend(pathbuf, pglob, limitp, &sb));
|
||||
}
|
||||
|
||||
/* Find end of next segment, copy tentatively to pathend. */
|
||||
@ -581,7 +649,7 @@ glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
|
||||
static int
|
||||
glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
|
||||
Char *pattern, Char *restpattern, Char *restpattern_last, glob_t *pglob,
|
||||
size_t *limitp)
|
||||
struct glob_lim *limitp)
|
||||
{
|
||||
struct dirent *dp;
|
||||
DIR *dirp;
|
||||
@ -624,6 +692,14 @@ glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
|
||||
u_char *sc;
|
||||
Char *dc;
|
||||
|
||||
if ((pglob->gl_flags & GLOB_LIMIT) &&
|
||||
limitp->glim_readdir++ >= GLOB_LIMIT_READDIR) {
|
||||
errno = 0;
|
||||
*pathend++ = SEP;
|
||||
*pathend = EOS;
|
||||
return(GLOB_NOSPACE);
|
||||
}
|
||||
|
||||
/* Initial DOT must be matched literally. */
|
||||
if (dp->d_name[0] == DOT && *pattern != DOT)
|
||||
continue;
|
||||
@ -670,25 +746,44 @@ glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
|
||||
* gl_pathv points to (gl_offs + gl_pathc + 1) items.
|
||||
*/
|
||||
static int
|
||||
globextend(const Char *path, glob_t *pglob, size_t *limitp)
|
||||
globextend(const Char *path, glob_t *pglob, struct glob_lim *limitp,
|
||||
struct stat *sb)
|
||||
{
|
||||
char **pathv;
|
||||
int i;
|
||||
u_int newsize, len;
|
||||
char *copy;
|
||||
ssize_t i;
|
||||
size_t newn, len;
|
||||
char *copy = NULL;
|
||||
const Char *p;
|
||||
struct stat **statv;
|
||||
|
||||
newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
|
||||
pathv = pglob->gl_pathv ? realloc((char *)pglob->gl_pathv, newsize) :
|
||||
malloc(newsize);
|
||||
if (pathv == NULL) {
|
||||
newn = 2 + pglob->gl_pathc + pglob->gl_offs;
|
||||
if (pglob->gl_offs >= INT_MAX ||
|
||||
pglob->gl_pathc >= INT_MAX ||
|
||||
newn >= INT_MAX ||
|
||||
SIZE_MAX / sizeof(*pathv) <= newn ||
|
||||
SIZE_MAX / sizeof(*statv) <= newn) {
|
||||
nospace:
|
||||
for (i = pglob->gl_offs; i < (ssize_t)(newn - 2); i++) {
|
||||
if (pglob->gl_pathv && pglob->gl_pathv[i])
|
||||
free(pglob->gl_pathv[i]);
|
||||
if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0 &&
|
||||
pglob->gl_pathv && pglob->gl_pathv[i])
|
||||
free(pglob->gl_statv[i]);
|
||||
}
|
||||
if (pglob->gl_pathv) {
|
||||
free(pglob->gl_pathv);
|
||||
pglob->gl_pathv = NULL;
|
||||
}
|
||||
if (pglob->gl_statv) {
|
||||
free(pglob->gl_statv);
|
||||
pglob->gl_statv = NULL;
|
||||
}
|
||||
return(GLOB_NOSPACE);
|
||||
}
|
||||
|
||||
pathv = realloc(pglob->gl_pathv, newn * sizeof(*pathv));
|
||||
if (pathv == NULL)
|
||||
goto nospace;
|
||||
if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
|
||||
/* first time around -- clear initial gl_offs items */
|
||||
pathv += pglob->gl_offs;
|
||||
@ -697,10 +792,39 @@ globextend(const Char *path, glob_t *pglob, size_t *limitp)
|
||||
}
|
||||
pglob->gl_pathv = pathv;
|
||||
|
||||
if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0) {
|
||||
statv = realloc(pglob->gl_statv, newn * sizeof(*statv));
|
||||
if (statv == NULL)
|
||||
goto nospace;
|
||||
if (pglob->gl_statv == NULL && pglob->gl_offs > 0) {
|
||||
/* first time around -- clear initial gl_offs items */
|
||||
statv += pglob->gl_offs;
|
||||
for (i = pglob->gl_offs; --i >= 0; )
|
||||
*--statv = NULL;
|
||||
}
|
||||
pglob->gl_statv = statv;
|
||||
if (sb == NULL)
|
||||
statv[pglob->gl_offs + pglob->gl_pathc] = NULL;
|
||||
else {
|
||||
limitp->glim_malloc += sizeof(**statv);
|
||||
if ((pglob->gl_flags & GLOB_LIMIT) &&
|
||||
limitp->glim_malloc >= GLOB_LIMIT_MALLOC) {
|
||||
errno = 0;
|
||||
return(GLOB_NOSPACE);
|
||||
}
|
||||
if ((statv[pglob->gl_offs + pglob->gl_pathc] =
|
||||
malloc(sizeof(**statv))) == NULL)
|
||||
goto copy_error;
|
||||
memcpy(statv[pglob->gl_offs + pglob->gl_pathc], sb,
|
||||
sizeof(*sb));
|
||||
}
|
||||
statv[pglob->gl_offs + pglob->gl_pathc + 1] = NULL;
|
||||
}
|
||||
|
||||
for (p = path; *p++;)
|
||||
;
|
||||
len = (size_t)(p - path);
|
||||
*limitp += len;
|
||||
limitp->glim_malloc += len;
|
||||
if ((copy = malloc(len)) != NULL) {
|
||||
if (g_Ctoc(path, copy, len)) {
|
||||
free(copy);
|
||||
@ -711,11 +835,12 @@ globextend(const Char *path, glob_t *pglob, size_t *limitp)
|
||||
pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
|
||||
|
||||
if ((pglob->gl_flags & GLOB_LIMIT) &&
|
||||
newsize + *limitp >= (u_int) get_arg_max()) {
|
||||
(newn * sizeof(*pathv)) + limitp->glim_malloc >
|
||||
GLOB_LIMIT_MALLOC) {
|
||||
errno = 0;
|
||||
return(GLOB_NOSPACE);
|
||||
}
|
||||
|
||||
copy_error:
|
||||
return(copy == NULL ? GLOB_NOSPACE : 0);
|
||||
}
|
||||
|
||||
@ -751,13 +876,21 @@ match(Char *name, Char *pat, Char *patend)
|
||||
return(0);
|
||||
if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
|
||||
++pat;
|
||||
while (((c = *pat++) & M_MASK) != M_END)
|
||||
while (((c = *pat++) & M_MASK) != M_END) {
|
||||
if ((c & M_MASK) == M_CLASS) {
|
||||
Char idx = *pat & M_MASK;
|
||||
if (idx < NCCLASSES &&
|
||||
cclasses[idx].isctype(k))
|
||||
ok = 1;
|
||||
++pat;
|
||||
}
|
||||
if ((*pat & M_MASK) == M_RNG) {
|
||||
if (c <= k && k <= pat[1])
|
||||
ok = 1;
|
||||
pat += 2;
|
||||
} else if (c == k)
|
||||
ok = 1;
|
||||
}
|
||||
if (ok == negate_range)
|
||||
return(0);
|
||||
break;
|
||||
@ -785,6 +918,14 @@ globfree(glob_t *pglob)
|
||||
free(pglob->gl_pathv);
|
||||
pglob->gl_pathv = NULL;
|
||||
}
|
||||
if (pglob->gl_statv != NULL) {
|
||||
for (i = 0; i < pglob->gl_pathc; i++) {
|
||||
if (pglob->gl_statv[i] != NULL)
|
||||
free(pglob->gl_statv[i]);
|
||||
}
|
||||
free(pglob->gl_statv);
|
||||
pglob->gl_statv = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static DIR *
|
||||
@ -830,11 +971,11 @@ g_stat(Char *fn, struct stat *sb, glob_t *pglob)
|
||||
}
|
||||
|
||||
static Char *
|
||||
g_strchr(Char *str, int ch)
|
||||
g_strchr(const Char *str, int ch)
|
||||
{
|
||||
do {
|
||||
if (*str == ch)
|
||||
return (str);
|
||||
return ((Char *)str);
|
||||
} while (*str++);
|
||||
return (NULL);
|
||||
}
|
||||
@ -870,5 +1011,4 @@ qprintf(const char *str, Char *s)
|
||||
#endif
|
||||
|
||||
#endif /* !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) ||
|
||||
!defined(GLOB_HAS_GL_MATCHC) */
|
||||
|
||||
!defined(GLOB_HAS_GL_MATCHC) || !defined(GLOB_HAS_GL_STATV) */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: glob.h,v 1.10 2005/12/13 00:35:22 millert Exp $ */
|
||||
/* $OpenBSD: glob.h,v 1.11 2010/09/24 13:32:55 djm Exp $ */
|
||||
/* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */
|
||||
|
||||
/*
|
||||
@ -38,13 +38,15 @@
|
||||
/* OPENBSD ORIGINAL: include/glob.h */
|
||||
|
||||
#if !defined(HAVE_GLOB_H) || !defined(GLOB_HAS_ALTDIRFUNC) || \
|
||||
!defined(GLOB_HAS_GL_MATCHC) || \
|
||||
!defined(GLOB_HAS_GL_MATCHC) || !defined(GLOB_HAS_GL_STATV) || \
|
||||
!defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \
|
||||
defined(BROKEN_GLOB)
|
||||
|
||||
#ifndef _GLOB_H_
|
||||
#define _GLOB_H_
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
struct stat;
|
||||
typedef struct {
|
||||
int gl_pathc; /* Count of total paths so far. */
|
||||
@ -52,6 +54,7 @@ typedef struct {
|
||||
int gl_offs; /* Reserved at beginning of gl_pathv. */
|
||||
int gl_flags; /* Copy of flags parameter to glob. */
|
||||
char **gl_pathv; /* List of paths matching pattern. */
|
||||
struct stat **gl_statv; /* Stat entries corresponding to gl_pathv */
|
||||
/* Copy of errfunc parameter to glob. */
|
||||
int (*gl_errfunc)(const char *, int);
|
||||
|
||||
@ -75,12 +78,10 @@ typedef struct {
|
||||
#define GLOB_NOSORT 0x0020 /* Don't sort. */
|
||||
#define GLOB_NOESCAPE 0x1000 /* Disable backslash escaping. */
|
||||
|
||||
/* Error values returned by glob(3) */
|
||||
#define GLOB_NOSPACE (-1) /* Malloc call failed. */
|
||||
#define GLOB_ABORTED (-2) /* Unignored error. */
|
||||
#define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK not set. */
|
||||
#define GLOB_NOSYS (-4) /* Function not supported. */
|
||||
#define GLOB_ABEND GLOB_ABORTED
|
||||
|
||||
#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */
|
||||
#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */
|
||||
@ -89,6 +90,8 @@ typedef struct {
|
||||
#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */
|
||||
#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */
|
||||
#define GLOB_LIMIT 0x2000 /* Limit pattern match output to ARG_MAX */
|
||||
#define GLOB_KEEPSTAT 0x4000 /* Retain stat data for paths in gl_statv. */
|
||||
#define GLOB_ABEND GLOB_ABORTED /* backward compatibility */
|
||||
|
||||
int glob(const char *, int, int (*)(const char *, int), glob_t *);
|
||||
void globfree(glob_t *);
|
||||
@ -96,5 +99,5 @@ void globfree(glob_t *);
|
||||
#endif /* !_GLOB_H_ */
|
||||
|
||||
#endif /* !defined(HAVE_GLOB_H) || !defined(GLOB_HAS_ALTDIRFUNC) ||
|
||||
!defined(GLOB_HAS_GL_MATCHC */
|
||||
!defined(GLOB_HAS_GL_MATCHC) || !defined(GLOH_HAS_GL_STATV) */
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: openbsd-compat.h,v 1.50 2010/08/16 03:15:23 dtucker Exp $ */
|
||||
/* $Id: openbsd-compat.h,v 1.51 2010/10/07 10:25:29 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999-2003 Damien Miller. All rights reserved.
|
||||
@ -213,6 +213,10 @@ char *user_from_uid(uid_t, int);
|
||||
char *group_from_gid(gid_t, int);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_TIMINGSAFE_BCMP
|
||||
int timingsafe_bcmp(const void *, const void *, size_t);
|
||||
#endif
|
||||
|
||||
void *xmmap(size_t size);
|
||||
char *xcrypt(const char *password, const char *salt);
|
||||
char *shadow_pw(struct passwd *pw);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: openssl-compat.c,v 1.9 2010/01/28 23:54:11 dtucker Exp $ */
|
||||
/* $Id: openssl-compat.c,v 1.13 2011/01/21 22:37:06 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au>
|
||||
@ -18,10 +18,20 @@
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USE_OPENSSL_ENGINE
|
||||
# include <openssl/engine.h>
|
||||
# include <openssl/conf.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_RSA_GET_DEFAULT_METHOD
|
||||
# include <openssl/rsa.h>
|
||||
#endif
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#define SSH_DONT_OVERLOAD_OPENSSL_FUNCS
|
||||
#include "openssl-compat.h"
|
||||
|
||||
@ -58,6 +68,70 @@ ssh_EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_BN_IS_PRIME_EX
|
||||
int
|
||||
BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, void *cb)
|
||||
{
|
||||
if (cb != NULL)
|
||||
fatal("%s: callback args not supported", __func__);
|
||||
return BN_is_prime(p, nchecks, NULL, ctx, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_RSA_GENERATE_KEY_EX
|
||||
int
|
||||
RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *bn_e, void *cb)
|
||||
{
|
||||
RSA *new_rsa, tmp_rsa;
|
||||
unsigned long e;
|
||||
|
||||
if (cb != NULL)
|
||||
fatal("%s: callback args not supported", __func__);
|
||||
e = BN_get_word(bn_e);
|
||||
if (e == 0xffffffffL)
|
||||
fatal("%s: value of e too large", __func__);
|
||||
new_rsa = RSA_generate_key(bits, e, NULL, NULL);
|
||||
if (new_rsa == NULL)
|
||||
return 0;
|
||||
/* swap rsa/new_rsa then free new_rsa */
|
||||
tmp_rsa = *rsa;
|
||||
*rsa = *new_rsa;
|
||||
*new_rsa = tmp_rsa;
|
||||
RSA_free(new_rsa);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_DSA_GENERATE_PARAMETERS_EX
|
||||
int
|
||||
DSA_generate_parameters_ex(DSA *dsa, int bits, const unsigned char *seed,
|
||||
int seed_len, int *counter_ret, unsigned long *h_ret, void *cb)
|
||||
{
|
||||
DSA *new_dsa, tmp_dsa;
|
||||
|
||||
if (cb != NULL)
|
||||
fatal("%s: callback args not supported", __func__);
|
||||
new_dsa = DSA_generate_parameters(bits, (unsigned char *)seed, seed_len,
|
||||
counter_ret, h_ret, NULL, NULL);
|
||||
if (new_dsa == NULL)
|
||||
return 0;
|
||||
/* swap dsa/new_dsa then free new_dsa */
|
||||
tmp_dsa = *dsa;
|
||||
*dsa = *new_dsa;
|
||||
*new_dsa = tmp_dsa;
|
||||
DSA_free(new_dsa);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_RSA_GET_DEFAULT_METHOD
|
||||
RSA_METHOD *
|
||||
RSA_get_default_method(void)
|
||||
{
|
||||
return RSA_PKCS1_SSLeay();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_OPENSSL_ENGINE
|
||||
void
|
||||
ssh_SSLeay_add_all_algorithms(void)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: openssl-compat.h,v 1.15 2010/05/12 07:50:02 djm Exp $ */
|
||||
/* $Id: openssl-compat.h,v 1.18 2011/01/21 22:37:06 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au>
|
||||
@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/dsa.h>
|
||||
@ -39,6 +40,12 @@
|
||||
# define EVP_CIPHER_CTX_get_app_data(e) ((e)->app_data)
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x1000000fL
|
||||
# define LIBCRYPTO_EVP_INL_TYPE unsigned int
|
||||
#else
|
||||
# define LIBCRYPTO_EVP_INL_TYPE size_t
|
||||
#endif
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x00907000L) || defined(OPENSSL_LOBOTOMISED_AES)
|
||||
# define USE_BUILTIN_RIJNDAEL
|
||||
#endif
|
||||
@ -71,6 +78,10 @@ extern const EVP_CIPHER *evp_acss(void);
|
||||
# define EVP_CIPHER_CTX_key_length(c) ((c)->key_len)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_RSA_GET_DEFAULT_METHOD
|
||||
RSA_METHOD *RSA_get_default_method(void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We overload some of the OpenSSL crypto functions with ssh_* equivalents
|
||||
* which cater for older and/or less featureful OpenSSL version.
|
||||
@ -101,6 +112,19 @@ extern const EVP_CIPHER *evp_acss(void);
|
||||
# define SSLeay_add_all_algorithms() ssh_SSLeay_add_all_algorithms()
|
||||
# endif
|
||||
|
||||
# ifndef HAVE_BN_IS_PRIME_EX
|
||||
int BN_is_prime_ex(const BIGNUM *, int, BN_CTX *, void *);
|
||||
# endif
|
||||
|
||||
# ifndef HAVE_DSA_GENERATE_PARAMETERS_EX
|
||||
int DSA_generate_parameters_ex(DSA *, int, const unsigned char *, int, int *,
|
||||
unsigned long *, void *);
|
||||
# endif
|
||||
|
||||
# ifndef HAVE_RSA_GENERATE_KEY_EX
|
||||
int RSA_generate_key_ex(RSA *, int, BIGNUM *, void *);
|
||||
# endif
|
||||
|
||||
int ssh_EVP_CipherInit(EVP_CIPHER_CTX *, const EVP_CIPHER *, unsigned char *,
|
||||
unsigned char *, int);
|
||||
int ssh_EVP_Cipher(EVP_CIPHER_CTX *, char *, char *, int);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: port-linux.c,v 1.8 2010/03/01 04:52:50 dtucker Exp $ */
|
||||
/* $Id: port-linux.c,v 1.11 2011/01/17 07:50:24 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>
|
||||
@ -45,7 +45,7 @@ ssh_selinux_enabled(void)
|
||||
static int enabled = -1;
|
||||
|
||||
if (enabled == -1) {
|
||||
enabled = is_selinux_enabled();
|
||||
enabled = (is_selinux_enabled() == 1);
|
||||
debug("SELinux support %s", enabled ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
@ -208,14 +208,22 @@ ssh_selinux_change_context(const char *newname)
|
||||
#endif /* WITH_SELINUX */
|
||||
|
||||
#ifdef LINUX_OOM_ADJUST
|
||||
#define OOM_ADJ_PATH "/proc/self/oom_adj"
|
||||
/*
|
||||
* The magic "don't kill me", as documented in eg:
|
||||
* The magic "don't kill me" values, old and new, as documented in eg:
|
||||
* http://lxr.linux.no/#linux+v2.6.32/Documentation/filesystems/proc.txt
|
||||
* http://lxr.linux.no/#linux+v2.6.36/Documentation/filesystems/proc.txt
|
||||
*/
|
||||
#define OOM_ADJ_NOKILL -17
|
||||
|
||||
static int oom_adj_save = INT_MIN;
|
||||
static char *oom_adj_path = NULL;
|
||||
struct {
|
||||
char *path;
|
||||
int value;
|
||||
} oom_adjust[] = {
|
||||
{"/proc/self/oom_score_adj", -1000}, /* kernels >= 2.6.36 */
|
||||
{"/proc/self/oom_adj", -17}, /* kernels <= 2.6.35 */
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
/*
|
||||
* Tell the kernel's out-of-memory killer to avoid sshd.
|
||||
@ -224,24 +232,32 @@ static int oom_adj_save = INT_MIN;
|
||||
void
|
||||
oom_adjust_setup(void)
|
||||
{
|
||||
int i, value;
|
||||
FILE *fp;
|
||||
|
||||
debug3("%s", __func__);
|
||||
if ((fp = fopen(OOM_ADJ_PATH, "r+")) != NULL) {
|
||||
for (i = 0; oom_adjust[i].path != NULL; i++) {
|
||||
oom_adj_path = oom_adjust[i].path;
|
||||
value = oom_adjust[i].value;
|
||||
if ((fp = fopen(oom_adj_path, "r+")) != NULL) {
|
||||
if (fscanf(fp, "%d", &oom_adj_save) != 1)
|
||||
verbose("error reading %s: %s", OOM_ADJ_PATH, strerror(errno));
|
||||
verbose("error reading %s: %s", oom_adj_path,
|
||||
strerror(errno));
|
||||
else {
|
||||
rewind(fp);
|
||||
if (fprintf(fp, "%d\n", OOM_ADJ_NOKILL) <= 0)
|
||||
if (fprintf(fp, "%d\n", value) <= 0)
|
||||
verbose("error writing %s: %s",
|
||||
OOM_ADJ_PATH, strerror(errno));
|
||||
oom_adj_path, strerror(errno));
|
||||
else
|
||||
verbose("Set %s from %d to %d",
|
||||
OOM_ADJ_PATH, oom_adj_save, OOM_ADJ_NOKILL);
|
||||
oom_adj_path, oom_adj_save, value);
|
||||
}
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
oom_adj_path = NULL;
|
||||
}
|
||||
|
||||
/* Restore the saved OOM adjustment */
|
||||
void
|
||||
@ -250,13 +266,14 @@ oom_adjust_restore(void)
|
||||
FILE *fp;
|
||||
|
||||
debug3("%s", __func__);
|
||||
if (oom_adj_save == INT_MIN || (fp = fopen(OOM_ADJ_PATH, "w")) == NULL)
|
||||
if (oom_adj_save == INT_MIN || oom_adj_path == NULL ||
|
||||
(fp = fopen(oom_adj_path, "w")) == NULL)
|
||||
return;
|
||||
|
||||
if (fprintf(fp, "%d\n", oom_adj_save) <= 0)
|
||||
verbose("error writing %s: %s", OOM_ADJ_PATH, strerror(errno));
|
||||
verbose("error writing %s: %s", oom_adj_path, strerror(errno));
|
||||
else
|
||||
verbose("Set %s to %d", OOM_ADJ_PATH, oom_adj_save);
|
||||
verbose("Set %s to %d", oom_adj_path, oom_adj_save);
|
||||
|
||||
fclose(fp);
|
||||
return;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: port-solaris.c,v 1.3 2006/10/31 23:28:49 dtucker Exp $ */
|
||||
/* $Id: port-solaris.c,v 1.4 2010/11/05 01:03:05 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Chad Mynhier.
|
||||
@ -197,3 +197,33 @@ solaris_contract_post_fork_parent(pid_t pid)
|
||||
close(ctl_fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SOLARIS_PROJECTS
|
||||
#include <sys/task.h>
|
||||
#include <project.h>
|
||||
|
||||
/*
|
||||
* Get/set solaris default project.
|
||||
* If we fail, just run along gracefully.
|
||||
*/
|
||||
void
|
||||
solaris_set_default_project(struct passwd *pw)
|
||||
{
|
||||
struct project *defaultproject;
|
||||
struct project tempproject;
|
||||
char buf[1024];
|
||||
|
||||
/* get default project, if we fail just return gracefully */
|
||||
if ((defaultproject = getdefaultproj(pw->pw_name, &tempproject, &buf,
|
||||
sizeof(buf))) > 0) {
|
||||
/* set default project */
|
||||
if (setproject(defaultproject->pj_name, pw->pw_name,
|
||||
TASK_NORMAL) != 0)
|
||||
debug("setproject(%s): %s", defaultproject->pj_name,
|
||||
strerror(errno));
|
||||
} else {
|
||||
/* debug on getdefaultproj() error */
|
||||
debug("getdefaultproj(%s): %s", pw->pw_name, strerror(errno));
|
||||
}
|
||||
}
|
||||
#endif /* USE_SOLARIS_PROJECTS */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: port-solaris.h,v 1.1 2006/08/30 17:24:42 djm Exp $ */
|
||||
/* $Id: port-solaris.h,v 1.2 2010/11/05 01:03:05 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Chad Mynhier.
|
||||
@ -20,8 +20,11 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <pwd.h>
|
||||
|
||||
void solaris_contract_pre_fork(void);
|
||||
void solaris_contract_post_fork_child(void);
|
||||
void solaris_contract_post_fork_parent(pid_t pid);
|
||||
void solaris_set_default_project(struct passwd *);
|
||||
|
||||
#endif
|
||||
|
34
openbsd-compat/timingsafe_bcmp.c
Normal file
34
openbsd-compat/timingsafe_bcmp.c
Normal file
@ -0,0 +1,34 @@
|
||||
/* $OpenBSD: timingsafe_bcmp.c,v 1.1 2010/09/24 13:33:00 matthew Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* OPENBSD ORIGINAL: lib/libc/string/timingsafe_bcmp.c */
|
||||
|
||||
#include "includes.h"
|
||||
#ifndef HAVE_TIMINGSAFE_BCMP
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#endif /* TIMINGSAFE_BCMP */
|
@ -20,6 +20,7 @@ SSH_KEYGEN=$prefix/bin/ssh-keygen
|
||||
HOST_KEY_RSA1=$sysconfdir/ssh_host_key
|
||||
HOST_KEY_DSA=$sysconfdir/ssh_host_dsa_key
|
||||
HOST_KEY_RSA=$sysconfdir/ssh_host_rsa_key
|
||||
@COMMENT_OUT_ECC@HOST_KEY_ECDSA=$sysconfdir/ssh_host_ecdsa_key
|
||||
|
||||
|
||||
checkkeys() {
|
||||
@ -32,6 +33,9 @@ checkkeys() {
|
||||
if [ ! -f $HOST_KEY_RSA ]; then
|
||||
${SSH_KEYGEN} -t rsa -f ${HOST_KEY_RSA} -N ""
|
||||
fi
|
||||
@COMMENT_OUT_ECC@ if [ ! -f $HOST_KEY_ECDSA ]; then
|
||||
@COMMENT_OUT_ECC@ ${SSH_KEYGEN} -t ecdsa -f ${HOST_KEY_ECDSA} -N ""
|
||||
@COMMENT_OUT_ECC@ fi
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
|
41
packet.c
41
packet.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: packet.c,v 1.168 2010/07/13 23:13:16 djm Exp $ */
|
||||
/* $OpenBSD: packet.c,v 1.172 2010/11/13 23:27:50 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -391,8 +391,8 @@ packet_get_ssh1_cipher(void)
|
||||
}
|
||||
|
||||
void
|
||||
packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, u_int32_t *packets,
|
||||
u_int64_t *bytes)
|
||||
packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks,
|
||||
u_int32_t *packets, u_int64_t *bytes)
|
||||
{
|
||||
struct packet_state *state;
|
||||
|
||||
@ -547,8 +547,7 @@ packet_start_compression(int level)
|
||||
*/
|
||||
|
||||
void
|
||||
packet_set_encryption_key(const u_char *key, u_int keylen,
|
||||
int number)
|
||||
packet_set_encryption_key(const u_char *key, u_int keylen, int number)
|
||||
{
|
||||
Cipher *cipher = cipher_by_number(number);
|
||||
|
||||
@ -641,6 +640,14 @@ packet_put_bignum2(BIGNUM * value)
|
||||
buffer_put_bignum2(&active_state->outgoing_packet, value);
|
||||
}
|
||||
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
void
|
||||
packet_put_ecpoint(const EC_GROUP *curve, const EC_POINT *point)
|
||||
{
|
||||
buffer_put_ecpoint(&active_state->outgoing_packet, curve, point);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Finalizes and sends the packet. If the encryption key has been set,
|
||||
* encrypts the packet before sending.
|
||||
@ -1511,6 +1518,14 @@ packet_get_bignum2(BIGNUM * value)
|
||||
buffer_get_bignum2(&active_state->incoming_packet, value);
|
||||
}
|
||||
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
void
|
||||
packet_get_ecpoint(const EC_GROUP *curve, EC_POINT *point)
|
||||
{
|
||||
buffer_get_ecpoint(&active_state->incoming_packet, curve, point);
|
||||
}
|
||||
#endif
|
||||
|
||||
void *
|
||||
packet_get_raw(u_int *length_ptr)
|
||||
{
|
||||
@ -1546,6 +1561,13 @@ packet_get_string_ptr(u_int *length_ptr)
|
||||
return buffer_get_string_ptr(&active_state->incoming_packet, length_ptr);
|
||||
}
|
||||
|
||||
/* Ensures the returned string has no embedded \0 characters in it. */
|
||||
char *
|
||||
packet_get_cstring(u_int *length_ptr)
|
||||
{
|
||||
return buffer_get_cstring(&active_state->incoming_packet, length_ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sends a diagnostic message from the server to the client. This message
|
||||
* can be sent at any time (but not while constructing another message). The
|
||||
@ -1728,14 +1750,13 @@ packet_not_very_much_data_to_write(void)
|
||||
}
|
||||
|
||||
static void
|
||||
packet_set_tos(int interactive)
|
||||
packet_set_tos(int tos)
|
||||
{
|
||||
#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)
|
||||
int tos = interactive ? IPTOS_LOWDELAY : IPTOS_THROUGHPUT;
|
||||
|
||||
if (!packet_connection_is_on_socket() ||
|
||||
!packet_connection_is_ipv4())
|
||||
return;
|
||||
debug3("%s: set IP_TOS 0x%02x", __func__, tos);
|
||||
if (setsockopt(active_state->connection_in, IPPROTO_IP, IP_TOS, &tos,
|
||||
sizeof(tos)) < 0)
|
||||
error("setsockopt IP_TOS %d: %.100s:",
|
||||
@ -1746,7 +1767,7 @@ packet_set_tos(int interactive)
|
||||
/* Informs that the current session is interactive. Sets IP flags for that. */
|
||||
|
||||
void
|
||||
packet_set_interactive(int interactive)
|
||||
packet_set_interactive(int interactive, int qos_interactive, int qos_bulk)
|
||||
{
|
||||
if (active_state->set_interactive_called)
|
||||
return;
|
||||
@ -1759,7 +1780,7 @@ packet_set_interactive(int interactive)
|
||||
if (!packet_connection_is_on_socket())
|
||||
return;
|
||||
set_nodelay(active_state->connection_in);
|
||||
packet_set_tos(interactive);
|
||||
packet_set_tos(interactive ? qos_interactive : qos_bulk);
|
||||
}
|
||||
|
||||
/* Returns true if the current connection is interactive. */
|
||||
|
14
packet.h
14
packet.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: packet.h,v 1.52 2009/06/27 09:29:06 andreas Exp $ */
|
||||
/* $OpenBSD: packet.h,v 1.55 2010/11/13 23:27:50 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -19,6 +19,9 @@
|
||||
#include <termios.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
#include <openssl/ec.h>
|
||||
#endif
|
||||
|
||||
void packet_set_connection(int, int);
|
||||
void packet_set_timeout(int, int);
|
||||
@ -31,7 +34,7 @@ u_int packet_get_encryption_key(u_char *);
|
||||
void packet_set_protocol_flags(u_int);
|
||||
u_int packet_get_protocol_flags(void);
|
||||
void packet_start_compression(int);
|
||||
void packet_set_interactive(int);
|
||||
void packet_set_interactive(int, int, int);
|
||||
int packet_is_interactive(void);
|
||||
void packet_set_server(void);
|
||||
void packet_set_authenticated(void);
|
||||
@ -42,6 +45,9 @@ void packet_put_int(u_int value);
|
||||
void packet_put_int64(u_int64_t value);
|
||||
void packet_put_bignum(BIGNUM * value);
|
||||
void packet_put_bignum2(BIGNUM * value);
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
void packet_put_ecpoint(const EC_GROUP *, const EC_POINT *);
|
||||
#endif
|
||||
void packet_put_string(const void *buf, u_int len);
|
||||
void packet_put_cstring(const char *str);
|
||||
void packet_put_raw(const void *buf, u_int len);
|
||||
@ -59,8 +65,12 @@ u_int packet_get_int(void);
|
||||
u_int64_t packet_get_int64(void);
|
||||
void packet_get_bignum(BIGNUM * value);
|
||||
void packet_get_bignum2(BIGNUM * value);
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
void packet_get_ecpoint(const EC_GROUP *, EC_POINT *);
|
||||
#endif
|
||||
void *packet_get_raw(u_int *length_ptr);
|
||||
void *packet_get_string(u_int *length_ptr);
|
||||
char *packet_get_cstring(u_int *length_ptr);
|
||||
void *packet_get_string_ptr(u_int *length_ptr);
|
||||
void packet_disconnect(const char *fmt,...) __attribute__((format(printf, 1, 2)));
|
||||
void packet_send_debug(const char *fmt,...) __attribute__((format(printf, 1, 2)));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pathnames.h,v 1.19 2010/02/11 20:37:47 djm Exp $ */
|
||||
/* $OpenBSD: pathnames.h,v 1.20 2010/08/31 11:54:45 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -38,6 +38,7 @@
|
||||
#define _PATH_HOST_CONFIG_FILE SSHDIR "/ssh_config"
|
||||
#define _PATH_HOST_KEY_FILE SSHDIR "/ssh_host_key"
|
||||
#define _PATH_HOST_DSA_KEY_FILE SSHDIR "/ssh_host_dsa_key"
|
||||
#define _PATH_HOST_ECDSA_KEY_FILE SSHDIR "/ssh_host_ecdsa_key"
|
||||
#define _PATH_HOST_RSA_KEY_FILE SSHDIR "/ssh_host_rsa_key"
|
||||
#define _PATH_DH_MODULI SSHDIR "/moduli"
|
||||
/* Backwards compatibility */
|
||||
@ -74,6 +75,7 @@
|
||||
*/
|
||||
#define _PATH_SSH_CLIENT_IDENTITY ".ssh/identity"
|
||||
#define _PATH_SSH_CLIENT_ID_DSA ".ssh/id_dsa"
|
||||
#define _PATH_SSH_CLIENT_ID_ECDSA ".ssh/id_ecdsa"
|
||||
#define _PATH_SSH_CLIENT_ID_RSA ".ssh/id_rsa"
|
||||
|
||||
/*
|
||||
|
132
platform.c
132
platform.c
@ -1,4 +1,4 @@
|
||||
/* $Id: platform.c,v 1.3 2009/12/20 23:49:22 dtucker Exp $ */
|
||||
/* $Id: platform.c,v 1.18 2011/01/11 06:02:25 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Darren Tucker. All rights reserved.
|
||||
@ -16,11 +16,27 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "buffer.h"
|
||||
#include "servconf.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "auth-pam.h"
|
||||
#include "platform.h"
|
||||
|
||||
#include "openbsd-compat/openbsd-compat.h"
|
||||
|
||||
extern int use_privsep;
|
||||
extern ServerOptions options;
|
||||
|
||||
void
|
||||
platform_pre_listen(void)
|
||||
{
|
||||
@ -57,6 +73,118 @@ platform_post_fork_child(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* return 1 if we are running with privilege to swap UIDs, 0 otherwise */
|
||||
int
|
||||
platform_privileged_uidswap(void)
|
||||
{
|
||||
#ifdef HAVE_CYGWIN
|
||||
/* uid 0 is not special on Cygwin so always try */
|
||||
return 1;
|
||||
#else
|
||||
return (getuid() == 0 || geteuid() == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* This gets called before switching UIDs, and is called even when sshd is
|
||||
* not running as root.
|
||||
*/
|
||||
void
|
||||
platform_setusercontext(struct passwd *pw)
|
||||
{
|
||||
#ifdef WITH_SELINUX
|
||||
/* Cache selinux status for later use */
|
||||
(void)ssh_selinux_enabled();
|
||||
#endif
|
||||
|
||||
#ifdef USE_SOLARIS_PROJECTS
|
||||
/* if solaris projects were detected, set the default now */
|
||||
if (getuid() == 0 || geteuid() == 0)
|
||||
solaris_set_default_project(pw);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LOGIN_CAP) && defined (__bsdi__)
|
||||
if (getuid() == 0 || geteuid() == 0)
|
||||
setpgid(0, 0);
|
||||
# endif
|
||||
|
||||
#if defined(HAVE_LOGIN_CAP) && defined(USE_PAM)
|
||||
/*
|
||||
* If we have both LOGIN_CAP and PAM, we want to establish creds
|
||||
* before calling setusercontext (in session.c:do_setusercontext).
|
||||
*/
|
||||
if (getuid() == 0 || geteuid() == 0) {
|
||||
if (options.use_pam) {
|
||||
do_pam_setcred(use_privsep);
|
||||
}
|
||||
}
|
||||
# endif /* USE_PAM */
|
||||
|
||||
#if !defined(HAVE_LOGIN_CAP) && defined(HAVE_GETLUID) && defined(HAVE_SETLUID)
|
||||
if (getuid() == 0 || geteuid() == 0) {
|
||||
/* Sets login uid for accounting */
|
||||
if (getluid() == -1 && setluid(pw->pw_uid) == -1)
|
||||
error("setluid: %s", strerror(errno));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* This gets called after we've established the user's groups, and is only
|
||||
* called if sshd is running as root.
|
||||
*/
|
||||
void
|
||||
platform_setusercontext_post_groups(struct passwd *pw)
|
||||
{
|
||||
#if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM)
|
||||
/*
|
||||
* PAM credentials may take the form of supplementary groups.
|
||||
* These will have been wiped by the above initgroups() call.
|
||||
* Reestablish them here.
|
||||
*/
|
||||
if (options.use_pam) {
|
||||
do_pam_setcred(use_privsep);
|
||||
}
|
||||
#endif /* USE_PAM */
|
||||
|
||||
#if !defined(HAVE_LOGIN_CAP) && (defined(WITH_IRIX_PROJECT) || \
|
||||
defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY))
|
||||
irix_setusercontext(pw);
|
||||
#endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
|
||||
|
||||
#ifdef _AIX
|
||||
aix_usrinfo(pw);
|
||||
#endif /* _AIX */
|
||||
|
||||
#if !defined(HAVE_LOGIN_CAP) && defined(USE_LIBIAF)
|
||||
if (set_id(pw->pw_name) != 0) {
|
||||
exit(1);
|
||||
}
|
||||
# endif /* USE_LIBIAF */
|
||||
|
||||
#ifdef HAVE_SETPCRED
|
||||
/*
|
||||
* If we have a chroot directory, we set all creds except real
|
||||
* uid which we will need for chroot. If we don't have a
|
||||
* chroot directory, we don't override anything.
|
||||
*/
|
||||
{
|
||||
char **creds = NULL, *chroot_creds[] =
|
||||
{ "REAL_USER=root", NULL };
|
||||
|
||||
if (options.chroot_directory != NULL &&
|
||||
strcasecmp(options.chroot_directory, "none") != 0)
|
||||
creds = chroot_creds;
|
||||
|
||||
if (setpcred(pw->pw_name, creds) == -1)
|
||||
fatal("Failed to set process credentials");
|
||||
}
|
||||
#endif /* HAVE_SETPCRED */
|
||||
#ifdef WITH_SELINUX
|
||||
ssh_selinux_setup_exec_context(pw->pw_name);
|
||||
#endif
|
||||
}
|
||||
|
||||
char *
|
||||
platform_krb5_get_principal_name(const char *pw_name)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: platform.h,v 1.4 2010/01/14 01:44:16 djm Exp $ */
|
||||
/* $Id: platform.h,v 1.7 2010/11/05 03:47:01 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Darren Tucker. All rights reserved.
|
||||
@ -18,10 +18,15 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <pwd.h>
|
||||
|
||||
void platform_pre_listen(void);
|
||||
void platform_pre_fork(void);
|
||||
void platform_post_fork_parent(pid_t child_pid);
|
||||
void platform_post_fork_child(void);
|
||||
int platform_privileged_uidswap(void);
|
||||
void platform_setusercontext(struct passwd *);
|
||||
void platform_setusercontext_post_groups(struct passwd *);
|
||||
char *platform_get_krb5_client(const char *);
|
||||
char *platform_krb5_get_principal_name(const char *);
|
||||
|
||||
|
51
readconf.c
51
readconf.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: readconf.c,v 1.187 2010/07/19 09:15:12 djm Exp $ */
|
||||
/* $OpenBSD: readconf.c,v 1.190 2010/11/13 23:27:50 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -19,6 +19,8 @@
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
@ -132,6 +134,7 @@ typedef enum {
|
||||
oHashKnownHosts,
|
||||
oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
|
||||
oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
|
||||
oKexAlgorithms, oIPQoS,
|
||||
oDeprecated, oUnsupported
|
||||
} OpCodes;
|
||||
|
||||
@ -240,6 +243,8 @@ static struct {
|
||||
#else
|
||||
{ "zeroknowledgepasswordauthentication", oUnsupported },
|
||||
#endif
|
||||
{ "kexalgorithms", oKexAlgorithms },
|
||||
{ "ipqos", oIPQoS },
|
||||
|
||||
{ NULL, oBadOption }
|
||||
};
|
||||
@ -699,6 +704,18 @@ process_config_line(Options *options, const char *host,
|
||||
options->macs = xstrdup(arg);
|
||||
break;
|
||||
|
||||
case oKexAlgorithms:
|
||||
arg = strdelim(&s);
|
||||
if (!arg || *arg == '\0')
|
||||
fatal("%.200s line %d: Missing argument.",
|
||||
filename, linenum);
|
||||
if (!kex_names_valid(arg))
|
||||
fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
|
||||
filename, linenum, arg ? arg : "<NONE>");
|
||||
if (*activep && options->kex_algorithms == NULL)
|
||||
options->kex_algorithms = xstrdup(arg);
|
||||
break;
|
||||
|
||||
case oHostKeyAlgorithms:
|
||||
arg = strdelim(&s);
|
||||
if (!arg || *arg == '\0')
|
||||
@ -959,6 +976,23 @@ process_config_line(Options *options, const char *host,
|
||||
intptr = &options->visual_host_key;
|
||||
goto parse_flag;
|
||||
|
||||
case oIPQoS:
|
||||
arg = strdelim(&s);
|
||||
if ((value = parse_ipqos(arg)) == -1)
|
||||
fatal("%s line %d: Bad IPQoS value: %s",
|
||||
filename, linenum, arg);
|
||||
arg = strdelim(&s);
|
||||
if (arg == NULL)
|
||||
value2 = value;
|
||||
else if ((value2 = parse_ipqos(arg)) == -1)
|
||||
fatal("%s line %d: Bad IPQoS value: %s",
|
||||
filename, linenum, arg);
|
||||
if (*activep) {
|
||||
options->ip_qos_interactive = value;
|
||||
options->ip_qos_bulk = value2;
|
||||
}
|
||||
break;
|
||||
|
||||
case oUseRoaming:
|
||||
intptr = &options->use_roaming;
|
||||
goto parse_flag;
|
||||
@ -1078,6 +1112,7 @@ initialize_options(Options * options)
|
||||
options->cipher = -1;
|
||||
options->ciphers = NULL;
|
||||
options->macs = NULL;
|
||||
options->kex_algorithms = NULL;
|
||||
options->hostkeyalgorithms = NULL;
|
||||
options->protocol = SSH_PROTO_UNKNOWN;
|
||||
options->num_identity_files = 0;
|
||||
@ -1120,6 +1155,8 @@ initialize_options(Options * options)
|
||||
options->use_roaming = -1;
|
||||
options->visual_host_key = -1;
|
||||
options->zero_knowledge_password_authentication = -1;
|
||||
options->ip_qos_interactive = -1;
|
||||
options->ip_qos_bulk = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1191,6 +1228,7 @@ fill_default_options(Options * options)
|
||||
options->cipher = SSH_CIPHER_NOT_SET;
|
||||
/* options->ciphers, default set in myproposals.h */
|
||||
/* options->macs, default set in myproposals.h */
|
||||
/* options->kex_algorithms, default set in myproposals.h */
|
||||
/* options->hostkeyalgorithms, default set in myproposals.h */
|
||||
if (options->protocol == SSH_PROTO_UNKNOWN)
|
||||
options->protocol = SSH_PROTO_2;
|
||||
@ -1214,6 +1252,13 @@ fill_default_options(Options * options)
|
||||
xmalloc(len);
|
||||
snprintf(options->identity_files[options->num_identity_files++],
|
||||
len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
len = 2 + strlen(_PATH_SSH_CLIENT_ID_ECDSA) + 1;
|
||||
options->identity_files[options->num_identity_files] =
|
||||
xmalloc(len);
|
||||
snprintf(options->identity_files[options->num_identity_files++],
|
||||
len, "~/%.100s", _PATH_SSH_CLIENT_ID_ECDSA);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (options->escape_char == -1)
|
||||
@ -1266,6 +1311,10 @@ fill_default_options(Options * options)
|
||||
options->visual_host_key = 0;
|
||||
if (options->zero_knowledge_password_authentication == -1)
|
||||
options->zero_knowledge_password_authentication = 0;
|
||||
if (options->ip_qos_interactive == -1)
|
||||
options->ip_qos_interactive = IPTOS_LOWDELAY;
|
||||
if (options->ip_qos_bulk == -1)
|
||||
options->ip_qos_bulk = IPTOS_THROUGHPUT;
|
||||
/* options->local_command should not be set by default */
|
||||
/* options->proxy_command should not be set by default */
|
||||
/* options->user will be set in the main program if appropriate */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: readconf.h,v 1.86 2010/07/19 09:15:12 djm Exp $ */
|
||||
/* $OpenBSD: readconf.h,v 1.88 2010/11/13 23:27:50 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -59,6 +59,8 @@ typedef struct {
|
||||
int compression_level; /* Compression level 1 (fast) to 9
|
||||
* (best). */
|
||||
int tcp_keep_alive; /* Set SO_KEEPALIVE. */
|
||||
int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */
|
||||
int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */
|
||||
LogLevel log_level; /* Level for logging. */
|
||||
|
||||
int port; /* Port to connect. */
|
||||
@ -73,6 +75,7 @@ typedef struct {
|
||||
char *ciphers; /* SSH2 ciphers in order of preference. */
|
||||
char *macs; /* SSH2 macs in order of preference. */
|
||||
char *hostkeyalgorithms; /* SSH2 server key types in order of preference. */
|
||||
char *kex_algorithms; /* SSH2 kex methods in order of preference. */
|
||||
int protocol; /* Protocol in order of preference. */
|
||||
char *hostname; /* Real host to connect. */
|
||||
char *host_key_alias; /* hostname alias for .ssh/known_hosts */
|
||||
|
27
readpass.c
27
readpass.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: readpass.c,v 1.47 2006/08/03 03:34:42 deraadt Exp $ */
|
||||
/* $OpenBSD: readpass.c,v 1.48 2010/12/15 00:49:27 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -33,6 +33,7 @@
|
||||
#ifdef HAVE_PATHS_H
|
||||
# include <paths.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -49,11 +50,12 @@
|
||||
static char *
|
||||
ssh_askpass(char *askpass, const char *msg)
|
||||
{
|
||||
pid_t pid;
|
||||
pid_t pid, ret;
|
||||
size_t len;
|
||||
char *pass;
|
||||
int p[2], status, ret;
|
||||
int p[2], status;
|
||||
char buf[1024];
|
||||
void (*osigchld)(int);
|
||||
|
||||
if (fflush(stdout) != 0)
|
||||
error("ssh_askpass: fflush: %s", strerror(errno));
|
||||
@ -63,8 +65,10 @@ ssh_askpass(char *askpass, const char *msg)
|
||||
error("ssh_askpass: pipe: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
osigchld = signal(SIGCHLD, SIG_DFL);
|
||||
if ((pid = fork()) < 0) {
|
||||
error("ssh_askpass: fork: %s", strerror(errno));
|
||||
signal(SIGCHLD, osigchld);
|
||||
return NULL;
|
||||
}
|
||||
if (pid == 0) {
|
||||
@ -77,23 +81,24 @@ ssh_askpass(char *askpass, const char *msg)
|
||||
}
|
||||
close(p[1]);
|
||||
|
||||
len = ret = 0;
|
||||
len = 0;
|
||||
do {
|
||||
ret = read(p[0], buf + len, sizeof(buf) - 1 - len);
|
||||
if (ret == -1 && errno == EINTR)
|
||||
ssize_t r = read(p[0], buf + len, sizeof(buf) - 1 - len);
|
||||
|
||||
if (r == -1 && errno == EINTR)
|
||||
continue;
|
||||
if (ret <= 0)
|
||||
if (r <= 0)
|
||||
break;
|
||||
len += ret;
|
||||
len += r;
|
||||
} while (sizeof(buf) - 1 - len > 0);
|
||||
buf[len] = '\0';
|
||||
|
||||
close(p[0]);
|
||||
while (waitpid(pid, &status, 0) < 0)
|
||||
while ((ret = waitpid(pid, &status, 0)) < 0)
|
||||
if (errno != EINTR)
|
||||
break;
|
||||
|
||||
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
signal(SIGCHLD, osigchld);
|
||||
if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
memset(buf, 0, sizeof(buf));
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
# $OpenBSD: Makefile,v 1.54 2010/06/27 19:19:56 phessler Exp $
|
||||
# $OpenBSD: Makefile,v 1.58 2011/01/06 22:46:21 djm Exp $
|
||||
|
||||
REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t-exec
|
||||
REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t-exec
|
||||
tests: $(REGRESS_TARGETS)
|
||||
|
||||
# Interop tests are not run by default
|
||||
@ -53,14 +53,20 @@ LTESTS= connect \
|
||||
localcommand \
|
||||
forcecommand \
|
||||
portnum \
|
||||
keytype \
|
||||
kextype \
|
||||
cert-hostkey \
|
||||
cert-userkey
|
||||
cert-userkey \
|
||||
host-expand
|
||||
|
||||
INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers
|
||||
#INTEROP_TESTS+=ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp
|
||||
|
||||
#LTESTS= cipher-speed
|
||||
|
||||
USER!= id -un
|
||||
CLEANFILES= t2.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \
|
||||
CLEANFILES= t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \
|
||||
t8.out t8.out.pub t9.out t9.out.pub \
|
||||
authorized_keys_${USER} known_hosts pidfile \
|
||||
ssh_config sshd_config.orig ssh_proxy sshd_config sshd_proxy \
|
||||
rsa.pub rsa rsa1.pub rsa1 host.rsa host.rsa1 \
|
||||
@ -69,45 +75,68 @@ CLEANFILES= t2.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \
|
||||
scp-ssh-wrapper.scp ssh_proxy_envpass remote_pid \
|
||||
sshd_proxy_bak rsa_ssh2_cr.prv rsa_ssh2_crnl.prv \
|
||||
known_hosts-cert host_ca_key* cert_host_key* \
|
||||
putty.rsa2 sshd_proxy_orig \
|
||||
authorized_principals_${USER}
|
||||
putty.rsa2 sshd_proxy_orig ssh_proxy_bak \
|
||||
key.rsa-* key.dsa-* key.ecdsa-* \
|
||||
authorized_principals_${USER} expect actual
|
||||
|
||||
# Enable all malloc(3) randomisations and checks
|
||||
TEST_ENV= "MALLOC_OPTIONS=AFGJPRX"
|
||||
|
||||
TEST_SSH_SSHKEYGEN?=ssh-keygen
|
||||
|
||||
t1:
|
||||
ssh-keygen -if ${.CURDIR}/rsa_ssh2.prv | diff - ${.CURDIR}/rsa_openssh.prv
|
||||
${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/rsa_ssh2.prv | diff - ${.CURDIR}/rsa_openssh.prv
|
||||
tr '\n' '\r' <${.CURDIR}/rsa_ssh2.prv > ${.OBJDIR}/rsa_ssh2_cr.prv
|
||||
${TEST_SSH_SSHKEYGEN} -if ${.OBJDIR}/rsa_ssh2_cr.prv | diff - ${.CURDIR}/rsa_openssh.prv
|
||||
awk '{print $$0 "\r"}' ${.CURDIR}/rsa_ssh2.prv > ${.OBJDIR}/rsa_ssh2_crnl.prv
|
||||
${TEST_SSH_SSHKEYGEN} -if ${.OBJDIR}/rsa_ssh2_crnl.prv | diff - ${.CURDIR}/rsa_openssh.prv
|
||||
|
||||
t2:
|
||||
cat ${.CURDIR}/rsa_openssh.prv > $(OBJ)/t2.out
|
||||
chmod 600 $(OBJ)/t2.out
|
||||
ssh-keygen -yf $(OBJ)/t2.out | diff - ${.CURDIR}/rsa_openssh.pub
|
||||
${TEST_SSH_SSHKEYGEN} -yf $(OBJ)/t2.out | diff - ${.CURDIR}/rsa_openssh.pub
|
||||
|
||||
t3:
|
||||
ssh-keygen -ef ${.CURDIR}/rsa_openssh.pub >$(OBJ)/rsa_secsh.pub
|
||||
ssh-keygen -if $(OBJ)/rsa_secsh.pub | diff - ${.CURDIR}/rsa_openssh.pub
|
||||
rm -f ${.CURDIR}/rsa_secsh.pub
|
||||
${TEST_SSH_SSHKEYGEN} -ef ${.CURDIR}/rsa_openssh.pub >$(OBJ)/t3.out
|
||||
${TEST_SSH_SSHKEYGEN} -if $(OBJ)/t3.out | diff - ${.CURDIR}/rsa_openssh.pub
|
||||
|
||||
t4:
|
||||
ssh-keygen -lf ${.CURDIR}/rsa_openssh.pub |\
|
||||
${TEST_SSH_SSHKEYGEN} -lf ${.CURDIR}/rsa_openssh.pub |\
|
||||
awk '{print $$2}' | diff - ${.CURDIR}/t4.ok
|
||||
|
||||
t5:
|
||||
ssh-keygen -Bf ${.CURDIR}/rsa_openssh.pub |\
|
||||
${TEST_SSH_SSHKEYGEN} -Bf ${.CURDIR}/rsa_openssh.pub |\
|
||||
awk '{print $$2}' | diff - ${.CURDIR}/t5.ok
|
||||
|
||||
t6:
|
||||
ssh-keygen -if ${.CURDIR}/dsa_ssh2.prv > $(OBJ)/t6.out1
|
||||
ssh-keygen -if ${.CURDIR}/dsa_ssh2.pub > $(OBJ)/t6.out2
|
||||
${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/dsa_ssh2.prv > $(OBJ)/t6.out1
|
||||
${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/dsa_ssh2.pub > $(OBJ)/t6.out2
|
||||
chmod 600 $(OBJ)/t6.out1
|
||||
ssh-keygen -yf $(OBJ)/t6.out1 | diff - $(OBJ)/t6.out2
|
||||
${TEST_SSH_SSHKEYGEN} -yf $(OBJ)/t6.out1 | diff - $(OBJ)/t6.out2
|
||||
|
||||
$(OBJ)/t7.out:
|
||||
ssh-keygen -q -t rsa -N '' -f $@
|
||||
${TEST_SSH_SSHKEYGEN} -q -t rsa -N '' -f $@
|
||||
|
||||
t7: $(OBJ)/t7.out
|
||||
ssh-keygen -lf $(OBJ)/t7.out > /dev/null
|
||||
ssh-keygen -Bf $(OBJ)/t7.out > /dev/null
|
||||
${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t7.out > /dev/null
|
||||
${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t7.out > /dev/null
|
||||
|
||||
$(OBJ)/t8.out:
|
||||
${TEST_SSH_SSHKEYGEN} -q -t dsa -N '' -f $@
|
||||
|
||||
t8: $(OBJ)/t8.out
|
||||
${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t8.out > /dev/null
|
||||
${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t8.out > /dev/null
|
||||
|
||||
$(OBJ)/t9.out:
|
||||
test "${TEST_SSH_ECC}" != yes || \
|
||||
${TEST_SSH_SSHKEYGEN} -q -t ecdsa -N '' -f $@
|
||||
|
||||
t9: $(OBJ)/t9.out
|
||||
test "${TEST_SSH_ECC}" != yes || \
|
||||
${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t9.out > /dev/null
|
||||
test "${TEST_SSH_ECC}" != yes || \
|
||||
${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t9.out > /dev/null
|
||||
|
||||
t-exec: ${LTESTS:=.sh}
|
||||
@if [ "x$?" = "x" ]; then exit 0; fi; \
|
||||
@ -123,3 +152,5 @@ t-exec-interop: ${INTEROP_TESTS:=.sh}
|
||||
(env SUDO="${SUDO}" TEST_ENV=${TEST_ENV} sh ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \
|
||||
done
|
||||
|
||||
# Not run by default
|
||||
interop: ${INTEROP_TARGETS}
|
||||
|
@ -7,10 +7,9 @@ UNPRIV=nobody
|
||||
ASOCK=${OBJ}/agent
|
||||
SSH_AUTH_SOCK=/nonexistent
|
||||
|
||||
if grep "#undef.*HAVE_GETPEEREID" ${BUILDDIR}/config.h >/dev/null 2>&1 && \
|
||||
grep "#undef.*HAVE_GETPEERUCRED" ${BUILDDIR}/config.h >/dev/null && \
|
||||
grep "#undef.*HAVE_SO_PEERCRED" ${BUILDDIR}/config.h >/dev/null
|
||||
then
|
||||
if config_defined HAVE_GETPEEREID HAVE_GETPEERUCRED HAVE_SO_PEERCRED ; then
|
||||
:
|
||||
else
|
||||
echo "skipped (not supported on this platform)"
|
||||
exit 0
|
||||
fi
|
||||
@ -34,7 +33,7 @@ else
|
||||
fail "ssh-add failed with $r != 1"
|
||||
fi
|
||||
|
||||
< /dev/null ${SUDO} -S -u ${UNPRIV} ssh-add -l > /dev/null 2>&1
|
||||
< /dev/null ${SUDO} -S -u ${UNPRIV} ssh-add -l 2>/dev/null
|
||||
r=$?
|
||||
if [ $r -lt 2 ]; then
|
||||
fail "ssh-add did not fail for ${UNPRIV}: $r < 2"
|
||||
|
@ -41,7 +41,7 @@ EOF
|
||||
if [ $? -ne 0 ]; then
|
||||
fail "gdb failed: exit code $?"
|
||||
fi
|
||||
egrep 'ptrace: Operation not permitted.|procfs:.*Permission denied.|ttrace.*Permission denied.|procfs:.*: Invalid argument.' >/dev/null ${OBJ}/gdb.out
|
||||
egrep 'ptrace: Operation not permitted.|procfs:.*Permission denied.|ttrace.*Permission denied.|procfs:.*: Invalid argument.|Unable to access task ' >/dev/null ${OBJ}/gdb.out
|
||||
r=$?
|
||||
rm -f ${OBJ}/gdb.out
|
||||
if [ $r -ne 0 ]; then
|
||||
|
@ -1,8 +1,14 @@
|
||||
# $OpenBSD: cert-hostkey.sh,v 1.4 2010/04/16 01:58:45 djm Exp $
|
||||
# $OpenBSD: cert-hostkey.sh,v 1.5 2010/08/31 12:24:09 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="certified host keys"
|
||||
|
||||
# used to disable ECC based tests on platforms without ECC
|
||||
ecdsa=""
|
||||
if test "x$TEST_SSH_ECC" = "xyes"; then
|
||||
ecdsa=ecdsa
|
||||
fi
|
||||
|
||||
rm -f $OBJ/known_hosts-cert $OBJ/host_ca_key* $OBJ/cert_host_key*
|
||||
cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
|
||||
|
||||
@ -18,7 +24,7 @@ ${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/host_ca_key ||\
|
||||
) > $OBJ/known_hosts-cert
|
||||
|
||||
# Generate and sign host keys
|
||||
for ktype in rsa dsa ; do
|
||||
for ktype in rsa dsa $ecdsa ; do
|
||||
verbose "$tid: sign host ${ktype} cert"
|
||||
# Generate and sign a host key
|
||||
${SSHKEYGEN} -q -N '' -t ${ktype} \
|
||||
@ -28,6 +34,8 @@ for ktype in rsa dsa ; do
|
||||
-I "regress host key for $USER" \
|
||||
-n $HOSTS $OBJ/cert_host_key_${ktype} ||
|
||||
fail "couldn't sign cert_host_key_${ktype}"
|
||||
# v00 ecdsa certs do not exist
|
||||
test "${ktype}" = "ecdsa" && continue
|
||||
cp $OBJ/cert_host_key_${ktype} $OBJ/cert_host_key_${ktype}_v00
|
||||
cp $OBJ/cert_host_key_${ktype}.pub $OBJ/cert_host_key_${ktype}_v00.pub
|
||||
${SSHKEYGEN} -t v00 -h -q -s $OBJ/host_ca_key \
|
||||
@ -38,7 +46,7 @@ done
|
||||
|
||||
# Basic connect tests
|
||||
for privsep in yes no ; do
|
||||
for ktype in rsa dsa rsa_v00 dsa_v00; do
|
||||
for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00; do
|
||||
verbose "$tid: host ${ktype} cert connect privsep $privsep"
|
||||
(
|
||||
cat $OBJ/sshd_proxy_bak
|
||||
@ -64,6 +72,11 @@ done
|
||||
echon '@revoked '
|
||||
echon "* "
|
||||
cat $OBJ/cert_host_key_rsa.pub
|
||||
if test "x$TEST_SSH_ECC" = "xyes"; then
|
||||
echon '@revoked '
|
||||
echon "* "
|
||||
cat $OBJ/cert_host_key_ecdsa.pub
|
||||
fi
|
||||
echon '@revoked '
|
||||
echon "* "
|
||||
cat $OBJ/cert_host_key_dsa.pub
|
||||
@ -75,7 +88,7 @@ done
|
||||
cat $OBJ/cert_host_key_dsa_v00.pub
|
||||
) > $OBJ/known_hosts-cert
|
||||
for privsep in yes no ; do
|
||||
for ktype in rsa dsa rsa_v00 dsa_v00; do
|
||||
for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00; do
|
||||
verbose "$tid: host ${ktype} revoked cert privsep $privsep"
|
||||
(
|
||||
cat $OBJ/sshd_proxy_bak
|
||||
@ -102,7 +115,7 @@ done
|
||||
echon "* "
|
||||
cat $OBJ/host_ca_key.pub
|
||||
) > $OBJ/known_hosts-cert
|
||||
for ktype in rsa dsa rsa_v00 dsa_v00 ; do
|
||||
for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00 ; do
|
||||
verbose "$tid: host ${ktype} revoked cert"
|
||||
(
|
||||
cat $OBJ/sshd_proxy_bak
|
||||
@ -173,7 +186,9 @@ test_one "cert has constraints" failure "-h -Oforce-command=false"
|
||||
|
||||
# Check downgrade of cert to raw key when no CA found
|
||||
for v in v01 v00 ; do
|
||||
for ktype in rsa dsa ; do
|
||||
for ktype in rsa dsa $ecdsa ; do
|
||||
# v00 ecdsa certs do not exist.
|
||||
test "${v}${ktype}" = "v00ecdsa" && continue
|
||||
rm -f $OBJ/known_hosts-cert $OBJ/cert_host_key*
|
||||
verbose "$tid: host ${ktype} ${v} cert downgrade to raw key"
|
||||
# Generate and sign a host key
|
||||
@ -210,7 +225,9 @@ done
|
||||
cat $OBJ/host_ca_key.pub
|
||||
) > $OBJ/known_hosts-cert
|
||||
for v in v01 v00 ; do
|
||||
for kt in rsa dsa ; do
|
||||
for kt in rsa dsa $ecdsa ; do
|
||||
# v00 ecdsa certs do not exist.
|
||||
test "${v}${ktype}" = "v00ecdsa" && continue
|
||||
rm -f $OBJ/cert_host_key*
|
||||
# Self-sign key
|
||||
${SSHKEYGEN} -q -N '' -t ${kt} \
|
||||
|
@ -1,8 +1,14 @@
|
||||
# $OpenBSD: cert-userkey.sh,v 1.6 2010/06/29 23:59:54 djm Exp $
|
||||
# $OpenBSD: cert-userkey.sh,v 1.7 2010/08/31 12:24:09 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="certified user keys"
|
||||
|
||||
# used to disable ECC based tests on platforms without ECC
|
||||
ecdsa=""
|
||||
if test "x$TEST_SSH_ECC" = "xyes"; then
|
||||
ecdsa=ecdsa
|
||||
fi
|
||||
|
||||
rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key*
|
||||
cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
|
||||
|
||||
@ -11,7 +17,7 @@ ${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_ca_key ||\
|
||||
fail "ssh-keygen of user_ca_key failed"
|
||||
|
||||
# Generate and sign user keys
|
||||
for ktype in rsa dsa ; do
|
||||
for ktype in rsa dsa $ecdsa ; do
|
||||
verbose "$tid: sign user ${ktype} cert"
|
||||
${SSHKEYGEN} -q -N '' -t ${ktype} \
|
||||
-f $OBJ/cert_user_key_${ktype} || \
|
||||
@ -20,6 +26,8 @@ for ktype in rsa dsa ; do
|
||||
"regress user key for $USER" \
|
||||
-n ${USER},mekmitasdigoat $OBJ/cert_user_key_${ktype} ||
|
||||
fail "couldn't sign cert_user_key_${ktype}"
|
||||
# v00 ecdsa certs do not exist
|
||||
test "{ktype}" = "ecdsa" && continue
|
||||
cp $OBJ/cert_user_key_${ktype} $OBJ/cert_user_key_${ktype}_v00
|
||||
cp $OBJ/cert_user_key_${ktype}.pub $OBJ/cert_user_key_${ktype}_v00.pub
|
||||
${SSHKEYGEN} -q -t v00 -s $OBJ/user_ca_key -I \
|
||||
@ -29,7 +37,7 @@ for ktype in rsa dsa ; do
|
||||
done
|
||||
|
||||
# Test explicitly-specified principals
|
||||
for ktype in rsa dsa rsa_v00 dsa_v00 ; do
|
||||
for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00 ; do
|
||||
for privsep in yes no ; do
|
||||
_prefix="${ktype} privsep $privsep"
|
||||
|
||||
@ -155,7 +163,7 @@ basic_tests() {
|
||||
extra_sshd="TrustedUserCAKeys $OBJ/user_ca_key.pub"
|
||||
fi
|
||||
|
||||
for ktype in rsa dsa rsa_v00 dsa_v00 ; do
|
||||
for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00 ; do
|
||||
for privsep in yes no ; do
|
||||
_prefix="${ktype} privsep $privsep $auth"
|
||||
# Simple connect
|
||||
@ -230,6 +238,11 @@ test_one() {
|
||||
|
||||
for auth in $auth_choice ; do
|
||||
for ktype in rsa rsa_v00 ; do
|
||||
case $ktype in
|
||||
*_v00) keyv="-t v00" ;;
|
||||
*) keyv="" ;;
|
||||
esac
|
||||
|
||||
cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy
|
||||
if test "x$auth" = "xauthorized_keys" ; then
|
||||
# Add CA to authorized_keys
|
||||
@ -249,7 +262,7 @@ test_one() {
|
||||
verbose "$tid: $ident auth $auth expect $result $ktype"
|
||||
${SSHKEYGEN} -q -s $OBJ/user_ca_key \
|
||||
-I "regress user key for $USER" \
|
||||
$sign_opts \
|
||||
$sign_opts $keyv \
|
||||
$OBJ/cert_user_key_${ktype} ||
|
||||
fail "couldn't sign cert_user_key_${ktype}"
|
||||
|
||||
@ -302,7 +315,7 @@ test_one "principals key option no principals" failure "" \
|
||||
|
||||
# Wrong certificate
|
||||
cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy
|
||||
for ktype in rsa dsa rsa_v00 dsa_v00 ; do
|
||||
for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00 ; do
|
||||
case $ktype in
|
||||
*_v00) args="-t v00" ;;
|
||||
*) args="" ;;
|
||||
|
18
regress/host-expand.sh
Executable file
18
regress/host-expand.sh
Executable file
@ -0,0 +1,18 @@
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="expand %h and %n"
|
||||
|
||||
echo 'PermitLocalCommand yes' >> $OBJ/ssh_proxy
|
||||
printf 'LocalCommand printf "%%%%s\\n" "%%n" "%%h"\n' >> $OBJ/ssh_proxy
|
||||
|
||||
cat >$OBJ/expect <<EOE
|
||||
somehost
|
||||
127.0.0.1
|
||||
EOE
|
||||
|
||||
for p in 1 2; do
|
||||
verbose "test $tid: proto $p"
|
||||
${SSH} -F $OBJ/ssh_proxy -$p somehost true >$OBJ/actual
|
||||
diff $OBJ/expect $OBJ/actual || fail "$tid proto $p"
|
||||
done
|
||||
|
30
regress/kextype.sh
Executable file
30
regress/kextype.sh
Executable file
@ -0,0 +1,30 @@
|
||||
# $OpenBSD: kextype.sh,v 1.1 2010/09/22 12:26:05 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="login with different key exchange algorithms"
|
||||
|
||||
TIME=/usr/bin/time
|
||||
cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
|
||||
cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak
|
||||
|
||||
if test "$TEST_SSH_ECC" = "yes"; then
|
||||
kextypes="ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521"
|
||||
fi
|
||||
if test "$TEST_SSH_SHA256" = "yes"; then
|
||||
kextypes="$kextypes diffie-hellman-group-exchange-sha256"
|
||||
fi
|
||||
kextypes="$kextypes diffie-hellman-group-exchange-sha1"
|
||||
kextypes="$kextypes diffie-hellman-group14-sha1"
|
||||
kextypes="$kextypes diffie-hellman-group1-sha1"
|
||||
|
||||
tries="1 2 3 4"
|
||||
for k in $kextypes; do
|
||||
verbose "kex $k"
|
||||
for i in $tries; do
|
||||
${SSH} -F $OBJ/ssh_proxy -o KexAlgorithms=$k x true
|
||||
if [ $? -ne 0 ]; then
|
||||
fail "ssh kex $k"
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user